Merge "[CB14] Implement backspace in the combiner chain"
commit
071b9c1a05
|
@ -17,7 +17,9 @@
|
||||||
package com.android.inputmethod.event;
|
package com.android.inputmethod.event;
|
||||||
|
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.Constants;
|
||||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -84,7 +86,19 @@ public class CombinerChain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (null != event) {
|
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();
|
mStateFeedback.clear();
|
||||||
for (int i = mCombiners.size() - 1; i >= 0; --i) {
|
for (int i = mCombiners.size() - 1; i >= 0; --i) {
|
||||||
|
|
|
@ -229,9 +229,9 @@ public class Event {
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case EVENT_MODE_KEY:
|
case EVENT_MODE_KEY:
|
||||||
case EVENT_NOT_HANDLED:
|
case EVENT_NOT_HANDLED:
|
||||||
|
case EVENT_TOGGLE:
|
||||||
return "";
|
return "";
|
||||||
case EVENT_INPUT_KEYPRESS:
|
case EVENT_INPUT_KEYPRESS:
|
||||||
case EVENT_TOGGLE:
|
|
||||||
return StringUtils.newSingleCodePointString(mCodePoint);
|
return StringUtils.newSingleCodePointString(mCodePoint);
|
||||||
case EVENT_GESTURE:
|
case EVENT_GESTURE:
|
||||||
case EVENT_SOFTWARE_GENERATED_STRING:
|
case EVENT_SOFTWARE_GENERATED_STRING:
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.inputmethod.event.Event;
|
||||||
import com.android.inputmethod.keyboard.ProximityInfo;
|
import com.android.inputmethod.keyboard.ProximityInfo;
|
||||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||||
import com.android.inputmethod.latin.define.ProductionFlag;
|
import com.android.inputmethod.latin.define.ProductionFlag;
|
||||||
|
@ -104,7 +105,11 @@ public final class Suggest {
|
||||||
if (trailingSingleQuotesCount > 0) {
|
if (trailingSingleQuotesCount > 0) {
|
||||||
wordComposerForLookup = new WordComposer(wordComposer);
|
wordComposerForLookup = new WordComposer(wordComposer);
|
||||||
for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
|
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 {
|
} else {
|
||||||
wordComposerForLookup = wordComposer;
|
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() {
|
public void deleteLast(final Event event) {
|
||||||
final int size = size();
|
mCombinerChain.processEvent(mEvents, event);
|
||||||
if (size > 0) {
|
mTypedWord.replace(0, mTypedWord.length(),
|
||||||
// Note: mTypedWord.length() and mCodes.length differ when there are surrogate pairs
|
mCombinerChain.getComposingWordWithCombiningFeedback().toString());
|
||||||
final int stringBuilderLength = mTypedWord.length();
|
mEvents.add(event);
|
||||||
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();
|
refreshSize();
|
||||||
}
|
|
||||||
// We may have deleted the last one.
|
// We may have deleted the last one.
|
||||||
if (0 == size()) {
|
if (0 == size()) {
|
||||||
mIsFirstCharCapitalized = false;
|
mIsFirstCharCapitalized = false;
|
||||||
|
|
|
@ -908,7 +908,7 @@ public final class InputLogic {
|
||||||
mWordComposer.reset();
|
mWordComposer.reset();
|
||||||
mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
|
mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
|
||||||
} else {
|
} else {
|
||||||
mWordComposer.deleteLast();
|
mWordComposer.deleteLast(inputTransaction.mEvent);
|
||||||
}
|
}
|
||||||
mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||||
handler.postUpdateSuggestionStrip();
|
handler.postUpdateSuggestionStrip();
|
||||||
|
|
|
@ -454,4 +454,24 @@ public class InputLogicTests extends InputTestsBase {
|
||||||
assertEquals("predictions after recorrection", "Obama",
|
assertEquals("predictions after recorrection", "Obama",
|
||||||
suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
|
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