aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorJean Chalard <jchalard@google.com>2013-12-20 18:05:35 +0900
committerJean Chalard <jchalard@google.com>2013-12-20 19:09:36 +0900
commit221df9e59aade0860624aeeb9b7b25311584c93a (patch)
tree3f965e750d713d1cc9dc8c42c81ef4edabcac9cc /java
parentec4b6e7bb37d2f1794673dc896c14d6b554c6a0a (diff)
downloadlatinime-221df9e59aade0860624aeeb9b7b25311584c93a.tar.gz
latinime-221df9e59aade0860624aeeb9b7b25311584c93a.tar.xz
latinime-221df9e59aade0860624aeeb9b7b25311584c93a.zip
[IL26] Move restartSuggestionsOnWordTouchedByCursor
Bug: 8636060 Change-Id: I373874585f4fa663b4207b9a02d751805259eb36
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java119
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java124
2 files changed, 132 insertions, 111 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c66fca58c..dd2c80664 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -43,7 +43,6 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.text.TextUtils;
-import android.text.style.SuggestionSpan;
import android.util.Log;
import android.util.Pair;
import android.util.PrintWriterPrinter;
@@ -81,13 +80,11 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripView;
import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CompletionInfoUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
-import com.android.inputmethod.latin.utils.TextRange;
import com.android.inputmethod.research.ResearchLogger;
import java.io.FileDescriptor;
@@ -212,7 +209,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
break;
case MSG_RESUME_SUGGESTIONS:
- latinIme.restartSuggestionsOnWordTouchedByCursor();
+ latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
+ latinIme.mSettings.getCurrent(), latinIme.mKeyboardSwitcher,
+ latinIme.mInputUpdater);
break;
case MSG_REOPEN_DICTIONARIES:
latinIme.initSuggest();
@@ -1367,7 +1366,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
1 /* nthPreviousWord */));
}
- static final class InputUpdater implements Handler.Callback {
+ // TODO[IL]: Make this a package-private standalone class in inputlogic/ and remove all
+ // references to it in LatinIME
+ public static final class InputUpdater implements Handler.Callback {
private final Handler mHandler;
private final LatinIME mLatinIme;
private final Object mLock = new Object();
@@ -1617,7 +1618,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mSettings.getCurrent().mSuggestPuncList == mInputLogic.mSuggestedWords;
}
- private boolean isSuggestionsStripVisible() {
+ // TODO[IL]: Define a clear interface for this
+ public boolean isSuggestionsStripVisible() {
final SettingsValues currentSettings = mSettings.getCurrent();
if (mSuggestionStripView == null)
return false;
@@ -1903,111 +1905,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setSuggestionStripShown(isSuggestionsStripVisible());
}
- private boolean isResumableWord(final String word, final SettingsValues settings) {
- final int firstCodePoint = word.codePointAt(0);
- return settings.isWordCodePoint(firstCodePoint)
- && Constants.CODE_SINGLE_QUOTE != firstCodePoint
- && Constants.CODE_DASH != firstCodePoint;
- }
-
- /**
- * Check if the cursor is touching a word. If so, restart suggestions on this word, else
- * do nothing.
- */
- private void restartSuggestionsOnWordTouchedByCursor() {
- // HACK: We may want to special-case some apps that exhibit bad behavior in case of
- // recorrection. This is a temporary, stopgap measure that will be removed later.
- // TODO: remove this.
- final SettingsValues settingsValues = mSettings.getCurrent();
- if (settingsValues.isBrokenByRecorrection()) return;
- // A simple way to test for support from the TextView.
- if (!isSuggestionsStripVisible()) return;
- // Recorrection is not supported in languages without spaces because we don't know
- // how to segment them yet.
- if (!settingsValues.mCurrentLanguageHasSpaces) return;
- // If the cursor is not touching a word, or if there is a selection, return right away.
- if (mInputLogic.mLastSelectionStart != mInputLogic.mLastSelectionEnd) return;
- // If we don't know the cursor location, return.
- if (mInputLogic.mLastSelectionStart < 0) return;
- final SettingsValues currentSettings = mSettings.getCurrent();
- if (!mInputLogic.mConnection.isCursorTouchingWord(currentSettings)) return;
- final TextRange range = mInputLogic.mConnection.getWordRangeAtCursor(
- currentSettings.mWordSeparators, 0 /* additionalPrecedingWordsCount */);
- if (null == range) return; // Happens if we don't have an input connection at all
- if (range.length() <= 0) return; // Race condition. No text to resume on, so bail out.
- // 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 > mInputLogic.mLastSelectionStart) return;
- final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
- final String typedWord = range.mWord.toString();
- if (!isResumableWord(typedWord, currentSettings)) return;
- int i = 0;
- for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) {
- for (final String s : span.getSuggestions()) {
- ++i;
- if (!TextUtils.equals(s, typedWord)) {
- suggestions.add(new SuggestedWordInfo(s,
- SuggestionStripView.MAX_SUGGESTIONS - i,
- SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED,
- SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
- SuggestedWordInfo.NOT_A_CONFIDENCE
- /* autoCommitFirstWordConfidence */));
- }
- }
- }
- mInputLogic.mWordComposer.setComposingWord(typedWord,
- mInputLogic.getNthPreviousWordForSuggestion(currentSettings,
- // We want the previous word for suggestion. If we have chars in the word
- // before the cursor, then we want the word before that, hence 2; otherwise,
- // we want the word immediately before the cursor, hence 1.
- 0 == numberOfCharsInWordBeforeCursor ? 1 : 2),
- mKeyboardSwitcher.getKeyboard());
- mInputLogic.mWordComposer.setCursorPositionWithinWord(
- typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor));
- mInputLogic.mConnection.setComposingRegion(
- mInputLogic.mLastSelectionStart - numberOfCharsInWordBeforeCursor,
- mInputLogic.mLastSelectionEnd + 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.
- mInputUpdater.getSuggestedWords(Suggest.SESSION_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 #getSuggestedWordsExcludingTypedWord() method sets
- // willAutoCorrect to false.
- suggestedWords = suggestedWordsIncludingTypedWord
- .getSuggestedWordsExcludingTypedWord();
- } 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;
- }
- // We need to pass typedWord because mWordComposer.mTypedWord may
- // differ from typedWord.
- unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(
- suggestedWords, typedWord);
- }});
- } else {
- // We found suggestion spans in the word. We'll create the SuggestedWords out of
- // them, and make willAutoCorrect false.
- final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
- true /* typedWordValid */, false /* willAutoCorrect */,
- false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
- false /* isPrediction */);
- // We need to pass typedWord because mWordComposer.mTypedWord may differ from typedWord.
- unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords, typedWord);
- }
- }
-
public void unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(
final SuggestedWords suggestedWords, final String typedWord) {
// Note that it's very important here that suggestedWords.mWillAutoCorrect is false.
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 27b7b98d8..5f3297794 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.inputlogic;
import android.os.SystemClock;
import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -30,6 +31,7 @@ import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.LastComposedWord;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
@@ -38,11 +40,13 @@ import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues;
+import com.android.inputmethod.latin.suggestions.SuggestionStripView;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -50,8 +54,10 @@ import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.StringUtils;
+import com.android.inputmethod.latin.utils.TextRange;
import com.android.inputmethod.research.ResearchLogger;
+import java.util.ArrayList;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
@@ -954,6 +960,107 @@ public final class InputLogic {
}
/**
+ * 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.
+ */
+ // TODO: make this private.
+ public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
+ // TODO: Remove these argument.
+ final KeyboardSwitcher keyboardSwitcher, final LatinIME.InputUpdater inputUpdater) {
+ // HACK: We may want to special-case some apps that exhibit bad behavior in case of
+ // recorrection. This is a temporary, stopgap measure that will be removed later.
+ // TODO: remove this.
+ if (settingsValues.isBrokenByRecorrection()) return;
+ // A simple way to test for support from the TextView.
+ if (!mLatinIME.isSuggestionsStripVisible()) return;
+ // Recorrection is not supported in languages without spaces because we don't know
+ // how to segment them yet.
+ if (!settingsValues.mCurrentLanguageHasSpaces) return;
+ // If the cursor is not touching a word, or if there is a selection, return right away.
+ if (mLastSelectionStart != mLastSelectionEnd) return;
+ // If we don't know the cursor location, return.
+ if (mLastSelectionStart < 0) return;
+ if (!mConnection.isCursorTouchingWord(settingsValues)) return;
+ final TextRange range = mConnection.getWordRangeAtCursor(
+ settingsValues.mWordSeparators, 0 /* additionalPrecedingWordsCount */);
+ if (null == range) return; // Happens if we don't have an input connection at all
+ if (range.length() <= 0) return; // Race condition. No text to resume on, so bail out.
+ // 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;
+ final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
+ final String typedWord = range.mWord.toString();
+ if (!isResumableWord(settingsValues, typedWord)) return;
+ int i = 0;
+ for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) {
+ for (final String s : span.getSuggestions()) {
+ ++i;
+ if (!TextUtils.equals(s, typedWord)) {
+ suggestions.add(new SuggestedWordInfo(s,
+ SuggestionStripView.MAX_SUGGESTIONS - i,
+ SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE
+ /* autoCommitFirstWordConfidence */));
+ }
+ }
+ }
+ mWordComposer.setComposingWord(typedWord,
+ getNthPreviousWordForSuggestion(settingsValues,
+ // We want the previous word for suggestion. If we have chars in the word
+ // before the cursor, then we want the word before that, hence 2; otherwise,
+ // we want the word immediately before the cursor, hence 1.
+ 0 == numberOfCharsInWordBeforeCursor ? 1 : 2),
+ keyboardSwitcher.getKeyboard());
+ mWordComposer.setCursorPositionWithinWord(
+ typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor));
+ mConnection.setComposingRegion(mLastSelectionStart - numberOfCharsInWordBeforeCursor,
+ mLastSelectionEnd + 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.
+ inputUpdater.getSuggestedWords(Suggest.SESSION_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 #getSuggestedWordsExcludingTypedWord() method sets
+ // willAutoCorrect to false.
+ suggestedWords = suggestedWordsIncludingTypedWord
+ .getSuggestedWordsExcludingTypedWord();
+ } 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;
+ }
+ // We need to pass typedWord because mWordComposer.mTypedWord may
+ // differ from typedWord.
+ mLatinIME.unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(
+ suggestedWords, typedWord);
+ }});
+ } else {
+ // We found suggestion spans in the word. We'll create the SuggestedWords out of
+ // them, and make willAutoCorrect false.
+ final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
+ true /* typedWordValid */, false /* willAutoCorrect */,
+ false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
+ false /* isPrediction */);
+ // We need to pass typedWord because mWordComposer.mTypedWord may differ from typedWord.
+ mLatinIME.unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords,
+ typedWord);
+ }
+ }
+
+ /**
* Reverts a previous commit with auto-correction.
*
* This is triggered upon pressing backspace just after a commit with auto-correction.
@@ -1101,6 +1208,23 @@ public final class InputLogic {
}
/**
+ * Tests the passed word for resumability.
+ *
+ * We can resume suggestions on words whose first code point is a word code point (with some
+ * nuances: check the code for details).
+ *
+ * @param settings the current values of the settings.
+ * @param word the word to evaluate.
+ * @return whether it's fine to resume suggestions on this word.
+ */
+ private static boolean isResumableWord(final SettingsValues settings, final String word) {
+ final int firstCodePoint = word.codePointAt(0);
+ return settings.isWordCodePoint(firstCodePoint)
+ && Constants.CODE_SINGLE_QUOTE != firstCodePoint
+ && Constants.CODE_DASH != firstCodePoint;
+ }
+
+ /**
* @param actionId the action to perform
*/
private void performEditorAction(final int actionId) {