aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorJean Chalard <jchalard@google.com>2013-04-10 18:30:11 +0900
committerJean Chalard <jchalard@google.com>2013-04-15 19:33:23 +0900
commit0e9ee4d3bf75459560670ca5c28ff4c4f7c346fb (patch)
tree34a080015b3e3df7df78c809b7f957aeb0244ca3 /java
parent059e084e983ce4a1440dc065f5167d278d8939e7 (diff)
downloadlatinime-0e9ee4d3bf75459560670ca5c28ff4c4f7c346fb.tar.gz
latinime-0e9ee4d3bf75459560670ca5c28ff4c4f7c346fb.tar.xz
latinime-0e9ee4d3bf75459560670ca5c28ff4c4f7c346fb.zip
If there are no suggestion span, recompute suggestions.
Bug: 8084810 Change-Id: I1743c09c43ca6835bb2f607684b037bf17d36335
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java71
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java17
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java16
3 files changed, 88 insertions, 16 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 47d51c586..da1232f5e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1466,7 +1466,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
"", mWordComposer.getTypedWord(), " ", mWordComposer);
}
}
- commitTyped(LastComposedWord.NOT_A_SEPARATOR);
+ if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
+ // If we are in the middle of a recorrection, we need to commit the recorrection
+ // first so that we can insert the character at the current cursor position.
+ resetEntireInputState(mLastSelectionStart);
+ } else {
+ commitTyped(LastComposedWord.NOT_A_SEPARATOR);
+ }
}
final int keyX, keyY;
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
@@ -1522,8 +1528,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
final int wordComposerSize = mWordComposer.size();
// Since isComposingWord() is true, the size is at least 1.
- final int lastChar = mWordComposer.getCodeAt(wordComposerSize - 1);
- if (wordComposerSize <= 1) {
+ final int lastChar = mWordComposer.getCodeBeforeCursor();
+ if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
+ // If we are in the middle of a recorrection, we need to commit the recorrection
+ // first so that we can insert the batch input at the current cursor position.
+ resetEntireInputState(mLastSelectionStart);
+ } else if (wordComposerSize <= 1) {
// We auto-correct the previous (typed, not gestured) string iff it's one character
// long. The reason for this is, even in the middle of gesture typing, you'll still
// tap one-letter words and you want them auto-corrected (typically, "i" in English
@@ -1734,8 +1744,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// during key repeat.
mHandler.postUpdateShiftState();
- if (mWordComposer.isComposingWord() && !mWordComposer.isCursorAtEndOfComposingWord()) {
+ if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
+ // If we are in the middle of a recorrection, we need to commit the recorrection
+ // first so that we can remove the character at the current cursor position.
resetEntireInputState(mLastSelectionStart);
+ // When we exit this if-clause, mWordComposer.isComposingWord() will return false.
}
if (mWordComposer.isComposingWord()) {
final int length = mWordComposer.size();
@@ -1870,7 +1883,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
promotePhantomSpace();
}
- if (mWordComposer.isComposingWord() && !mWordComposer.isCursorAtEndOfComposingWord()) {
+ if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
+ // If we are in the middle of a recorrection, we need to commit the recorrection
+ // first so that we can insert the character at the current cursor position.
resetEntireInputState(mLastSelectionStart);
isComposingWord = false;
}
@@ -1935,7 +1950,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
ResearchLogger.latinIME_handleSeparator(primaryCode, mWordComposer.isComposingWord());
}
boolean didAutoCorrect = false;
- // Handle separator
+ if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
+ // If we are in the middle of a recorrection, we need to commit the recorrection
+ // first so that we can insert the separator at the current cursor position.
+ resetEntireInputState(mLastSelectionStart);
+ }
if (mWordComposer.isComposingWord()) {
if (mSettings.getCurrent().mCorrectionEnabled) {
// TODO: maybe cache Strings in an <String> sparse array or something
@@ -2357,9 +2376,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final Range range = mConnection.getWordRangeAtCursor(mSettings.getWordSeparators(),
0 /* additionalPrecedingWordsCount */);
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
+ final String typedWord = range.mWord.toString();
if (range.mWord instanceof SpannableString) {
final SpannableString spannableString = (SpannableString)range.mWord;
- final String typedWord = spannableString.toString();
int i = 0;
for (Object object : spannableString.getSpans(0, spannableString.length(),
SuggestionSpan.class)) {
@@ -2374,18 +2393,42 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
}
}
- mWordComposer.setComposingWord(range.mWord, mKeyboardSwitcher.getKeyboard());
+ mWordComposer.setComposingWord(typedWord, mKeyboardSwitcher.getKeyboard());
mWordComposer.setCursorPositionWithinWord(range.mCharsBefore);
mConnection.setComposingRegion(mLastSelectionStart - range.mCharsBefore,
mLastSelectionEnd + range.mCharsAfter);
+ final SuggestedWords suggestedWords;
if (suggestions.isEmpty()) {
- suggestions.add(new SuggestedWordInfo(range.mWord.toString(), 1,
- SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_RESUMED));
+ // We come here if there weren't any suggestion spans on this word. We will try to
+ // compute suggestions for it instead.
+ final SuggestedWords suggestedWordsIncludingTypedWord =
+ getSuggestedWords(Suggest.SESSION_TYPING);
+ 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;
+ }
+ } else {
+ // We found suggestion spans in the word. We'll create the SuggestedWords out of
+ // them, and make willAutoCorrect false.
+ suggestedWords = new SuggestedWords(suggestions,
+ true /* typedWordValid */, false /* willAutoCorrect */,
+ false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
+ false /* isPrediction */);
}
- showSuggestionStrip(new SuggestedWords(suggestions,
- true /* typedWordValid */, false /* willAutoCorrect */,
- false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
- false /* isPrediction */), range.mWord.toString());
+
+ // Note that it's very important here that suggestedWords.mWillAutoCorrect is false.
+ // We never want to auto-correct on a resumed suggestion. Please refer to the three
+ // places above where suggestedWords is affected.
+ showSuggestionStrip(suggestedWords, typedWord);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 158cc1155..616e1911b 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -195,4 +195,21 @@ public final class SuggestedWords {
}
}
}
+
+ // 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.
+ public SuggestedWords getSuggestedWordsExcludingTypedWord() {
+ final ArrayList<SuggestedWordInfo> newSuggestions = CollectionUtils.newArrayList();
+ for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
+ final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
+ if (SuggestedWordInfo.KIND_TYPED != info.mKind) {
+ newSuggestions.add(info);
+ }
+ }
+ // 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, true /* typedWordValid */,
+ false /* willAutoCorrect */, mIsPunctuationSuggestions, mIsObsoleteSuggestions,
+ mIsPrediction);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 098e8ac7b..51bd901fb 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
*/
public final class WordComposer {
private static final int MAX_WORD_LENGTH = Constants.Dictionary.MAX_WORD_LENGTH;
+ private static final boolean DBG = LatinImeLogger.sDBG;
public static final int CAPS_MODE_OFF = 0;
// 1 is shift bit, 2 is caps bit, 4 is auto bit but this is just a convention as these bits
@@ -132,6 +133,13 @@ public final class WordComposer {
return mPrimaryKeyCodes[index];
}
+ public int getCodeBeforeCursor() {
+ if (mCursorPositionWithinWord < 1 || mCursorPositionWithinWord > mPrimaryKeyCodes.length) {
+ return Constants.NOT_A_CODE;
+ }
+ return mPrimaryKeyCodes[mCursorPositionWithinWord - 1];
+ }
+
public InputPointers getInputPointers() {
return mInputPointers;
}
@@ -177,8 +185,12 @@ public final class WordComposer {
mCursorPositionWithinWord = posWithinWord;
}
- public boolean isCursorAtEndOfComposingWord() {
- return mCursorPositionWithinWord == mCodePointSize;
+ public boolean isCursorFrontOrMiddleOfComposingWord() {
+ if (DBG && mCursorPositionWithinWord > mCodePointSize) {
+ throw new RuntimeException("Wrong cursor position : " + mCursorPositionWithinWord
+ + "in a word of size " + mCodePointSize);
+ }
+ return mCursorPositionWithinWord != mCodePointSize;
}
public void setBatchInputPointers(final InputPointers batchPointers) {