aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod')
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java2
-rw-r--r--java/src/com/android/inputmethod/latin/CompletionInfoUtils.java43
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java3
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java7
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java77
-rw-r--r--java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java28
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java23
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java4
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java1
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java4
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java16
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java2
13 files changed, 188 insertions, 24 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 562e1d0b7..42f713697 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -422,7 +422,7 @@ public final class BinaryDictionaryFileDumper {
private static void reinitializeClientRecordInDictionaryContentProvider(final Context context,
final ContentProviderClient client, final String clientId) throws RemoteException {
- final String metadataFileUri = context.getString(R.string.dictionary_pack_metadata_uri);
+ final String metadataFileUri = MetadataFileUriGetter.getMetadataUri(context);
if (TextUtils.isEmpty(metadataFileUri)) return;
// Tell the content provider to reset all information about this client id
final Uri metadataContentUri = getProviderUriBuilder(clientId)
diff --git a/java/src/com/android/inputmethod/latin/CompletionInfoUtils.java b/java/src/com/android/inputmethod/latin/CompletionInfoUtils.java
new file mode 100644
index 000000000..792a446c9
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/CompletionInfoUtils.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.text.TextUtils;
+import android.view.inputmethod.CompletionInfo;
+
+import java.util.Arrays;
+
+/**
+ * Utilities to do various stuff with CompletionInfo.
+ */
+public class CompletionInfoUtils {
+ private CompletionInfoUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public static CompletionInfo[] removeNulls(final CompletionInfo[] src) {
+ int j = 0;
+ final CompletionInfo[] dst = new CompletionInfo[src.length];
+ for (int i = 0; i < src.length; ++i) {
+ if (null != src[i] && !TextUtils.isEmpty(src[i].getText())) {
+ dst[j] = src[i];
+ ++j;
+ }
+ }
+ return Arrays.copyOfRange(dst, 0, j);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 8b5a76a17..22d189987 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -173,7 +173,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
// capitalization of i.
final int wordLen = StringUtils.codePointCount(word);
if (wordLen < MAX_WORD_LENGTH && wordLen > 1) {
- super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS);
+ super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS,
+ false /* isNotAWord */);
if (!TextUtils.isEmpty(prevWord)) {
if (mUseFirstLastBigrams) {
super.setBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM);
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index ff3d83fad..9691fa231 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -37,6 +37,8 @@ public abstract class Dictionary {
public static final String TYPE_USER = "user";
// User history dictionary internal to LatinIME.
public static final String TYPE_USER_HISTORY = "history";
+ // Spawned by resuming suggestions. Comes from a span that was in the TextView.
+ public static final String TYPE_RESUMED = "resumed";
protected final String mDictType;
public Dictionary(final String dictType) {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 97dc6a8ac..4b1975a00 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -176,14 +176,15 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
// TODO: Create "cache dictionary" to cache fresh words for frequently updated dictionaries,
// considering performance regression.
- protected void addWord(final String word, final String shortcutTarget, final int frequency) {
+ protected void addWord(final String word, final String shortcutTarget, final int frequency,
+ final boolean isNotAWord) {
if (shortcutTarget == null) {
- mFusionDictionary.add(word, frequency, null, false /* isNotAWord */);
+ mFusionDictionary.add(word, frequency, null, isNotAWord);
} else {
// TODO: Do this in the subclass, with this class taking an arraylist.
final ArrayList<WeightedString> shortcutTargets = CollectionUtils.newArrayList();
shortcutTargets.add(new WeightedString(shortcutTarget, frequency));
- mFusionDictionary.add(word, frequency, shortcutTargets, false /* isNotAWord */);
+ mFusionDictionary.add(word, frequency, shortcutTargets, isNotAWord);
}
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index f08e10763..094ccd77f 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -44,7 +44,9 @@ import android.os.Message;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.InputType;
+import android.text.SpannableString;
import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -72,6 +74,7 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.latin.RichInputConnection.Range;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.Utils.Stats;
import com.android.inputmethod.latin.define.ProductionFlag;
@@ -197,6 +200,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private static final int MSG_PENDING_IMS_CALLBACK = 1;
private static final int MSG_UPDATE_SUGGESTION_STRIP = 2;
private static final int MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 3;
+ private static final int MSG_RESUME_SUGGESTIONS = 4;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
@@ -234,6 +238,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
latinIme.showGesturePreviewAndSuggestionStrip((SuggestedWords)msg.obj,
msg.arg1 == ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT);
break;
+ case MSG_RESUME_SUGGESTIONS:
+ latinIme.restartSuggestionsOnWordTouchedByCursor();
+ break;
}
}
@@ -241,6 +248,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP), mDelayUpdateSuggestions);
}
+ public void postResumeSuggestions() {
+ sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS), mDelayUpdateSuggestions);
+ }
+
public void cancelUpdateSuggestionStrip() {
removeMessages(MSG_UPDATE_SUGGESTION_STRIP);
}
@@ -910,13 +921,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
resetEntireInputState(newSelStart);
}
+ // We moved the cursor. If we are touching a word, we need to resume suggestion.
+ mHandler.postResumeSuggestions();
+
mKeyboardSwitcher.updateShiftState();
}
mExpectingUpdateSelection = false;
- // TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not
- // here. It would probably be too expensive to call directly here but we may want to post a
- // message to delay it. The point would be to unify behavior between backspace to the
- // end of a word and manually put the pointer at the end of the word.
// Make a note of the cursor position
mLastSelectionStart = newSelStart;
@@ -983,7 +993,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
}
if (!mSettings.getCurrent().isApplicationSpecifiedCompletionsOn()) return;
- mApplicationSpecifiedCompletions = applicationSpecifiedCompletions;
+ mApplicationSpecifiedCompletions =
+ CompletionInfoUtils.removeNulls(applicationSpecifiedCompletions);
if (applicationSpecifiedCompletions == null) {
clearSuggestionStrip();
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -1723,6 +1734,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// during key repeat.
mHandler.postUpdateShiftState();
+ if (mWordComposer.isComposingWord() && !mWordComposer.isCursorAtEndOfComposingWord()) {
+ resetEntireInputState(mLastSelectionStart);
+ }
if (mWordComposer.isComposingWord()) {
final int length = mWordComposer.size();
if (length > 0) {
@@ -1854,6 +1868,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
promotePhantomSpace();
}
+ if (mWordComposer.isComposingWord() && !mWordComposer.isCursorAtEndOfComposingWord()) {
+ resetEntireInputState(mLastSelectionStart);
+ isComposingWord = false;
+ }
// NOTE: isCursorTouchingWord() is a blocking IPC call, so it often takes several
// dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
// thread here.
@@ -2327,6 +2345,48 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
/**
+ * Check if the cursor is touching a word. If so, restart suggestions on this word, else
+ * do nothing.
+ */
+ private void restartSuggestionsOnWordTouchedByCursor() {
+ // If the cursor is not touching a word, or if there is a selection, return right away.
+ if (mLastSelectionStart != mLastSelectionEnd) return;
+ if (!mConnection.isCursorTouchingWord(mSettings.getCurrent())) return;
+ final Range range = mConnection.getWordRangeAtCursor(mSettings.getWordSeparators(),
+ 0 /* additionalPrecedingWordsCount */);
+ final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
+ 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)) {
+ SuggestionSpan span = (SuggestionSpan)object;
+ for (String s : span.getSuggestions()) {
+ ++i;
+ if (!TextUtils.equals(s, typedWord)) {
+ suggestions.add(new SuggestedWordInfo(s,
+ SuggestionStripView.MAX_SUGGESTIONS - i,
+ SuggestedWordInfo.KIND_RESUMED, Dictionary.TYPE_RESUMED));
+ }
+ }
+ }
+ }
+ mWordComposer.setComposingWord(range.mWord, mKeyboardSwitcher.getKeyboard());
+ mWordComposer.setCursorPositionWithinWord(range.mCharsBefore);
+ mConnection.setComposingRegion(mLastSelectionStart - range.mCharsBefore,
+ mLastSelectionEnd + range.mCharsAfter);
+ if (suggestions.isEmpty()) {
+ suggestions.add(new SuggestedWordInfo(range.mWord.toString(), 1,
+ SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_RESUMED));
+ }
+ showSuggestionStrip(new SuggestedWords(suggestions,
+ true /* typedWordValid */, false /* willAutoCorrect */,
+ false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
+ false /* isPrediction */), range.mWord.toString());
+ }
+
+ /**
* Check if the cursor is actually at the end of a word. If so, restart suggestions on this
* word, else do nothing.
*/
@@ -2334,17 +2394,18 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final CharSequence word =
mConnection.getWordBeforeCursorIfAtEndOfWord(mSettings.getCurrent());
if (null != word) {
- restartSuggestionsOnWordBeforeCursor(word);
+ final String wordString = word.toString();
+ restartSuggestionsOnWordBeforeCursor(wordString);
// 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(word.toString(),
+ ResearchLogger.getInstance().uncommitCurrentLogUnit(wordString,
true /* dumpCurrentLogUnit */);
}
}
}
- private void restartSuggestionsOnWordBeforeCursor(final CharSequence word) {
+ private void restartSuggestionsOnWordBeforeCursor(final String word) {
mWordComposer.setComposingWord(word, mKeyboardSwitcher.getKeyboard());
final int length = word.length();
mConnection.deleteSurroundingText(length, 0);
diff --git a/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java b/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
new file mode 100644
index 000000000..e6dc6db8f
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import android.content.Context;
+
+/**
+ * Helper class to get the metadata URI.
+ */
+public class MetadataFileUriGetter {
+ public static String getMetadataUri(Context context) {
+ return context.getString(R.string.dictionary_pack_metadata_uri);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 16744d1f0..b74ea593d 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -17,7 +17,9 @@
package com.android.inputmethod.latin;
import android.inputmethodservice.InputMethodService;
+import android.text.SpannableString;
import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.CompletionInfo;
@@ -392,7 +394,9 @@ public final class RichInputConnection {
public void commitCompletion(final CompletionInfo completionInfo) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
- final CharSequence text = completionInfo.getText();
+ CharSequence text = completionInfo.getText();
+ // text should never be null, but just in case, it's better to insert nothing than to crash
+ if (null == text) text = "";
mCommittedTextBeforeComposingText.append(text);
mCurrentCursorPosition += text.length() - mComposingText.length();
mComposingText.setLength(0);
@@ -442,9 +446,9 @@ public final class RichInputConnection {
public final int mCharsAfter;
/** The actual characters that make up a word */
- public final String mWord;
+ public final CharSequence mWord;
- public Range(int charsBefore, int charsAfter, String word) {
+ public Range(int charsBefore, int charsAfter, CharSequence word) {
if (charsBefore < 0 || charsAfter < 0) {
throw new IndexOutOfBoundsException();
}
@@ -498,7 +502,7 @@ public final class RichInputConnection {
* separator. For example, if the field contains "he|llo world", where |
* represents the cursor, then "hello " will be returned.
*/
- public String getWordAtCursor(String separators) {
+ public CharSequence getWordAtCursor(String separators) {
// getWordRangeAtCursor returns null if the connection is null
Range r = getWordRangeAtCursor(separators, 0);
return (r == null) ? null : r.mWord;
@@ -517,8 +521,10 @@ public final class RichInputConnection {
if (mIC == null || sep == null) {
return null;
}
- final CharSequence before = mIC.getTextBeforeCursor(1000, 0);
- final CharSequence after = mIC.getTextAfterCursor(1000, 0);
+ final CharSequence before = mIC.getTextBeforeCursor(1000,
+ InputConnection.GET_TEXT_WITH_STYLES);
+ final CharSequence after = mIC.getTextAfterCursor(1000,
+ InputConnection.GET_TEXT_WITH_STYLES);
if (before == null || after == null) {
return null;
}
@@ -560,8 +566,9 @@ public final class RichInputConnection {
}
}
- final String word = before.toString().substring(startIndexInBefore, before.length())
- + after.toString().substring(0, endIndexInAfter);
+ final SpannableString word = new SpannableString(TextUtils.concat(
+ before.subSequence(startIndexInBefore, before.length()),
+ after.subSequence(0, endIndexInAfter)));
return new Range(before.length() - startIndexInBefore, endIndexInAfter, word);
}
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 8fbe843cf..318d2b23f 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -134,6 +134,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return mSettingsValues.mIsInternal;
}
+ public String getWordSeparators() {
+ return mSettingsValues.mWordSeparators;
+ }
+
// Accessed from the settings interface, hence public
public static boolean readKeypressSoundEnabled(final SharedPreferences prefs,
final Resources res) {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 3d6fe2d22..158cc1155 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -131,6 +131,7 @@ public final class SuggestedWords {
public static final int KIND_APP_DEFINED = 6; // Suggested by the application
public static final int KIND_SHORTCUT = 7; // A shortcut
public static final int KIND_PREDICTION = 8; // A prediction (== a suggestion with no input)
+ public static final int KIND_RESUMED = 9; // A resumed suggestion (comes from a span)
public final String mWord;
public final int mScore;
public final int mKind; // one of the KIND_* constants above
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 8d2e7623f..90f92972a 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -252,10 +252,10 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
final int adjustedFrequency = scaleFrequencyFromDefaultToLatinIme(frequency);
// Safeguard against adding really long words.
if (word.length() < MAX_WORD_LENGTH) {
- super.addWord(word, null, adjustedFrequency);
+ super.addWord(word, null, adjustedFrequency, false /* isNotAWord */);
}
if (null != shortcut && shortcut.length() < MAX_WORD_LENGTH) {
- super.addWord(shortcut, word, adjustedFrequency);
+ super.addWord(shortcut, word, adjustedFrequency, true /* isNotAWord */);
}
cursor.moveToNext();
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index f7cb4346a..1af12428d 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -49,6 +49,7 @@ public final class WordComposer {
private int mCapitalizedMode;
private int mTrailingSingleQuotesCount;
private int mCodePointSize;
+ private int mCursorPositionWithinWord;
/**
* Whether the user chose to capitalize the first char of the word.
@@ -62,6 +63,7 @@ public final class WordComposer {
mTrailingSingleQuotesCount = 0;
mIsResumed = false;
mIsBatchMode = false;
+ mCursorPositionWithinWord = 0;
refreshSize();
}
@@ -76,6 +78,7 @@ public final class WordComposer {
mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount;
mIsResumed = source.mIsResumed;
mIsBatchMode = source.mIsBatchMode;
+ mCursorPositionWithinWord = source.mCursorPositionWithinWord;
refreshSize();
}
@@ -91,6 +94,7 @@ public final class WordComposer {
mTrailingSingleQuotesCount = 0;
mIsResumed = false;
mIsBatchMode = false;
+ mCursorPositionWithinWord = 0;
refreshSize();
}
@@ -135,6 +139,7 @@ public final class WordComposer {
final int newIndex = size();
mTypedWord.appendCodePoint(primaryCode);
refreshSize();
+ mCursorPositionWithinWord = mCodePointSize;
if (newIndex < MAX_WORD_LENGTH) {
mPrimaryKeyCodes[newIndex] = primaryCode >= Constants.CODE_SPACE
? Character.toLowerCase(primaryCode) : primaryCode;
@@ -158,6 +163,14 @@ public final class WordComposer {
mAutoCorrection = null;
}
+ public void setCursorPositionWithinWord(final int posWithinWord) {
+ mCursorPositionWithinWord = posWithinWord;
+ }
+
+ public boolean isCursorAtEndOfComposingWord() {
+ return mCursorPositionWithinWord == mCodePointSize;
+ }
+
public void setBatchInputPointers(final InputPointers batchPointers) {
mInputPointers.set(batchPointers);
mIsBatchMode = true;
@@ -242,6 +255,7 @@ public final class WordComposer {
++mTrailingSingleQuotesCount;
}
}
+ mCursorPositionWithinWord = mCodePointSize;
mAutoCorrection = null;
}
@@ -368,6 +382,7 @@ public final class WordComposer {
mCapitalizedMode = CAPS_MODE_OFF;
refreshSize();
mAutoCorrection = null;
+ mCursorPositionWithinWord = 0;
mIsResumed = false;
return lastComposedWord;
}
@@ -380,6 +395,7 @@ public final class WordComposer {
refreshSize();
mCapitalizedMode = lastComposedWord.mCapitalizedMode;
mAutoCorrection = null; // This will be filled by the next call to updateSuggestion.
+ mCursorPositionWithinWord = mCodePointSize;
mIsResumed = true;
}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index c05de0992..320db8123 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -1283,7 +1283,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
if (connection != null) {
Range range = connection.getWordRangeAtCursor(WHITESPACE_SEPARATORS, 1);
if (range != null) {
- word = range.mWord;
+ word = range.mWord.toString();
}
}
final ResearchLogger researchLogger = getInstance();