From 117fc93f373cb86d4120c1261f9d0562c6529fec Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Tue, 13 Dec 2011 19:38:36 +0900 Subject: [PATCH] Move mBestWord to the word composer. mBestWord has a confusing name - it's actually an auto-correction. It's cleaner if it lives in the word composer because an auto-correction should be tied to a specific user input, and should be reset each time the user input changes to avoid race conditions. Change-Id: I718d29395bc747372067e6440e090c6a181994ae --- .../android/inputmethod/latin/LatinIME.java | 43 +++++++++++-------- .../inputmethod/latin/WordComposer.java | 31 ++++++++++++- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index a8f4e3179..80f6c150d 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -203,7 +203,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private boolean mApplicationSpecifiedCompletionOn; private WordComposer mWordComposer = new WordComposer(); - private CharSequence mBestWord; private boolean mHasUncommittedTypedChars; private int mCorrectionMode; @@ -1019,7 +1018,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar .setHasMinimalSuggestion(false); // When in fullscreen mode, show completions generated by the application setSuggestions(builder.build()); - mBestWord = null; + mWordComposer.deleteAutoCorrection(); setSuggestionStripShown(true); } } @@ -1649,10 +1648,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar Utils.Stats.onSeparator((char)primaryCode, x, y); if (pickedDefault) { - CharSequence typedWord = mWordComposer.getTypedWord(); - if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) { + final CharSequence autoCorrection = mWordComposer.getAutoCorrectionOrNull(); + final String typedWord = mWordComposer.getTypedWord(); + if (TextUtils.isEmpty(typedWord)) { + throw new RuntimeException("We have non-committed chars but the typed word " + + "is empty? Impossible! I must commit suicide."); + } + if (!typedWord.equals(autoCorrection)) { + // TODO: if the commitCorrection method is not supported by the platform + // this will do nothing and the correction will not be committed at all. What + // happens on Froyo/Gingerbread, where this API is not present? InputConnectionCompatUtils.commitCorrection( - ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); + ic, mLastSelectionEnd - typedWord.length(), typedWord, autoCorrection); } } mKeyboardSwitcher.updateShiftState(); @@ -1847,14 +1854,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar setSuggestions(suggestedWords); if (suggestedWords.size() > 0) { if (shouldBlockAutoCorrectionBySafetyNet) { - mBestWord = typedWord; + mWordComposer.setAutoCorrection(typedWord); } else if (suggestedWords.hasAutoCorrectionWord()) { - mBestWord = suggestedWords.getWord(1); + mWordComposer.setAutoCorrection(suggestedWords.getWord(1)); } else { - mBestWord = typedWord; + mWordComposer.setAutoCorrection(typedWord); } } else { - mBestWord = null; + // TODO: replace with mWordComposer.deleteAutoCorrection()? + mWordComposer.setAutoCorrection(null); } setSuggestionStripShown(isSuggestionsStripVisible()); } @@ -1865,16 +1873,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.cancelUpdateSuggestions(); updateSuggestions(); } - if (mBestWord != null && mBestWord.length() > 0) { - Utils.Stats.onAutoCorrection(mWordComposer.getTypedWord(), mBestWord.toString(), - separatorCode); + final CharSequence autoCorrection = mWordComposer.getAutoCorrectionOrNull(); + if (autoCorrection != null) { + final String typedWord = mWordComposer.getTypedWord(); + Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCode); mExpectingUpdateSelection = true; - commitBestWord(mBestWord); - if (!mBestWord.equals(mWordComposer.getTypedWord())) { - mWordSavedForAutoCorrectCancellation = mBestWord.toString(); + commitBestWord(autoCorrection); + if (!autoCorrection.equals(typedWord)) { + mWordSavedForAutoCorrectCancellation = autoCorrection.toString(); } // Add the word to the user unigram dictionary if it's not a known word - addToUserUnigramAndBigramDictionaries(mBestWord, + addToUserUnigramAndBigramDictionaries(autoCorrection, UserUnigramDictionary.FREQUENCY_FOR_TYPED); return true; } @@ -2153,8 +2162,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private void restartSuggestionsOnWordBeforeCursor(final InputConnection ic, final CharSequence word) { mWordComposer.setComposingWord(word, mKeyboardSwitcher.getLatinKeyboard()); - // mBestWord will be set appropriately by updateSuggestions() called by the handler - mBestWord = null; mHasUncommittedTypedChars = true; mComposingStateManager.onStartComposingText(); ic.deleteSurroundingText(word.length(), 0); diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index dfb00c8ab..fcaf81cd5 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -41,6 +41,8 @@ public class WordComposer { private int[] mYCoordinates; private StringBuilder mTypedWord; + // An auto-correction for this word out of the dictionary. + private CharSequence mAutoCorrection; private int mCapsCount; @@ -60,6 +62,7 @@ public class WordComposer { mXCoordinates = new int[N]; mYCoordinates = new int[N]; mTrailingSingleQuotesCount = 0; + mAutoCorrection = null; } public WordComposer(WordComposer source) { @@ -75,6 +78,7 @@ public class WordComposer { mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mAutoCapitalized = source.mAutoCapitalized; mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; + mAutoCorrection = null; } /** @@ -86,6 +90,7 @@ public class WordComposer { mCapsCount = 0; mIsFirstCharCapitalized = false; mTrailingSingleQuotesCount = 0; + mAutoCorrection = null; } /** @@ -140,6 +145,7 @@ public class WordComposer { } else { mTrailingSingleQuotesCount = 0; } + mAutoCorrection = null; } /** @@ -173,6 +179,7 @@ public class WordComposer { int codePoint = word.charAt(i); addKeyInfo(codePoint, keyboard, keyDetector); } + mAutoCorrection = null; } /** @@ -224,11 +231,12 @@ public class WordComposer { ++mTrailingSingleQuotesCount; } } + mAutoCorrection = null; } /** * Returns the word as it was typed, without any correction applied. - * @return the word that was typed so far + * @return the word that was typed so far. Never returns null. */ public String getTypedWord() { return mTypedWord.toString(); @@ -277,4 +285,25 @@ public class WordComposer { public boolean isAutoCapitalized() { return mAutoCapitalized; } + + /** + * Sets the auto-correction for this word. + */ + public void setAutoCorrection(final CharSequence correction) { + mAutoCorrection = correction; + } + + /** + * Remove any auto-correction that may have been set. + */ + public void deleteAutoCorrection() { + mAutoCorrection = null; + } + + /** + * @return the auto-correction for this world, or null if none. + */ + public CharSequence getAutoCorrectionOrNull() { + return mAutoCorrection; + } }