Merge "[IL56] Don't erase suggestions when reverting a commit."

main
Jean Chalard 2014-01-15 19:21:06 +00:00 committed by Android (Google) Code Review
commit 118a4fc2b7
4 changed files with 50 additions and 21 deletions

View File

@ -42,7 +42,7 @@ public final class LastComposedWord {
public final int[] mPrimaryKeyCodes; public final int[] mPrimaryKeyCodes;
public final String mTypedWord; public final String mTypedWord;
public final String mCommittedWord; public final CharSequence mCommittedWord;
public final String mSeparatorString; public final String mSeparatorString;
public final String mPrevWord; public final String mPrevWord;
public final int mCapitalizedMode; public final int mCapitalizedMode;
@ -58,7 +58,7 @@ public final class LastComposedWord {
// Warning: this is using the passed objects as is and fully expects them to be // Warning: this is using the passed objects as is and fully expects them to be
// 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 separatorString, final String typedWord, final CharSequence committedWord, final String separatorString,
final String prevWord, final int capitalizedMode) { final String prevWord, final int capitalizedMode) {
mPrimaryKeyCodes = primaryKeyCodes; mPrimaryKeyCodes = primaryKeyCodes;
if (inputPointers != null) { if (inputPointers != null) {

View File

@ -1389,7 +1389,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// We're checking the previous word in the text field against the memorized previous // We're checking the previous word in the text field against the memorized previous
// word. If we are composing a word we should have the second word before the cursor // word. If we are composing a word we should have the second word before the cursor
// memorized, otherwise we should have the first. // memorized, otherwise we should have the first.
final String rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion( final CharSequence rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion(
currentSettings.mSpacingAndPunctuations, currentSettings.mSpacingAndPunctuations,
mInputLogic.mWordComposer.isComposingWord() ? 2 : 1); mInputLogic.mWordComposer.isComposingWord() ? 2 : 1);
if (!TextUtils.equals(previousWord, rereadPrevWord)) { if (!TextUtils.equals(previousWord, rereadPrevWord)) {

View File

@ -297,7 +297,7 @@ public final class WordComposer {
* the context is nil (typically, at start of text). * the context is nil (typically, at start of text).
* @param keyboard the keyboard this is typed on, for coordinate info/proximity. * @param keyboard the keyboard this is typed on, for coordinate info/proximity.
*/ */
public void setComposingWord(final CharSequence word, final String previousWord, public void setComposingWord(final CharSequence word, final CharSequence previousWord,
final Keyboard keyboard) { final Keyboard keyboard) {
reset(); reset();
final int length = word.length(); final int length = word.length();
@ -306,7 +306,7 @@ public final class WordComposer {
addKeyInfo(codePoint, keyboard); addKeyInfo(codePoint, keyboard);
} }
mIsResumed = true; mIsResumed = true;
mPreviousWordForSuggestion = previousWord; mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString();
} }
/** /**
@ -418,9 +418,9 @@ public final class WordComposer {
* @param previousWord the previous word as context for suggestions. May be null if none. * @param previousWord the previous word as context for suggestions. May be null if none.
*/ */
public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode, public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode,
final String previousWord) { final CharSequence previousWord) {
mCapitalizedMode = mode; mCapitalizedMode = mode;
mPreviousWordForSuggestion = previousWord; mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString();
} }
/** /**
@ -454,7 +454,8 @@ public final 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, // committedWord should contain suggestion spans if applicable.
public LastComposedWord commitWord(final int type, final CharSequence committedWord,
final String separatorString, final String prevWord) { final String separatorString, final String 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
@ -472,7 +473,7 @@ public final class WordComposer {
mCapsCount = 0; mCapsCount = 0;
mDigitsCount = 0; mDigitsCount = 0;
mIsBatchMode = false; mIsBatchMode = false;
mPreviousWordForSuggestion = committedWord; mPreviousWordForSuggestion = committedWord.toString();
mTypedWord.setLength(0); mTypedWord.setLength(0);
mCodePointSize = 0; mCodePointSize = 0;
mTrailingSingleQuotesCount = 0; mTrailingSingleQuotesCount = 0;

View File

@ -17,6 +17,7 @@
package com.android.inputmethod.latin.inputlogic; package com.android.inputmethod.latin.inputlogic;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.SuggestionSpan; import android.text.style.SuggestionSpan;
import android.util.Log; import android.util.Log;
@ -1168,8 +1169,8 @@ public final class InputLogic {
// TODO: remove these arguments // TODO: remove these arguments
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) { final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
final String previousWord = mLastComposedWord.mPrevWord; final String previousWord = mLastComposedWord.mPrevWord;
final String originallyTypedWord = mLastComposedWord.mTypedWord; final CharSequence originallyTypedWord = mLastComposedWord.mTypedWord;
final String committedWord = mLastComposedWord.mCommittedWord; final CharSequence committedWord = mLastComposedWord.mCommittedWord;
final int cancelLength = committedWord.length(); final int cancelLength = committedWord.length();
// We want java chars, not codepoints for the following. // We want java chars, not codepoints for the following.
final int separatorLength = mLastComposedWord.mSeparatorString.length(); final int separatorLength = mLastComposedWord.mSeparatorString.length();
@ -1191,28 +1192,53 @@ public final class InputLogic {
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) { if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
if (mSuggest != null) { if (mSuggest != null) {
mSuggest.mDictionaryFacilitator.cancelAddingUserHistory( mSuggest.mDictionaryFacilitator.cancelAddingUserHistory(
previousWord, committedWord); previousWord, committedWord.toString());
}
}
final SpannableString textToCommit =
new SpannableString(originallyTypedWord + mLastComposedWord.mSeparatorString);
if (committedWord instanceof SpannableString) {
final int lastCharIndex = textToCommit.length() - 1;
// Add the auto-correction to the list of suggestions.
textToCommit.setSpan(new SuggestionSpan(settingsValues.mLocale,
new String[] { committedWord.toString() }, 0 /* flags */),
0 /* start */, lastCharIndex /* end */, 0 /* flags */);
final SpannableString committedWordWithSuggestionSpans = (SpannableString)committedWord;
final Object[] spans = committedWordWithSuggestionSpans.getSpans(0,
committedWord.length(), Object.class);
for (final Object span : spans) {
// Put all the spans in the original text on this new text. We could remove the
// typed word from the suggestions, but we'd have to make more dynamic instanceof
// checks, to copy the span, copy all suggestions and attributes... And there is
// the risk to drop the originally typed string if there is a subtle bug. There is
// still the committed auto-correction that we reverted from, which is not included
// in the suggestions, that's why we added it with another call to setSpan a few
// lines above.
// The code that re-reads these spans already knows to do the right thing whether
// the typed word is included or not. That should be enough.
textToCommit.setSpan(span, 0 /* start */, lastCharIndex /* end */,
committedWordWithSuggestionSpans.getSpanFlags(span));
} }
} }
final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
if (settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) { if (settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
// For languages with spaces, we revert to the typed string, but the cursor is still // For languages with spaces, we revert to the typed string, but the cursor is still
// after the separator so we don't resume suggestions. If the user wants to correct // after the separator so we don't resume suggestions. If the user wants to correct
// the word, they have to press backspace again. // the word, they have to press backspace again.
mConnection.commitText(stringToCommit, 1); mConnection.commitText(textToCommit, 1);
} else { } else {
// For languages without spaces, we revert the typed string but the cursor is flush // For languages without spaces, we revert the typed string but the cursor is flush
// with the typed word, so we need to resume suggestions right away. // with the typed word, so we need to resume suggestions right away.
mWordComposer.setComposingWord(stringToCommit, previousWord, mWordComposer.setComposingWord(textToCommit, previousWord,
keyboardSwitcher.getKeyboard()); keyboardSwitcher.getKeyboard());
mConnection.setComposingText(stringToCommit, 1); mConnection.setComposingText(textToCommit, 1);
} }
if (settingsValues.mIsInternal) { if (settingsValues.mIsInternal) {
LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString, LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
} }
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_revertCommit(committedWord, originallyTypedWord, ResearchLogger.latinIME_revertCommit(committedWord.toString(),
originallyTypedWord.toString(),
mWordComposer.isBatchMode(), mLastComposedWord.mSeparatorString); mWordComposer.isBatchMode(), mLastComposedWord.mSeparatorString);
} }
// Don't restart suggestion yet. We'll restart if the user deletes the // Don't restart suggestion yet. We'll restart if the user deletes the
@ -1294,7 +1320,7 @@ public final class InputLogic {
* @return the nth previous word before the cursor. * @return the nth previous word before the cursor.
*/ */
// TODO: Make this private // TODO: Make this private
public String getNthPreviousWordForSuggestion( public CharSequence getNthPreviousWordForSuggestion(
final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) { final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) {
if (spacingAndPunctuations.mCurrentLanguageHasSpaces) { if (spacingAndPunctuations.mCurrentLanguageHasSpaces) {
// If we are typing in a language with spaces we can just look up the previous // If we are typing in a language with spaces we can just look up the previous
@ -1645,8 +1671,10 @@ public final class InputLogic {
public void commitChosenWord(final SettingsValues settingsValues, final String chosenWord, public void commitChosenWord(final SettingsValues settingsValues, final String chosenWord,
final int commitType, final String separatorString) { final int commitType, final String separatorString) {
final SuggestedWords suggestedWords = mSuggestedWords; final SuggestedWords suggestedWords = mSuggestedWords;
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord, final CharSequence chosenWordWithSuggestions =
suggestedWords), 1); SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord,
suggestedWords);
mConnection.commitText(chosenWordWithSuggestions, 1);
// TODO: we pass 2 here, but would it be better to move this above and pass 1 instead? // TODO: we pass 2 here, but would it be better to move this above and pass 1 instead?
final String prevWord = mConnection.getNthPreviousWord( final String prevWord = mConnection.getNthPreviousWord(
settingsValues.mSpacingAndPunctuations, 2); settingsValues.mSpacingAndPunctuations, 2);
@ -1657,7 +1685,7 @@ public final class InputLogic {
// LastComposedWord#didCommitTypedWord by string equality of the remembered // LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings. // strings.
mLastComposedWord = mWordComposer.commitWord(commitType, mLastComposedWord = mWordComposer.commitWord(commitType,
chosenWord, separatorString, prevWord); chosenWordWithSuggestions, separatorString, prevWord);
final boolean shouldDiscardPreviousWordForSuggestion; final boolean shouldDiscardPreviousWordForSuggestion;
if (0 == StringUtils.codePointCount(separatorString)) { if (0 == StringUtils.codePointCount(separatorString)) {
// Separator is 0-length, we can keep the previous word for suggestion. Either this // Separator is 0-length, we can keep the previous word for suggestion. Either this