Merge "Reorganize the auto-correction memory"

main
Jean Chalard 2011-12-19 02:22:49 -08:00 committed by Android (Google) Code Review
commit 715a203501
2 changed files with 38 additions and 38 deletions

View File

@ -199,7 +199,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private WordComposer mWordComposer = new WordComposer(); private WordComposer mWordComposer = new WordComposer();
private int mCorrectionMode; private int mCorrectionMode;
private String mWordSavedForAutoCorrectCancellation;
// Keep track of the last selection range to decide if we need to show word alternatives // Keep track of the last selection range to decide if we need to show word alternatives
private int mLastSelectionStart; private int mLastSelectionStart;
private int mLastSelectionEnd; private int mLastSelectionEnd;
@ -1308,8 +1307,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_DUMMY); mKeyboardSwitcher.onCodeInput(Keyboard.CODE_DUMMY);
mSpaceState = SPACE_STATE_NONE; mSpaceState = SPACE_STATE_NONE;
mWordSavedForAutoCorrectCancellation = null;
mEnteredText = text; mEnteredText = text;
mWordComposer.reset();
} }
@Override @Override
@ -1363,13 +1362,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
ic.deleteSurroundingText(1, 0); ic.deleteSurroundingText(1, 0);
} }
} else { } else {
if (null != mWordSavedForAutoCorrectCancellation) { if (mWordComposer.didAutoCorrectToAnotherWord()) {
Utils.Stats.onAutoCorrectionCancellation(); Utils.Stats.onAutoCorrectionCancellation();
cancelAutoCorrect(ic); cancelAutoCorrect(ic);
mWordSavedForAutoCorrectCancellation = null;
return; return;
} else {
mWordSavedForAutoCorrectCancellation = null;
} }
if (SPACE_STATE_DOUBLE == spaceState) { if (SPACE_STATE_DOUBLE == spaceState) {
@ -1524,9 +1520,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ic != null) { if (ic != null) {
ic.beginBatchEdit(); ic.beginBatchEdit();
} }
// Reset the saved word in all cases. If this separator causes an autocorrection,
// it will overwrite this null with the actual word we need to save.
mWordSavedForAutoCorrectCancellation = null;
if (mWordComposer.isComposingWord()) { if (mWordComposer.isComposingWord()) {
// In certain languages where single quote is a separator, it's better // In certain languages where single quote is a separator, it's better
// not to auto correct, but accept the typed word. For instance, // not to auto correct, but accept the typed word. For instance,
@ -1810,9 +1803,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint); Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
mExpectingUpdateSelection = true; mExpectingUpdateSelection = true;
commitBestWord(autoCorrection); commitBestWord(autoCorrection);
if (!autoCorrection.equals(typedWord)) {
mWordSavedForAutoCorrectCancellation = autoCorrection.toString();
}
// Add the word to the user unigram dictionary if it's not a known word // Add the word to the user unigram dictionary if it's not a known word
addToUserUnigramAndBigramDictionaries(autoCorrection, addToUserUnigramAndBigramDictionaries(autoCorrection,
UserUnigramDictionary.FREQUENCY_FOR_TYPED); UserUnigramDictionary.FREQUENCY_FOR_TYPED);
@ -2103,28 +2093,31 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// "ic" must not be null // "ic" must not be null
private void cancelAutoCorrect(final InputConnection ic) { private void cancelAutoCorrect(final InputConnection ic) {
final int cancelLength = mWordSavedForAutoCorrectCancellation.length(); mWordComposer.resumeSuggestionOnKeptWord();
final String originallyTypedWord = mWordComposer.getTypedWord();
final CharSequence autoCorrectedTo = mWordComposer.getAutoCorrectionOrNull();
final int cancelLength = autoCorrectedTo.length();
final CharSequence separator = ic.getTextBeforeCursor(1, 0); final CharSequence separator = ic.getTextBeforeCursor(1, 0);
if (DEBUG) { if (DEBUG) {
final String wordBeforeCursor = final String wordBeforeCursor =
ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength) ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength)
.toString(); .toString();
if (!mWordSavedForAutoCorrectCancellation.equals(wordBeforeCursor)) { if (!autoCorrectedTo.equals(wordBeforeCursor)) {
throw new RuntimeException("cancelAutoCorrect check failed: we thought we were " throw new RuntimeException("cancelAutoCorrect check failed: we thought we were "
+ "reverting \"" + mWordSavedForAutoCorrectCancellation + "reverting \"" + autoCorrectedTo
+ "\", but before the cursor we found \"" + wordBeforeCursor + "\""); + "\", but before the cursor we found \"" + wordBeforeCursor + "\"");
} }
if (mWordComposer.getTypedWord().equals(wordBeforeCursor)) { if (originallyTypedWord.equals(wordBeforeCursor)) {
throw new RuntimeException("cancelAutoCorrect check failed: we wanted to cancel " throw new RuntimeException("cancelAutoCorrect check failed: we wanted to cancel "
+ "auto correction and revert to \"" + mWordComposer.getTypedWord() + "auto correction and revert to \"" + originallyTypedWord
+ "\" but we found this very string before the cursor"); + "\" but we found this very string before the cursor");
} }
} }
ic.deleteSurroundingText(cancelLength + 1, 0); ic.deleteSurroundingText(cancelLength + 1, 0);
mWordComposer.resumeSuggestionOnKeptWord(); ic.commitText(originallyTypedWord, 1);
ic.commitText(mWordComposer.getTypedWord(), 1);
// Re-insert the separator // Re-insert the separator
ic.commitText(separator, 1); ic.commitText(separator, 1);
mWordComposer.deleteAutoCorrection();
mWordComposer.onCommitWord(); mWordComposer.onCommitWord();
Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE, Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
WordComposer.NOT_A_COORDINATE); WordComposer.NOT_A_COORDINATE);

View File

@ -16,6 +16,8 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import android.text.TextUtils;
import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
@ -40,12 +42,14 @@ public class WordComposer {
int[] mXCoordinates; int[] mXCoordinates;
int[] mYCoordinates; int[] mYCoordinates;
StringBuilder mTypedWord; StringBuilder mTypedWord;
CharSequence mAutoCorrection;
CharacterStore() { CharacterStore() {
final int N = BinaryDictionary.MAX_WORD_LENGTH; final int N = BinaryDictionary.MAX_WORD_LENGTH;
mCodes = new ArrayList<int[]>(N); mCodes = new ArrayList<int[]>(N);
mTypedWord = new StringBuilder(N); mTypedWord = new StringBuilder(N);
mXCoordinates = new int[N]; mXCoordinates = new int[N];
mYCoordinates = new int[N]; mYCoordinates = new int[N];
mAutoCorrection = null;
} }
CharacterStore(final CharacterStore that) { CharacterStore(final CharacterStore that) {
mCodes = new ArrayList<int[]>(that.mCodes); mCodes = new ArrayList<int[]>(that.mCodes);
@ -57,15 +61,14 @@ public class WordComposer {
// For better performance than creating a new character store. // For better performance than creating a new character store.
mCodes.clear(); mCodes.clear();
mTypedWord.setLength(0); mTypedWord.setLength(0);
mAutoCorrection = null;
} }
} }
// The currently typing word. May not be null. // The currently typing word. May not be null.
private CharacterStore mCurrentWord; private CharacterStore mCurrentWord;
// The information being kept for resuming suggestion. May be null if wiped. // The information being kept for resuming suggestion. May be null if wiped.
private CharacterStore mWordKeptForSuggestionResuming; private CharacterStore mCommittedWordSavedForSuggestionResuming;
// An auto-correction for this word out of the dictionary.
private CharSequence mAutoCorrection;
private int mCapsCount; private int mCapsCount;
@ -80,9 +83,8 @@ public class WordComposer {
public WordComposer() { public WordComposer() {
mCurrentWord = new CharacterStore(); mCurrentWord = new CharacterStore();
mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null;
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;
mAutoCorrection = null;
} }
public WordComposer(WordComposer source) { public WordComposer(WordComposer source) {
@ -91,12 +93,11 @@ public class WordComposer {
public void init(WordComposer source) { public void init(WordComposer source) {
mCurrentWord = new CharacterStore(source.mCurrentWord); mCurrentWord = new CharacterStore(source.mCurrentWord);
mWordKeptForSuggestionResuming = source.mWordKeptForSuggestionResuming; mCommittedWordSavedForSuggestionResuming = source.mCommittedWordSavedForSuggestionResuming;
mCapsCount = source.mCapsCount; mCapsCount = source.mCapsCount;
mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized;
mAutoCapitalized = source.mAutoCapitalized; mAutoCapitalized = source.mAutoCapitalized;
mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount;
mAutoCorrection = null;
} }
/** /**
@ -104,11 +105,10 @@ public class WordComposer {
*/ */
public void reset() { public void reset() {
mCurrentWord.reset(); mCurrentWord.reset();
mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null;
mCapsCount = 0; mCapsCount = 0;
mIsFirstCharCapitalized = false; mIsFirstCharCapitalized = false;
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;
mAutoCorrection = null;
} }
/** /**
@ -167,7 +167,7 @@ public class WordComposer {
} else { } else {
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;
} }
mAutoCorrection = null; mCurrentWord.mAutoCorrection = null;
} }
/** /**
@ -201,7 +201,7 @@ public class WordComposer {
int codePoint = word.charAt(i); int codePoint = word.charAt(i);
addKeyInfo(codePoint, keyboard, keyDetector); addKeyInfo(codePoint, keyboard, keyDetector);
} }
mAutoCorrection = null; mCommittedWordSavedForSuggestionResuming = null;
} }
/** /**
@ -253,7 +253,7 @@ public class WordComposer {
++mTrailingSingleQuotesCount; ++mTrailingSingleQuotesCount;
} }
} }
mAutoCorrection = null; mCurrentWord.mAutoCorrection = null;
} }
/** /**
@ -312,37 +312,44 @@ public class WordComposer {
* Sets the auto-correction for this word. * Sets the auto-correction for this word.
*/ */
public void setAutoCorrection(final CharSequence correction) { public void setAutoCorrection(final CharSequence correction) {
mAutoCorrection = correction; mCurrentWord.mAutoCorrection = correction;
} }
/** /**
* Remove any auto-correction that may have been set. * Remove any auto-correction that may have been set.
*/ */
public void deleteAutoCorrection() { public void deleteAutoCorrection() {
mAutoCorrection = null; mCurrentWord.mAutoCorrection = null;
} }
/** /**
* @return the auto-correction for this word, or null if none. * @return the auto-correction for this word, or null if none.
*/ */
public CharSequence getAutoCorrectionOrNull() { public CharSequence getAutoCorrectionOrNull() {
return mAutoCorrection; return mCurrentWord.mAutoCorrection;
} }
// TODO: pass the information about what was committed and how. Was it an auto-correction? // TODO: pass the information about what was committed and how. Was it an auto-correction?
// Was it a completion? Was is what the user typed? // Was it a completion? Was is what the user typed?
public void onCommitWord() { public void onCommitWord() {
mWordKeptForSuggestionResuming = mCurrentWord; mCommittedWordSavedForSuggestionResuming = mCurrentWord;
// TODO: improve performance by swapping buffers instead of creating a new object. // TODO: improve performance by swapping buffers instead of creating a new object.
mCurrentWord = new CharacterStore(); mCurrentWord = new CharacterStore();
} }
public boolean hasWordKeptForSuggestionResuming() { public boolean hasWordKeptForSuggestionResuming() {
return null != mWordKeptForSuggestionResuming; return null != mCommittedWordSavedForSuggestionResuming;
} }
public void resumeSuggestionOnKeptWord() { public void resumeSuggestionOnKeptWord() {
mCurrentWord = mWordKeptForSuggestionResuming; mCurrentWord = mCommittedWordSavedForSuggestionResuming;
mWordKeptForSuggestionResuming = null; mCommittedWordSavedForSuggestionResuming = null;
}
public boolean didAutoCorrectToAnotherWord() {
return null != mCommittedWordSavedForSuggestionResuming
&& !TextUtils.isEmpty(mCommittedWordSavedForSuggestionResuming.mAutoCorrection)
&& !TextUtils.equals(mCommittedWordSavedForSuggestionResuming.mTypedWord,
mCommittedWordSavedForSuggestionResuming.mAutoCorrection);
} }
} }