Always show the typed word in recorrections.
Bug: 11330140 Bug: 17875601 Bug: 17623275 Change-Id: Ie4620f36f312c54c7b01b5f6cbdb0bc9171b6179main
parent
41302021d6
commit
bc18005948
|
@ -1627,7 +1627,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
|
||||
@Override
|
||||
public void showAddToDictionaryHint(final String word) {
|
||||
public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip) {
|
||||
if (!hasSuggestionStripView()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1637,7 +1637,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
} else {
|
||||
wordToShow = word;
|
||||
}
|
||||
mSuggestionStripView.showAddToDictionaryHint(wordToShow);
|
||||
mSuggestionStripView.showAddToDictionaryHint(wordToShow,
|
||||
isFromSuggestionStrip /* shouldShowWordToSave */);
|
||||
}
|
||||
|
||||
// This will show either an empty suggestion strip (if prediction is enabled) or
|
||||
|
|
|
@ -413,28 +413,6 @@ public class SuggestedWords {
|
|||
return isPrediction(mInputStyle);
|
||||
}
|
||||
|
||||
// SuggestedWords is an immutable object, as much as possible. We must not just remove
|
||||
// words from the member ArrayList as some other parties may expect the object to never change.
|
||||
// This is only ever called by recorrection at the moment, hence the ForRecorrection moniker.
|
||||
public SuggestedWords getSuggestedWordsExcludingTypedWordForRecorrection() {
|
||||
final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
|
||||
String typedWord = null;
|
||||
for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
|
||||
final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
|
||||
if (!info.isKindOf(SuggestedWordInfo.KIND_TYPED)) {
|
||||
newSuggestions.add(info);
|
||||
} else {
|
||||
assert(null == typedWord);
|
||||
typedWord = info.mWord;
|
||||
}
|
||||
}
|
||||
// We should never autocorrect, so we say the typed word is valid. Also, in this case,
|
||||
// no auto-correction should take place hence willAutoCorrect = false.
|
||||
return new SuggestedWords(newSuggestions, null /* rawSuggestions */, typedWord,
|
||||
true /* typedWordValid */, false /* willAutoCorrect */, mIsObsoleteSuggestions,
|
||||
SuggestedWords.INPUT_STYLE_RECORRECTION, NOT_A_SEQUENCE_NUMBER);
|
||||
}
|
||||
|
||||
// Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
|
||||
// last word of all suggestions, separated by a space. This is necessary because when we commit
|
||||
// a multiple-word suggestion, the IME only retains the last word as the composing word, and
|
||||
|
|
|
@ -349,7 +349,8 @@ public final class InputLogic {
|
|||
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
|
||||
|
||||
if (shouldShowAddToDictionaryHint) {
|
||||
mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
|
||||
mSuggestionStripViewAccessor.suggestAddingToDictionary(suggestion,
|
||||
true /* isFromSuggestionStrip */);
|
||||
} else {
|
||||
// If we're not showing the "Touch again to save", then update the suggestion strip.
|
||||
// That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
|
||||
|
@ -1485,6 +1486,11 @@ public final class InputLogic {
|
|||
if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return;
|
||||
final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
|
||||
final String typedWord = range.mWord.toString();
|
||||
suggestions.add(new SuggestedWordInfo(typedWord,
|
||||
SuggestedWords.MAX_SUGGESTIONS + 1,
|
||||
SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
|
||||
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
|
||||
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
|
||||
if (!isResumableWord(settingsValues, typedWord)) {
|
||||
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
|
||||
return;
|
||||
|
@ -1517,30 +1523,14 @@ public final class InputLogic {
|
|||
mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug();
|
||||
mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor,
|
||||
expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor());
|
||||
if (suggestions.size() <= 0) {
|
||||
if (suggestions.size() <= 1) {
|
||||
// If there weren't any suggestion spans on this word, suggestions#size() will be 1
|
||||
// if shouldIncludeResumedWordInSuggestions is true, 0 otherwise. In this case, we
|
||||
// have no useful suggestions, so we will try to compute some for it instead.
|
||||
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_ID_TYPING,
|
||||
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
|
||||
@Override
|
||||
public void onGetSuggestedWords(
|
||||
final SuggestedWords suggestedWordsIncludingTypedWord) {
|
||||
final SuggestedWords suggestedWords;
|
||||
if (suggestedWordsIncludingTypedWord.size() > 1) {
|
||||
// We were able to compute new suggestions for this word.
|
||||
// Remove the typed word, since we don't want to display it in this
|
||||
// case. The #getSuggestedWordsExcludingTypedWordForRecorrection()
|
||||
// method sets willAutoCorrect to false.
|
||||
suggestedWords = suggestedWordsIncludingTypedWord
|
||||
.getSuggestedWordsExcludingTypedWordForRecorrection();
|
||||
} else {
|
||||
// No saved suggestions, and we were unable to compute any good one
|
||||
// either. Rather than displaying an empty suggestion strip, we'll
|
||||
// display the original word alone in the middle.
|
||||
// Since there is only one word, willAutoCorrect is false.
|
||||
suggestedWords = suggestedWordsIncludingTypedWord;
|
||||
}
|
||||
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
|
||||
mIsAutoCorrectionIndicatorOn = false;
|
||||
mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
|
||||
}});
|
||||
|
@ -1684,7 +1674,8 @@ public final class InputLogic {
|
|||
mConnection.getExpectedSelectionStart(),
|
||||
mConnection.getExpectedSelectionEnd());
|
||||
}
|
||||
mSuggestionStripViewAccessor.showAddToDictionaryHint(originallyTypedWordString);
|
||||
mSuggestionStripViewAccessor.suggestAddingToDictionary(originallyTypedWordString,
|
||||
false /* isFromSuggestionStrip */);
|
||||
} else {
|
||||
// We have a separator between the word and the cursor: we should show predictions.
|
||||
inputTransaction.setRequiresUpdateSuggestions();
|
||||
|
|
|
@ -553,12 +553,12 @@ final class SuggestionStripLayoutHelper {
|
|||
return countInStrip;
|
||||
}
|
||||
|
||||
public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip) {
|
||||
final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent()
|
||||
.mShouldShowLxxSuggestionUi;
|
||||
public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip,
|
||||
final boolean shouldShowWordToSave) {
|
||||
final boolean showsHintWithWord = shouldShowWordToSave
|
||||
|| !Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi;
|
||||
final int stripWidth = addToDictionaryStrip.getWidth();
|
||||
final int width = shouldShowUiToAcceptTypedWord ? stripWidth
|
||||
: stripWidth - mDividerWidth - mPadding * 2;
|
||||
final int width = stripWidth - (showsHintWithWord ? mDividerWidth + mPadding * 2 : 0);
|
||||
|
||||
final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save);
|
||||
wordView.setTextColor(mColorTypedWord);
|
||||
|
@ -569,7 +569,7 @@ final class SuggestionStripLayoutHelper {
|
|||
wordView.setText(wordToSave);
|
||||
wordView.setTextScaleX(wordScaleX);
|
||||
setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
final int wordVisibility = shouldShowUiToAcceptTypedWord ? View.GONE : View.VISIBLE;
|
||||
final int wordVisibility = showsHintWithWord ? View.VISIBLE : View.GONE;
|
||||
wordView.setVisibility(wordVisibility);
|
||||
addToDictionaryStrip.findViewById(R.id.word_to_save_divider).setVisibility(wordVisibility);
|
||||
|
||||
|
@ -579,12 +579,7 @@ final class SuggestionStripLayoutHelper {
|
|||
final float hintWeight;
|
||||
final TextView hintView = (TextView)addToDictionaryStrip.findViewById(
|
||||
R.id.hint_add_to_dictionary);
|
||||
if (shouldShowUiToAcceptTypedWord) {
|
||||
hintText = res.getText(R.string.hint_add_to_dictionary_without_word);
|
||||
hintWidth = width;
|
||||
hintWeight = 1.0f;
|
||||
hintView.setGravity(Gravity.CENTER);
|
||||
} else {
|
||||
if (showsHintWithWord) {
|
||||
final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip)
|
||||
== ViewCompat.LAYOUT_DIRECTION_RTL);
|
||||
final String arrow = isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW;
|
||||
|
@ -595,6 +590,11 @@ final class SuggestionStripLayoutHelper {
|
|||
hintWidth = width - wordWidth;
|
||||
hintWeight = 1.0f - mCenterSuggestionWeight;
|
||||
hintView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
|
||||
} else {
|
||||
hintText = res.getText(R.string.hint_add_to_dictionary_without_word);
|
||||
hintWidth = width;
|
||||
hintWeight = 1.0f;
|
||||
hintView.setGravity(Gravity.CENTER);
|
||||
}
|
||||
hintView.setTextColor(mColorAutoCorrect);
|
||||
final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint());
|
||||
|
|
|
@ -231,8 +231,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
return mStripVisibilityGroup.isShowingAddToDictionaryStrip();
|
||||
}
|
||||
|
||||
public void showAddToDictionaryHint(final String word) {
|
||||
mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip);
|
||||
public void showAddToDictionaryHint(final String word, final boolean shouldShowWordToSave) {
|
||||
mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip, shouldShowWordToSave);
|
||||
// {@link TextView#setTag()} is used to hold the word to be added to dictionary. The word
|
||||
// will be extracted at {@link #onClick(View)}.
|
||||
mAddToDictionaryStrip.setTag(word);
|
||||
|
@ -501,7 +501,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
return;
|
||||
}
|
||||
final Object tag = view.getTag();
|
||||
// {@link String} tag is set at {@link #showAddToDictionaryHint(String,CharSequence)}.
|
||||
// {@link String} tag is set at {@link #suggestAddingToDictionary(String,CharSequence)}.
|
||||
if (tag instanceof String) {
|
||||
final String wordToSave = (String)tag;
|
||||
mListener.addWordToUserDictionary(wordToSave);
|
||||
|
|
|
@ -22,7 +22,7 @@ import com.android.inputmethod.latin.SuggestedWords;
|
|||
* An object that gives basic control of a suggestion strip and some info on it.
|
||||
*/
|
||||
public interface SuggestionStripViewAccessor {
|
||||
public void showAddToDictionaryHint(final String word);
|
||||
public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip);
|
||||
public boolean isShowingAddToDictionaryHint();
|
||||
public void dismissAddToDictionaryHint();
|
||||
public void setNeutralSuggestionStrip();
|
||||
|
|
|
@ -59,40 +59,6 @@ public class SuggestedWordsTests extends AndroidTestCase {
|
|||
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
|
||||
}
|
||||
|
||||
public void testGetSuggestedWordsExcludingTypedWord() {
|
||||
final String TYPED_WORD = "typed";
|
||||
final int NUMBER_OF_ADDED_SUGGESTIONS = 5;
|
||||
final int KIND_OF_SECOND_CORRECTION = SuggestedWordInfo.KIND_CORRECTION;
|
||||
final ArrayList<SuggestedWordInfo> list = new ArrayList<>();
|
||||
list.add(createTypedWordInfo(TYPED_WORD));
|
||||
for (int i = 0; i < NUMBER_OF_ADDED_SUGGESTIONS; ++i) {
|
||||
list.add(createCorrectionWordInfo(Integer.toString(i)));
|
||||
}
|
||||
|
||||
final SuggestedWords words = new SuggestedWords(
|
||||
list, null /* rawSuggestions */,
|
||||
false /* typedWordValid */,
|
||||
false /* willAutoCorrect */,
|
||||
false /* isObsoleteSuggestions */,
|
||||
SuggestedWords.INPUT_STYLE_NONE);
|
||||
assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
|
||||
assertEquals("typed", words.getWord(0));
|
||||
assertTrue(words.getInfo(0).isKindOf(SuggestedWordInfo.KIND_TYPED));
|
||||
assertEquals("0", words.getWord(1));
|
||||
assertTrue(words.getInfo(1).isKindOf(KIND_OF_SECOND_CORRECTION));
|
||||
assertEquals("4", words.getWord(5));
|
||||
assertTrue(words.getInfo(5).isKindOf(KIND_OF_SECOND_CORRECTION));
|
||||
|
||||
final SuggestedWords wordsWithoutTyped =
|
||||
words.getSuggestedWordsExcludingTypedWordForRecorrection();
|
||||
// Make sure that the typed word has indeed been excluded, by testing the size of the
|
||||
// suggested words, the string and the kind of the top suggestion, which should match
|
||||
// the string and kind of what we inserted after the typed word.
|
||||
assertEquals(words.size() - 1, wordsWithoutTyped.size());
|
||||
assertEquals("0", wordsWithoutTyped.getWord(0));
|
||||
assertTrue(wordsWithoutTyped.getInfo(0).isKindOf(KIND_OF_SECOND_CORRECTION));
|
||||
}
|
||||
|
||||
// Helper for testGetTransformedWordInfo
|
||||
private SuggestedWordInfo transformWordInfo(final String info,
|
||||
final int trailingSingleQuotesCount) {
|
||||
|
@ -141,9 +107,14 @@ public class SuggestedWordsTests extends AndroidTestCase {
|
|||
assertNotNull(typedWord);
|
||||
assertEquals(TYPED_WORD, typedWord.mWord);
|
||||
|
||||
// Make sure getTypedWordInfoOrNull() returns null.
|
||||
final SuggestedWords wordsWithoutTypedWord =
|
||||
wordsWithTypedWord.getSuggestedWordsExcludingTypedWordForRecorrection();
|
||||
// Make sure getTypedWordInfoOrNull() returns null when no typed word.
|
||||
list.remove(0);
|
||||
final SuggestedWords wordsWithoutTypedWord = new SuggestedWords(
|
||||
list, null /* rawSuggestions */,
|
||||
false /* typedWordValid */,
|
||||
false /* willAutoCorrect */,
|
||||
false /* isObsoleteSuggestions */,
|
||||
SuggestedWords.INPUT_STYLE_NONE);
|
||||
assertNull(wordsWithoutTypedWord.getTypedWordInfoOrNull());
|
||||
|
||||
// Make sure getTypedWordInfoOrNull() returns null.
|
||||
|
|
Loading…
Reference in New Issue