[CB14] Implement backspace in the combiner chain
Bug: 13622107 Bug: 13406701 Change-Id: I0023b398c4451253f9f717e2bd990b8a054004bcmain
parent
37b9562fd7
commit
1079665c3c
|
@ -17,7 +17,9 @@
|
|||
package com.android.inputmethod.event;
|
||||
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -84,7 +86,19 @@ public class CombinerChain {
|
|||
}
|
||||
}
|
||||
if (null != event) {
|
||||
mCombinedText.append(event.getTextToCommit());
|
||||
// TODO: figure out the generic way of doing this
|
||||
if (Constants.CODE_DELETE == event.mKeyCode) {
|
||||
final int length = mCombinedText.length();
|
||||
if (length > 0) {
|
||||
final int lastCodePoint = mCombinedText.codePointBefore(length);
|
||||
mCombinedText.delete(length - Character.charCount(lastCodePoint), length);
|
||||
}
|
||||
} else {
|
||||
final CharSequence textToCommit = event.getTextToCommit();
|
||||
if (!TextUtils.isEmpty(textToCommit)) {
|
||||
mCombinedText.append(textToCommit);
|
||||
}
|
||||
}
|
||||
}
|
||||
mStateFeedback.clear();
|
||||
for (int i = mCombiners.size() - 1; i >= 0; --i) {
|
||||
|
|
|
@ -229,9 +229,9 @@ public class Event {
|
|||
switch (mType) {
|
||||
case EVENT_MODE_KEY:
|
||||
case EVENT_NOT_HANDLED:
|
||||
case EVENT_TOGGLE:
|
||||
return "";
|
||||
case EVENT_INPUT_KEYPRESS:
|
||||
case EVENT_TOGGLE:
|
||||
return StringUtils.newSingleCodePointString(mCodePoint);
|
||||
case EVENT_GESTURE:
|
||||
case EVENT_SOFTWARE_GENERATED_STRING:
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
|
|||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.inputmethod.event.Event;
|
||||
import com.android.inputmethod.keyboard.ProximityInfo;
|
||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.define.ProductionFlag;
|
||||
|
@ -121,7 +122,11 @@ public final class Suggest {
|
|||
if (trailingSingleQuotesCount > 0) {
|
||||
wordComposerForLookup = new WordComposer(wordComposer);
|
||||
for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
|
||||
wordComposerForLookup.deleteLast();
|
||||
// TODO: do not create a fake event for this. Ideally the word composer should know
|
||||
// how to give out the word without trailing quotes and we can remove this entirely
|
||||
wordComposerForLookup.deleteLast(Event.createSoftwareKeypressEvent(
|
||||
Event.NOT_A_CODE_POINT, Constants.CODE_DELETE,
|
||||
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE));
|
||||
}
|
||||
} else {
|
||||
wordComposerForLookup = wordComposer;
|
||||
|
|
|
@ -314,29 +314,14 @@ public final class WordComposer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete the last keystroke as a result of hitting backspace.
|
||||
* Delete the last composing unit as a result of hitting backspace.
|
||||
*/
|
||||
public void deleteLast() {
|
||||
final int size = size();
|
||||
if (size > 0) {
|
||||
// Note: mTypedWord.length() and mCodes.length differ when there are surrogate pairs
|
||||
final int stringBuilderLength = mTypedWord.length();
|
||||
if (stringBuilderLength < size) {
|
||||
throw new RuntimeException(
|
||||
"In WordComposer: mCodes and mTypedWords have non-matching lengths");
|
||||
}
|
||||
final int lastChar = mTypedWord.codePointBefore(stringBuilderLength);
|
||||
// TODO: with events and composition, this is absolutely not necessarily true.
|
||||
mEvents.remove(mEvents.size() - 1);
|
||||
if (Character.isSupplementaryCodePoint(lastChar)) {
|
||||
mTypedWord.delete(stringBuilderLength - 2, stringBuilderLength);
|
||||
} else {
|
||||
mTypedWord.deleteCharAt(stringBuilderLength - 1);
|
||||
}
|
||||
if (Character.isUpperCase(lastChar)) mCapsCount--;
|
||||
if (Character.isDigit(lastChar)) mDigitsCount--;
|
||||
refreshSize();
|
||||
}
|
||||
public void deleteLast(final Event event) {
|
||||
mCombinerChain.processEvent(mEvents, event);
|
||||
mTypedWord.replace(0, mTypedWord.length(),
|
||||
mCombinerChain.getComposingWordWithCombiningFeedback().toString());
|
||||
mEvents.add(event);
|
||||
refreshSize();
|
||||
// We may have deleted the last one.
|
||||
if (0 == size()) {
|
||||
mIsFirstCharCapitalized = false;
|
||||
|
|
|
@ -922,7 +922,7 @@ public final class InputLogic {
|
|||
mWordComposer.reset();
|
||||
mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
|
||||
} else {
|
||||
mWordComposer.deleteLast();
|
||||
mWordComposer.deleteLast(inputTransaction.mEvent);
|
||||
}
|
||||
mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||
handler.postUpdateSuggestionStrip();
|
||||
|
|
|
@ -454,4 +454,24 @@ public class InputLogicTests extends InputTestsBase {
|
|||
assertEquals("predictions after recorrection", "Obama",
|
||||
suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
|
||||
}
|
||||
|
||||
public void testComposingMultipleBackspace() {
|
||||
final String WORD_TO_TYPE = "radklro";
|
||||
final int TIMES_TO_TYPE = 3;
|
||||
final int TIMES_TO_BACKSPACE = 8;
|
||||
type(WORD_TO_TYPE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(WORD_TO_TYPE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(WORD_TO_TYPE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(Constants.CODE_DELETE);
|
||||
type(Constants.CODE_DELETE);
|
||||
assertEquals("composing with multiple backspace",
|
||||
WORD_TO_TYPE.length() * TIMES_TO_TYPE - TIMES_TO_BACKSPACE,
|
||||
mEditText.getText().length());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue