am 4fa01ee5
: Merge "Allow Latin IME to cancel smiley-auto-correct consistenly" into jb-mr1-dev
* commit '4fa01ee570cf4d4aab3a7cdca5246d8f119ac6f1': Allow Latin IME to cancel smiley-auto-correct consistenly
This commit is contained in:
commit
dad8917eee
4 changed files with 61 additions and 44 deletions
|
@ -38,12 +38,12 @@ public class LastComposedWord {
|
||||||
// an auto-correction.
|
// an auto-correction.
|
||||||
public static final int COMMIT_TYPE_CANCEL_AUTO_CORRECT = 3;
|
public static final int COMMIT_TYPE_CANCEL_AUTO_CORRECT = 3;
|
||||||
|
|
||||||
public static final int NOT_A_SEPARATOR = -1;
|
public static final String NOT_A_SEPARATOR = "";
|
||||||
|
|
||||||
public final int[] mPrimaryKeyCodes;
|
public final int[] mPrimaryKeyCodes;
|
||||||
public final String mTypedWord;
|
public final String mTypedWord;
|
||||||
public final String mCommittedWord;
|
public final String mCommittedWord;
|
||||||
public final int mSeparatorCode;
|
public final String mSeparatorString;
|
||||||
public final CharSequence mPrevWord;
|
public final CharSequence mPrevWord;
|
||||||
public final InputPointers mInputPointers = new InputPointers(BinaryDictionary.MAX_WORD_LENGTH);
|
public final InputPointers mInputPointers = new InputPointers(BinaryDictionary.MAX_WORD_LENGTH);
|
||||||
|
|
||||||
|
@ -56,14 +56,14 @@ public class LastComposedWord {
|
||||||
// immutable. Do not fiddle with their contents after you passed them to this constructor.
|
// immutable. Do not fiddle with their contents after you passed them to this constructor.
|
||||||
public LastComposedWord(final int[] primaryKeyCodes, final InputPointers inputPointers,
|
public LastComposedWord(final int[] primaryKeyCodes, final InputPointers inputPointers,
|
||||||
final String typedWord, final String committedWord,
|
final String typedWord, final String committedWord,
|
||||||
final int separatorCode, final CharSequence prevWord) {
|
final String separatorString, final CharSequence prevWord) {
|
||||||
mPrimaryKeyCodes = primaryKeyCodes;
|
mPrimaryKeyCodes = primaryKeyCodes;
|
||||||
if (inputPointers != null) {
|
if (inputPointers != null) {
|
||||||
mInputPointers.copy(inputPointers);
|
mInputPointers.copy(inputPointers);
|
||||||
}
|
}
|
||||||
mTypedWord = typedWord;
|
mTypedWord = typedWord;
|
||||||
mCommittedWord = committedWord;
|
mCommittedWord = committedWord;
|
||||||
mSeparatorCode = separatorCode;
|
mSeparatorString = separatorString;
|
||||||
mActive = true;
|
mActive = true;
|
||||||
mPrevWord = prevWord;
|
mPrevWord = prevWord;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public class LastComposedWord {
|
||||||
return TextUtils.equals(mTypedWord, mCommittedWord);
|
return TextUtils.equals(mTypedWord, mCommittedWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getSeparatorLength(final int separatorCode) {
|
public static int getSeparatorLength(final String separatorString) {
|
||||||
return NOT_A_SEPARATOR == separatorCode ? 0 : 1;
|
return StringUtils.codePointCount(separatorString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1055,7 +1055,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
|
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void commitTyped(final int separatorCode) {
|
private void commitTyped(final String separatorString) {
|
||||||
if (!mWordComposer.isComposingWord()) return;
|
if (!mWordComposer.isComposingWord()) return;
|
||||||
final CharSequence typedWord = mWordComposer.getTypedWord();
|
final CharSequence typedWord = mWordComposer.getTypedWord();
|
||||||
if (typedWord.length() > 0) {
|
if (typedWord.length() > 0) {
|
||||||
|
@ -1063,7 +1063,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
final CharSequence prevWord = addToUserHistoryDictionary(typedWord);
|
final CharSequence prevWord = addToUserHistoryDictionary(typedWord);
|
||||||
mLastComposedWord = mWordComposer.commitWord(
|
mLastComposedWord = mWordComposer.commitWord(
|
||||||
LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(),
|
LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(),
|
||||||
separatorCode, prevWord);
|
separatorString, prevWord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,7 +1340,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
if (!didAutoCorrect && primaryCode != Keyboard.CODE_SHIFT
|
if (!didAutoCorrect && primaryCode != Keyboard.CODE_SHIFT
|
||||||
&& primaryCode != Keyboard.CODE_SWITCH_ALPHA_SYMBOL)
|
&& primaryCode != Keyboard.CODE_SWITCH_ALPHA_SYMBOL)
|
||||||
mLastComposedWord.deactivate();
|
mLastComposedWord.deactivate();
|
||||||
mEnteredText = null;
|
if (Keyboard.CODE_DELETE != primaryCode) {
|
||||||
|
mEnteredText = null;
|
||||||
|
}
|
||||||
mConnection.endBatchEdit();
|
mConnection.endBatchEdit();
|
||||||
if (ProductionFlag.IS_EXPERIMENTAL) {
|
if (ProductionFlag.IS_EXPERIMENTAL) {
|
||||||
ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
|
ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
|
||||||
|
@ -1352,7 +1354,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
public void onTextInput(CharSequence rawText) {
|
public void onTextInput(CharSequence rawText) {
|
||||||
mConnection.beginBatchEdit();
|
mConnection.beginBatchEdit();
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
commitCurrentAutoCorrection(LastComposedWord.NOT_A_SEPARATOR);
|
commitCurrentAutoCorrection(rawText.toString());
|
||||||
|
} else {
|
||||||
|
resetComposingState(true /* alsoResetLastComposedWord */);
|
||||||
}
|
}
|
||||||
mHandler.postUpdateSuggestionStrip();
|
mHandler.postUpdateSuggestionStrip();
|
||||||
final CharSequence text = specificTldProcessingOnTextInput(rawText);
|
final CharSequence text = specificTldProcessingOnTextInput(rawText);
|
||||||
|
@ -1365,7 +1369,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
|
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
|
||||||
mSpaceState = SPACE_STATE_NONE;
|
mSpaceState = SPACE_STATE_NONE;
|
||||||
mEnteredText = text;
|
mEnteredText = text;
|
||||||
resetComposingState(true /* alsoResetLastComposedWord */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1451,18 +1454,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// In many cases, we may have to put the keyboard in auto-shift state again.
|
// In many cases, we may have to put the keyboard in auto-shift state again.
|
||||||
mHandler.postUpdateShiftState();
|
mHandler.postUpdateShiftState();
|
||||||
|
|
||||||
if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) {
|
|
||||||
// Cancel multi-character input: remove the text we just entered.
|
|
||||||
// This is triggered on backspace after a key that inputs multiple characters,
|
|
||||||
// like the smiley key or the .com key.
|
|
||||||
final int length = mEnteredText.length();
|
|
||||||
mConnection.deleteSurroundingText(length, 0);
|
|
||||||
// If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
|
|
||||||
// In addition we know that spaceState is false, and that we should not be
|
|
||||||
// reverting any autocorrect at this point. So we can safely return.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
final int length = mWordComposer.size();
|
final int length = mWordComposer.size();
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
|
@ -1483,6 +1474,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
revertCommit();
|
revertCommit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) {
|
||||||
|
// Cancel multi-character input: remove the text we just entered.
|
||||||
|
// This is triggered on backspace after a key that inputs multiple characters,
|
||||||
|
// like the smiley key or the .com key.
|
||||||
|
final int length = mEnteredText.length();
|
||||||
|
mConnection.deleteSurroundingText(length, 0);
|
||||||
|
mEnteredText = null;
|
||||||
|
// If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
|
||||||
|
// In addition we know that spaceState is false, and that we should not be
|
||||||
|
// reverting any autocorrect at this point. So we can safely return.
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (SPACE_STATE_DOUBLE == spaceState) {
|
if (SPACE_STATE_DOUBLE == spaceState) {
|
||||||
mHandler.cancelDoubleSpacesTimer();
|
mHandler.cancelDoubleSpacesTimer();
|
||||||
if (mConnection.revertDoubleSpace()) {
|
if (mConnection.revertDoubleSpace()) {
|
||||||
|
@ -1626,10 +1629,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// Handle separator
|
// Handle separator
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
if (mCurrentSettings.mCorrectionEnabled) {
|
if (mCurrentSettings.mCorrectionEnabled) {
|
||||||
commitCurrentAutoCorrection(primaryCode);
|
// TODO: maybe cache Strings in an <String> sparse array or something
|
||||||
|
commitCurrentAutoCorrection(new String(new int[]{primaryCode}, 0, 1));
|
||||||
didAutoCorrect = true;
|
didAutoCorrect = true;
|
||||||
} else {
|
} else {
|
||||||
commitTyped(primaryCode);
|
commitTyped(new String(new int[]{primaryCode}, 0, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1834,7 +1838,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
setSuggestionStripShown(isSuggestionsStripVisible());
|
setSuggestionStripShown(isSuggestionsStripVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void commitCurrentAutoCorrection(final int separatorCodePoint) {
|
private void commitCurrentAutoCorrection(final String separatorString) {
|
||||||
// Complete any pending suggestions query first
|
// Complete any pending suggestions query first
|
||||||
if (mHandler.hasPendingUpdateSuggestions()) {
|
if (mHandler.hasPendingUpdateSuggestions()) {
|
||||||
updateSuggestionStrip();
|
updateSuggestionStrip();
|
||||||
|
@ -1848,10 +1852,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
throw new RuntimeException("We have an auto-correction but the typed word "
|
throw new RuntimeException("We have an auto-correction but the typed word "
|
||||||
+ "is empty? Impossible! I must commit suicide.");
|
+ "is empty? Impossible! I must commit suicide.");
|
||||||
}
|
}
|
||||||
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
|
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorString);
|
||||||
mExpectingUpdateSelection = true;
|
mExpectingUpdateSelection = true;
|
||||||
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
|
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
|
||||||
separatorCodePoint);
|
separatorString);
|
||||||
if (!typedWord.equals(autoCorrection)) {
|
if (!typedWord.equals(autoCorrection)) {
|
||||||
// This will make the correction flash for a short while as a visual clue
|
// This will make the correction flash for a short while as a visual clue
|
||||||
// to the user that auto-correction happened.
|
// to the user that auto-correction happened.
|
||||||
|
@ -1949,7 +1953,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
* Commits the chosen word to the text field and saves it for later retrieval.
|
* Commits the chosen word to the text field and saves it for later retrieval.
|
||||||
*/
|
*/
|
||||||
private void commitChosenWord(final CharSequence chosenWord, final int commitType,
|
private void commitChosenWord(final CharSequence chosenWord, final int commitType,
|
||||||
final int separatorCode) {
|
final String separatorString) {
|
||||||
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
|
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
|
||||||
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
|
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
|
||||||
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
|
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
|
||||||
|
@ -1960,7 +1964,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// LastComposedWord#didCommitTypedWord by string equality of the remembered
|
// LastComposedWord#didCommitTypedWord by string equality of the remembered
|
||||||
// strings.
|
// strings.
|
||||||
mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord.toString(),
|
mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord.toString(),
|
||||||
separatorCode, prevWord);
|
separatorString, prevWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPunctuationSuggestions() {
|
private void setPunctuationSuggestions() {
|
||||||
|
@ -2030,7 +2034,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
|
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
|
||||||
final int cancelLength = committedWord.length();
|
final int cancelLength = committedWord.length();
|
||||||
final int separatorLength = LastComposedWord.getSeparatorLength(
|
final int separatorLength = LastComposedWord.getSeparatorLength(
|
||||||
mLastComposedWord.mSeparatorCode);
|
mLastComposedWord.mSeparatorString);
|
||||||
// TODO: should we check our saved separator against the actual contents of the text view?
|
// TODO: should we check our saved separator against the actual contents of the text view?
|
||||||
final int deleteLength = cancelLength + separatorLength;
|
final int deleteLength = cancelLength + separatorLength;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
@ -2051,10 +2055,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mUserHistoryDictionary.cancelAddingUserHistory(
|
mUserHistoryDictionary.cancelAddingUserHistory(
|
||||||
previousWord.toString(), committedWord.toString());
|
previousWord.toString(), committedWord.toString());
|
||||||
}
|
}
|
||||||
mConnection.commitText(originallyTypedWord, 1);
|
mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
|
||||||
// Re-insert the separator
|
Utils.Stats.onSeparator(mLastComposedWord.mSeparatorString,
|
||||||
sendKeyCodePoint(mLastComposedWord.mSeparatorCode);
|
|
||||||
Utils.Stats.onSeparator(mLastComposedWord.mSeparatorCode,
|
|
||||||
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
|
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
|
||||||
if (ProductionFlag.IS_EXPERIMENTAL) {
|
if (ProductionFlag.IS_EXPERIMENTAL) {
|
||||||
ResearchLogger.latinIME_revertCommit(originallyTypedWord);
|
ResearchLogger.latinIME_revertCommit(originallyTypedWord);
|
||||||
|
|
|
@ -29,7 +29,6 @@ import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||||
|
@ -394,23 +393,39 @@ public class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Stats {
|
public static class Stats {
|
||||||
|
static final int NOT_A_SEPARATOR_CODE_POINT = -1;
|
||||||
|
|
||||||
public static void onNonSeparator(final char code, final int x,
|
public static void onNonSeparator(final char code, final int x,
|
||||||
final int y) {
|
final int y) {
|
||||||
RingCharBuffer.getInstance().push(code, x, y);
|
RingCharBuffer.getInstance().push(code, x, y);
|
||||||
LatinImeLogger.logOnInputChar();
|
LatinImeLogger.logOnInputChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onSeparator(final int code, final int x,
|
public static void onSeparator(final int code, final int x, final int y) {
|
||||||
final int y) {
|
// Helper method to log a single code point separator
|
||||||
// TODO: accept code points
|
// TODO: cache this mapping of a code point to a string in a sparse array in StringUtils
|
||||||
RingCharBuffer.getInstance().push((char)code, x, y);
|
onSeparator(new String(new int[]{code}, 0, 1), x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onSeparator(final String separator, final int x, final int y) {
|
||||||
|
final int length = separator.length();
|
||||||
|
for (int i = 0; i < length; i = Character.offsetByCodePoints(separator, i, 1)) {
|
||||||
|
int codePoint = Character.codePointAt(separator, i);
|
||||||
|
// TODO: accept code points
|
||||||
|
RingCharBuffer.getInstance().push((char)codePoint, x, y);
|
||||||
|
}
|
||||||
LatinImeLogger.logOnInputSeparator();
|
LatinImeLogger.logOnInputSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onAutoCorrection(final String typedWord, final String correctedWord,
|
public static void onAutoCorrection(final String typedWord, final String correctedWord,
|
||||||
final int separatorCode) {
|
final String separatorString) {
|
||||||
if (TextUtils.isEmpty(typedWord)) return;
|
if (TextUtils.isEmpty(typedWord)) return;
|
||||||
LatinImeLogger.logOnAutoCorrection(typedWord, correctedWord, separatorCode);
|
// TODO: this fails when the separator is more than 1 code point long, but
|
||||||
|
// the backend can't handle it yet. The only case when this happens is with
|
||||||
|
// smileys and other multi-character keys.
|
||||||
|
final int codePoint = TextUtils.isEmpty(separatorString) ? NOT_A_SEPARATOR_CODE_POINT
|
||||||
|
: separatorString.codePointAt(0);
|
||||||
|
LatinImeLogger.logOnAutoCorrection(typedWord, correctedWord, codePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onAutoCorrectionCancellation() {
|
public static void onAutoCorrectionCancellation() {
|
||||||
|
|
|
@ -336,14 +336,14 @@ public class WordComposer {
|
||||||
|
|
||||||
// `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
|
// `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
|
||||||
public LastComposedWord commitWord(final int type, final String committedWord,
|
public LastComposedWord commitWord(final int type, final String committedWord,
|
||||||
final int separatorCode, final CharSequence prevWord) {
|
final String separatorString, final CharSequence prevWord) {
|
||||||
// Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK
|
// Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK
|
||||||
// or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate
|
// or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate
|
||||||
// the last composed word to ensure this does not happen.
|
// the last composed word to ensure this does not happen.
|
||||||
final int[] primaryKeyCodes = mPrimaryKeyCodes;
|
final int[] primaryKeyCodes = mPrimaryKeyCodes;
|
||||||
mPrimaryKeyCodes = new int[N];
|
mPrimaryKeyCodes = new int[N];
|
||||||
final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes,
|
final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes,
|
||||||
mInputPointers, mTypedWord.toString(), committedWord, separatorCode,
|
mInputPointers, mTypedWord.toString(), committedWord, separatorString,
|
||||||
prevWord);
|
prevWord);
|
||||||
mInputPointers.reset();
|
mInputPointers.reset();
|
||||||
if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD
|
if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD
|
||||||
|
|
Loading…
Reference in a new issue