From 1e50c681af56dd77d97a1e6d463f1e3023c1a69b Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 25 Dec 2013 21:43:23 +0900 Subject: [PATCH] [IL52] Remove a useless method. This old method doesn't even re-read the old suggestions. It used to recompute them without the coordinates. Re-using the recorrection code, which is much more advanced, is the right thing to do here. Also, refining the test. It's no use trying to resume suggestion if we don't have a suggestion strip, since we aren't going to auto-correct anything anyway. Not the motivation for this change, but this also fixes Bug: 11620256 Change-Id: Id49efa32e293c49837c61fdc752c86bbac1d2c88 --- .../android/inputmethod/latin/LatinIME.java | 3 +- .../latin/RichInputConnection.java | 39 ------------ .../latin/inputlogic/InputLogic.java | 61 +++++++------------ .../inputmethod/latin/BlueUnderlineTests.java | 3 + .../inputmethod/latin/InputLogicTests.java | 6 +- 5 files changed, 32 insertions(+), 80 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index a62c22cbf..5a5674f8f 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -201,7 +201,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; case MSG_RESUME_SUGGESTIONS: latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor( - latinIme.mSettings.getCurrent(), latinIme.mKeyboardSwitcher); + latinIme.mSettings.getCurrent(), 0 /* offset */, + false /* includeResumedWordInSuggestions */, latinIme.mKeyboardSwitcher); break; case MSG_REOPEN_DICTIONARIES: latinIme.initSuggest(); diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 37311acf2..4d174ddb8 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -706,45 +706,6 @@ public final class RichInputConnection { return TextUtils.equals(text, beforeText); } - /* (non-javadoc) - * Returns the word before the cursor if the cursor is at the end of a word, null otherwise - */ - public CharSequence getWordBeforeCursorIfAtEndOfWord(final SettingsValues settings) { - // Bail out if the cursor is in the middle of a word (cursor must be followed by whitespace, - // separator or end of line/text) - // Example: "test|" "te|st" get rejected here - final CharSequence textAfterCursor = getTextAfterCursor(1, 0); - if (!TextUtils.isEmpty(textAfterCursor) - && !settings.isWordSeparator(textAfterCursor.charAt(0))) return null; - - // Bail out if word before cursor is 0-length or a single non letter (like an apostrophe) - // Example: " -|" gets rejected here but "e-|" and "e|" are okay - CharSequence word = getWordAtCursor(settings.mWordSeparators); - // We don't suggest on leading single quotes, so we have to remove them from the word if - // it starts with single quotes. - while (!TextUtils.isEmpty(word) && Constants.CODE_SINGLE_QUOTE == word.charAt(0)) { - word = word.subSequence(1, word.length()); - } - if (TextUtils.isEmpty(word)) return null; - // Find the last code point of the string - final int lastCodePoint = Character.codePointBefore(word, word.length()); - // If for some reason the text field contains non-unicode binary data, or if the - // charsequence is exactly one char long and the contents is a low surrogate, return null. - if (!Character.isDefined(lastCodePoint)) return null; - // Bail out if the cursor is not at the end of a word (cursor must be preceded by - // non-whitespace, non-separator, non-start-of-text) - // Example ("|" is the cursor here) : "|a" " |a" " | " all get rejected here. - if (settings.isWordSeparator(lastCodePoint)) return null; - final char firstChar = word.charAt(0); // we just tested that word is not empty - if (word.length() == 1 && !Character.isLetter(firstChar)) return null; - - // We don't restart suggestion if the first character is not a letter, because we don't - // start composing when the first character is not a letter. - if (!Character.isLetter(firstChar)) return null; - - return word; - } - public boolean revertDoubleSpacePeriod() { if (DEBUG_BATCH_NESTING) checkBatchEdit(); // Here we test whether we indeed have a period and a space before us. This should not diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index ced3f049b..b365003a5 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -680,6 +680,7 @@ public final class InputLogic { // TODO: remove these arguments final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) { mSpaceState = SpaceState.NONE; + final int deleteCountAtStart = mDeleteCount; mDeleteCount++; // In many cases, we may have to put the keyboard in auto-shift state again. However @@ -811,12 +812,13 @@ public final class InputLogic { } } } - if (settingsValues.isSuggestionsRequested() + if (settingsValues.isSuggestionStripVisible() && settingsValues.mCurrentLanguageHasSpaces) { - restartSuggestionsOnWordBeforeCursorIfAtEndOfWord(settingsValues, keyboardSwitcher, - handler); + restartSuggestionsOnWordTouchedByCursor(settingsValues, + deleteCountAtStart - mDeleteCount /* offset */, + true /* includeResumedWordInSuggestions */, keyboardSwitcher); } - // We just removed a character. We need to update the auto-caps state. + // We just removed at least one character. We need to update the auto-caps state. keyboardSwitcher.updateShiftState(); } } @@ -1041,44 +1043,18 @@ public final class InputLogic { } } - /** - * Check if the cursor is actually at the end of a word. If so, restart suggestions on this - * word, otherwise do nothing. - * @param settingsValues the current values of the settings. - */ - private void restartSuggestionsOnWordBeforeCursorIfAtEndOfWord( - final SettingsValues settingsValues, - // TODO: remove these two arguments - final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) { - final CharSequence word = mConnection.getWordBeforeCursorIfAtEndOfWord(settingsValues); - if (null != word) { - final String wordString = word.toString(); - mWordComposer.setComposingWord(word, - // Previous word is the 2nd word before cursor because we are restarting on the - // 1st word before cursor. - getNthPreviousWordForSuggestion(settingsValues, 2 /* nthPreviousWord */), - keyboardSwitcher.getKeyboard()); - final int length = word.length(); - mConnection.deleteSurroundingText(length, 0); - mConnection.setComposingText(word, 1); - handler.postUpdateSuggestionStrip(); - // TODO: Handle the case where the user manually moves the cursor and then backs up over - // a separator. In that case, the current log unit should not be uncommitted. - if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - ResearchLogger.getInstance().uncommitCurrentLogUnit(wordString, - true /* dumpCurrentLogUnit */); - } - } - } - /** * Check if the cursor is touching a word. If so, restart suggestions on this word, else * do nothing. * * @param settingsValues the current values of the settings. + * @param offset how much the cursor is expected to have moved since the last updateSelection. + * @param includeResumedWordInSuggestions whether to include the word on which we resume + * suggestions in the suggestion list. */ // TODO: make this private. public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues, + final int offset, final boolean includeResumedWordInSuggestions, // TODO: Remove this argument. final KeyboardSwitcher keyboardSwitcher) { // HACK: We may want to special-case some apps that exhibit bad behavior in case of @@ -1094,6 +1070,7 @@ public final class InputLogic { if (mLastSelectionStart != mLastSelectionEnd) return; // If we don't know the cursor location, return. if (mLastSelectionStart < 0) return; + final int expectedCursorPosition = mLastSelectionStart + offset; // We know Start == End if (!mConnection.isCursorTouchingWord(settingsValues)) return; final TextRange range = mConnection.getWordRangeAtCursor( settingsValues.mWordSeparators, 0 /* additionalPrecedingWordsCount */); @@ -1102,9 +1079,16 @@ public final class InputLogic { // If for some strange reason (editor bug or so) we measure the text before the cursor as // longer than what the entire text is supposed to be, the safe thing to do is bail out. final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor(); - if (numberOfCharsInWordBeforeCursor > mLastSelectionStart) return; + if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return; final ArrayList suggestions = CollectionUtils.newArrayList(); final String typedWord = range.mWord.toString(); + if (includeResumedWordInSuggestions) { + suggestions.add(new SuggestedWordInfo(typedWord, + SuggestionStripView.MAX_SUGGESTIONS + 1, + SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, + SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, + SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); + } if (!isResumableWord(settingsValues, typedWord)) return; int i = 0; for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) { @@ -1129,8 +1113,8 @@ public final class InputLogic { keyboardSwitcher.getKeyboard()); mWordComposer.setCursorPositionWithinWord( typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor)); - mConnection.setComposingRegion(mLastSelectionStart - numberOfCharsInWordBeforeCursor, - mLastSelectionEnd + range.getNumberOfCharsInWordAfterCursor()); + mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor, + expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor()); if (suggestions.isEmpty()) { // We come here if there weren't any suggestion spans on this word. We will try to // compute suggestions for it instead. @@ -1140,7 +1124,8 @@ public final class InputLogic { public void onGetSuggestedWords( final SuggestedWords suggestedWordsIncludingTypedWord) { final SuggestedWords suggestedWords; - if (suggestedWordsIncludingTypedWord.size() > 1) { + if (suggestedWordsIncludingTypedWord.size() > 1 + && !includeResumedWordInSuggestions) { // 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 #getSuggestedWordsExcludingTypedWord() method sets diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java index c4fd5a0c4..cdd8f6b85 100644 --- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java +++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java @@ -61,6 +61,7 @@ public class BlueUnderlineTests extends InputTestsBase { public void testBlueUnderlineOnBackspace() { final String STRING_TO_TYPE = "tgis"; + final int typedLength = STRING_TO_TYPE.length(); final int EXPECTED_SUGGESTION_SPAN_START = -1; final int EXPECTED_UNDERLINE_SPAN_START = 0; final int EXPECTED_UNDERLINE_SPAN_END = 4; @@ -68,6 +69,8 @@ public class BlueUnderlineTests extends InputTestsBase { sleep(DELAY_TO_WAIT_FOR_UNDERLINE); runMessages(); type(Constants.CODE_SPACE); + // typedLength + 1 because we also typed a space + mLatinIME.onUpdateSelection(0, 0, typedLength + 1, typedLength + 1, -1, -1); sleep(DELAY_TO_WAIT_FOR_UNDERLINE); runMessages(); type(Constants.CODE_DELETE); diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java index da8627aa3..039f581a7 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java @@ -307,12 +307,14 @@ public class InputLogicTests extends InputTestsBase { } public void testResumeSuggestionOnBackspace() { - final String WORD_TO_TYPE = "and this "; - type(WORD_TO_TYPE); + final String STRING_TO_TYPE = "and this "; + final int typedLength = STRING_TO_TYPE.length(); + type(STRING_TO_TYPE); assertEquals("resume suggestion on backspace", -1, BaseInputConnection.getComposingSpanStart(mEditText.getText())); assertEquals("resume suggestion on backspace", -1, BaseInputConnection.getComposingSpanEnd(mEditText.getText())); + mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1); type(Constants.CODE_DELETE); assertEquals("resume suggestion on backspace", 4, BaseInputConnection.getComposingSpanStart(mEditText.getText()));