Fix a bug where changing languages kills the composition.

Bug: 14926896
Change-Id: Id2a06c68a51f833db4d8bbc858a232c2696afb6e
main
Jean Chalard 2014-05-14 20:19:16 +09:00
parent 71f4c6b8ea
commit 5ce39dfa78
5 changed files with 30 additions and 15 deletions

View File

@ -56,18 +56,20 @@ public class CombinerChain {
*
* The combiner chain takes events as inputs and outputs code points and combining state.
* For example, if the input language is Japanese, the combining chain will typically perform
* kana conversion.
* kana conversion. This takes a string for initial text, taken to be present before the
* cursor: we'll start after this.
*
* @param initialText The text that has already been combined so far.
* @param combinerList A list of combiners to be applied in order.
*/
public CombinerChain(final Combiner... combinerList) {
public CombinerChain(final String initialText, final Combiner... combinerList) {
mCombiners = CollectionUtils.newArrayList();
// The dead key combiner is always active, and always first
mCombiners.add(new DeadKeyCombiner());
for (final Combiner combiner : combinerList) {
mCombiners.add(combiner);
}
mCombinedText = new StringBuilder();
mCombinedText = new StringBuilder(initialText);
mStateFeedback = new SpannableStringBuilder();
}

View File

@ -80,7 +80,7 @@ public final class WordComposer {
private boolean mIsFirstCharCapitalized;
public WordComposer() {
mCombinerChain = new CombinerChain();
mCombinerChain = new CombinerChain("");
mEvents = CollectionUtils.newArrayList();
mAutoCorrection = null;
mIsResumed = false;
@ -92,18 +92,17 @@ public final class WordComposer {
}
/**
* Restart input with a new combining spec.
* Restart the combiners, possibly with a new spec.
* @param combiningSpec The spec string for combining. This is found in the extra value.
*/
public void restart(final String combiningSpec) {
public void restartCombining(final String combiningSpec) {
final String nonNullCombiningSpec = null == combiningSpec ? "" : combiningSpec;
if (nonNullCombiningSpec.equals(mCombiningSpec)) {
mCombinerChain.reset();
} else {
mCombinerChain = new CombinerChain(CombinerChain.createCombiners(nonNullCombiningSpec));
if (!nonNullCombiningSpec.equals(mCombiningSpec)) {
mCombinerChain = new CombinerChain(
mCombinerChain.getComposingWordWithCombiningFeedback().toString(),
CombinerChain.createCombiners(nonNullCombiningSpec));
mCombiningSpec = nonNullCombiningSpec;
}
reset();
}
/**

View File

@ -127,7 +127,7 @@ public final class InputLogic {
public void startInput(final boolean restarting, final EditorInfo editorInfo,
final String combiningSpec) {
mEnteredText = null;
mWordComposer.restart(combiningSpec);
mWordComposer.restartCombining(combiningSpec);
resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SpaceState.NONE;
@ -150,7 +150,7 @@ public final class InputLogic {
* @param combiningSpec the spec string for the combining rules
*/
public void onSubtypeChanged(final String combiningSpec) {
mWordComposer.restart(combiningSpec);
mWordComposer.restartCombining(combiningSpec);
}
/**

View File

@ -600,4 +600,16 @@ public class InputLogicTests extends InputTestsBase {
assertEquals("type words letter by letter", EXPECTED_RESULT,
mEditText.getText().toString());
}
public void testSwitchLanguages() {
final String WORD_TO_TYPE_FIRST_PART = "com";
final String WORD_TO_TYPE_SECOND_PART = "md ";
final String EXPECTED_RESULT = "comme ";
changeLanguage("en");
type(WORD_TO_TYPE_FIRST_PART);
changeLanguage("fr");
type(WORD_TO_TYPE_SECOND_PART);
assertEquals("Composing continues after switching languages", EXPECTED_RESULT,
mEditText.getText().toString());
}
}

View File

@ -28,8 +28,10 @@ import java.util.ArrayList;
// TODO: there should not be a dependency to this in dicttool, so there
// should be a sensible way to separate them cleanly.
public class CombinerChain {
private StringBuilder mComposingWord = new StringBuilder();
public CombinerChain(final Combiner... combinerList) {}
private StringBuilder mComposingWord;
public CombinerChain(final String initialText, final Combiner... combinerList) {
mComposingWord = new StringBuilder(initialText);
}
public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
mComposingWord.append(newEvent.getTextToCommit());