Merge "Reorganize the auto-correction memory"
commit
715a203501
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue