diff options
author | 2012-07-04 15:38:14 +0900 | |
---|---|---|
committer | 2012-07-04 15:38:21 +0900 | |
commit | c68b37964b083015967ce290991ad69d29a4055d (patch) | |
tree | 909bddc0f0c699b6344015e7ff67e31c0a1f4eff /java/src/com/android/inputmethod/latin/WordComposer.java | |
parent | 1e094ac19b99c47f0b8a5108e20949ac91cfa03e (diff) | |
parent | 30a324a58dbe1e2dc47d83c1bcc0af262ab0d542 (diff) | |
download | latinime-c68b37964b083015967ce290991ad69d29a4055d.tar.gz latinime-c68b37964b083015967ce290991ad69d29a4055d.tar.xz latinime-c68b37964b083015967ce290991ad69d29a4055d.zip |
Merge remote-tracking branch 'goog/master' into mergescript
Conflicts:
CleanSpec.mk
java/Android.mk
java/res/drawable-large-hdpi/btn_keyboard_key_popup_selected_holo.9.png
java/res/drawable-large-hdpi/hint_popup_holo.9.png
java/res/drawable-large-hdpi/sym_keyboard_numsymbol_holo.png
java/res/drawable-large-hdpi/sym_keyboard_tab_holo.png
java/res/drawable-large-land-hdpi/hint_popup_holo.9.png
java/res/drawable-large-land-mdpi/hint_popup_holo.9.png
java/res/drawable-large-land-xhdpi/hint_popup_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_dark_normal_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_light_normal_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_light_pressed_holo.9.png
java/res/drawable-large-mdpi/btn_keyboard_key_popup_selected_holo.9.png
java/res/drawable-large-mdpi/hint_popup_holo.9.png
java/res/drawable-large-mdpi/keyboard_background_holo.9.png
java/res/drawable-large-mdpi/keyboard_popup_panel_background_holo.9.png
java/res/drawable-large-mdpi/keyboard_suggest_strip_holo.9.png
java/res/drawable-large-mdpi/sym_keyboard_delete_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num0_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num1_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num2_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num3_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num4_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num5_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num6_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num7_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num8_holo.png
java/res/drawable-large-mdpi/sym_keyboard_num9_holo.png
java/res/drawable-large-mdpi/sym_keyboard_numbpound_holo.png
java/res/drawable-large-mdpi/sym_keyboard_numbstar_holo.png
java/res/drawable-large-mdpi/sym_keyboard_numsymbol_holo.png
java/res/drawable-large-mdpi/sym_keyboard_return_holo.png
java/res/drawable-large-mdpi/sym_keyboard_settings_holo.png
java/res/drawable-large-mdpi/sym_keyboard_shift_holo.png
java/res/drawable-large-mdpi/sym_keyboard_shift_locked_holo.png
java/res/drawable-large-mdpi/sym_keyboard_space_holo.png
java/res/drawable-large-mdpi/sym_keyboard_tab_holo.png
java/res/drawable-large-mdpi/sym_keyboard_voice_holo.png
java/res/drawable-large-mdpi/sym_keyboard_voice_off_holo.png
java/res/drawable-large-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
java/res/drawable-large-xhdpi/hint_popup_holo.9.png
java/res/drawable-large-xhdpi/sym_keyboard_numsymbol_holo.png
java/res/drawable-large-xhdpi/sym_keyboard_tab_holo.png
java/res/drawable-xlarge-hdpi/btn_keyboard_key_popup_selected_holo.9.png
java/res/drawable-xlarge-hdpi/hint_popup_holo.9.png
java/res/drawable-xlarge-land-hdpi/hint_popup_holo.9.png
java/res/drawable-xlarge-land-mdpi/hint_popup_holo.9.png
java/res/drawable-xlarge-land-xhdpi/hint_popup_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_dark_normal_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_light_normal_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_light_pressed_holo.9.png
java/res/drawable-xlarge-mdpi/btn_keyboard_key_popup_selected_holo.9.png
java/res/drawable-xlarge-mdpi/hint_popup_holo.9.png
java/res/drawable-xlarge-mdpi/keyboard_background_holo.9.png
java/res/drawable-xlarge-mdpi/keyboard_popup_panel_background_holo.9.png
java/res/drawable-xlarge-mdpi/keyboard_suggest_strip_holo.9.png
java/res/drawable-xlarge-mdpi/sym_keyboard_delete_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num0_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num1_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num2_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num3_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num4_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num5_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num6_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num7_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num8_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_num9_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_numbpound_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_numbstar_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_return_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_settings_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_shift_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_shift_locked_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_space_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_voice_holo.png
java/res/drawable-xlarge-mdpi/sym_keyboard_voice_off_holo.png
java/res/drawable-xlarge-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
java/res/drawable-xlarge-xhdpi/hint_popup_holo.9.png
java/res/layout-xlarge/recognition_status.xml
java/res/values-af/strings.xml
java/res/values-am/strings.xml
java/res/values-ar/strings.xml
java/res/values-be/strings.xml
java/res/values-bg/strings.xml
java/res/values-ca/strings.xml
java/res/values-cs/strings.xml
java/res/values-da/strings.xml
java/res/values-de/strings.xml
java/res/values-el/strings.xml
java/res/values-en-rGB/strings.xml
java/res/values-es-rUS/strings.xml
java/res/values-es/strings.xml
java/res/values-et/strings.xml
java/res/values-fa/strings.xml
java/res/values-fi/strings.xml
java/res/values-fr/strings.xml
java/res/values-hi/strings.xml
java/res/values-hr/strings.xml
java/res/values-hu/strings.xml
java/res/values-in/strings.xml
java/res/values-it/strings.xml
java/res/values-iw/strings.xml
java/res/values-ja/strings.xml
java/res/values-ko/strings.xml
java/res/values-large/donottranslate.xml
java/res/values-lt/strings.xml
java/res/values-lv/strings.xml
java/res/values-ms/strings.xml
java/res/values-nb/strings.xml
java/res/values-nl/strings.xml
java/res/values-pl/strings.xml
java/res/values-pt-rPT/strings.xml
java/res/values-pt/strings.xml
java/res/values-rm/strings.xml
java/res/values-ro/strings.xml
java/res/values-ru/strings.xml
java/res/values-sk/strings.xml
java/res/values-sl/strings.xml
java/res/values-sr/strings.xml
java/res/values-sv/strings.xml
java/res/values-sw/strings.xml
java/res/values-sw600dp/donottranslate.xml
java/res/values-sw768dp/donottranslate.xml
java/res/values-th/strings.xml
java/res/values-tl/strings.xml
java/res/values-tr/strings.xml
java/res/values-uk/strings.xml
java/res/values-vi/strings.xml
java/res/values-xlarge/donottranslate.xml
java/res/values-zh-rCN/strings.xml
java/res/values-zh-rTW/strings.xml
java/res/values-zu/strings.xml
java/res/values/keypress-vibration-durations.xml
java/res/values/predefined-subtypes.xml
java/res/xml-large-land/kbd_popup_template.xml
java/res/xml-large/kbd_key_styles.xml
java/res/xml-large/kbd_popup_template.xml
java/res/xml-large/kbd_qwerty_f2.xml
java/res/xml-large/kbd_qwerty_row1.xml
java/res/xml-large/kbd_qwerty_row2.xml
java/res/xml-large/kbd_qwerty_row3.xml
java/res/xml-large/kbd_qwerty_row4.xml
java/res/xml-large/kbd_row3_right.xml
java/res/xml-large/kbd_rows_arabic.xml
java/res/xml-large/kbd_rows_azerty.xml
java/res/xml-large/kbd_rows_hebrew.xml
java/res/xml-large/kbd_rows_qwerty.xml
java/res/xml-large/kbd_rows_qwertz.xml
java/res/xml-large/kbd_rows_russian.xml
java/res/xml-large/kbd_rows_scandinavian.xml
java/res/xml-large/kbd_rows_serbian.xml
java/res/xml-large/kbd_rows_spanish.xml
java/res/xml-large/kbd_symbols.xml
java/res/xml-large/kbd_symbols_shift.xml
java/res/xml-sw600dp-land/kbd_more_keys_keyboard_template.xml
java/res/xml-sw600dp-land/kbd_popup_template.xml
java/res/xml-sw600dp/kbd_more_keys_keyboard_template.xml
java/res/xml-sw600dp/kbd_popup_template.xml
java/res/xml-sw600dp/kbd_row3_right.xml
java/res/xml-sw600dp/kbd_rows_qwerty.xml
java/res/xml-sw600dp/keys_comma_period.xml
java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml
java/res/xml-sw768dp-land/kbd_popup_template.xml
java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml
java/res/xml-sw768dp/kbd_popup_template.xml
java/res/xml-sw768dp/kbd_row3_right2.xml
java/res/xml-sw768dp/kbd_rows_qwerty.xml
java/res/xml-sw768dp/row_symbols_shift4.xml
java/res/xml-xlarge-land/kbd_popup_template.xml
java/res/xml-xlarge/kbd_key_styles.xml
java/res/xml-xlarge/kbd_popup_template.xml
java/res/xml-xlarge/kbd_qwerty_row1.xml
java/res/xml-xlarge/kbd_qwerty_row2.xml
java/res/xml-xlarge/kbd_qwerty_row3.xml
java/res/xml-xlarge/kbd_qwerty_row4.xml
java/res/xml-xlarge/kbd_row3_right2.xml
java/res/xml-xlarge/kbd_rows_arabic.xml
java/res/xml-xlarge/kbd_rows_azerty.xml
java/res/xml-xlarge/kbd_rows_hebrew.xml
java/res/xml-xlarge/kbd_rows_qwerty.xml
java/res/xml-xlarge/kbd_rows_qwertz.xml
java/res/xml-xlarge/kbd_rows_russian.xml
java/res/xml-xlarge/kbd_rows_scandinavian.xml
java/res/xml-xlarge/kbd_rows_serbian.xml
java/res/xml-xlarge/kbd_rows_spanish.xml
java/res/xml-xlarge/kbd_symbols.xml
java/res/xml-xlarge/kbd_symbols_shift.xml
java/res/xml/key_azerty_quote.xml
java/res/xml/key_f1.xml
java/res/xml/method.xml
java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java
java/src/com/android/inputmethod/latin/Utils.java
native/Android.mk
Change-Id: I96e8e042f636ed8e5cc023cf8514f13121e39195
Diffstat (limited to 'java/src/com/android/inputmethod/latin/WordComposer.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/WordComposer.java | 308 |
1 files changed, 210 insertions, 98 deletions
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index af5e4b179..ca9caa1d3 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2008 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 @@ -16,9 +16,12 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.KeyDetector; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardActionListener; -import java.util.ArrayList; +import java.util.Arrays; /** * A place to store the currently composing word with information such as adjacent key codes as well @@ -28,38 +31,35 @@ public class WordComposer { public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; public static final int NOT_A_COORDINATE = -1; - /** - * The list of unicode values for each keystroke (including surrounding keys) - */ - private ArrayList<int[]> mCodes; + private static final int N = BinaryDictionary.MAX_WORD_LENGTH; - private int mTypedLength; + private int[] mPrimaryKeyCodes; private int[] mXCoordinates; private int[] mYCoordinates; - - /** - * The word chosen from the candidate list, until it is committed. - */ - private String mPreferredWord; - private StringBuilder mTypedWord; + private CharSequence mAutoCorrection; + private boolean mIsResumed; + // Cache these values for performance private int mCapsCount; - private boolean mAutoCapitalized; - + private int mTrailingSingleQuotesCount; + private int mCodePointSize; + /** * Whether the user chose to capitalize the first char of the word. */ private boolean mIsFirstCharCapitalized; public WordComposer() { - final int N = BinaryDictionary.MAX_WORD_LENGTH; - mCodes = new ArrayList<int[]>(N); + mPrimaryKeyCodes = new int[N]; mTypedWord = new StringBuilder(N); - mTypedLength = 0; mXCoordinates = new int[N]; mYCoordinates = new int[N]; + mAutoCorrection = null; + mTrailingSingleQuotesCount = 0; + mIsResumed = false; + refreshSize(); } public WordComposer(WordComposer source) { @@ -67,44 +67,53 @@ public class WordComposer { } public void init(WordComposer source) { - mCodes = new ArrayList<int[]>(source.mCodes); - mPreferredWord = source.mPreferredWord; + mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length); mTypedWord = new StringBuilder(source.mTypedWord); + mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length); + mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length); mCapsCount = source.mCapsCount; - mAutoCapitalized = source.mAutoCapitalized; mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; - mTypedLength = source.mTypedLength; - mXCoordinates = source.mXCoordinates; - mYCoordinates = source.mYCoordinates; + mAutoCapitalized = source.mAutoCapitalized; + mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; + mIsResumed = source.mIsResumed; + refreshSize(); } /** * Clear out the keys registered so far. */ public void reset() { - mCodes.clear(); - mTypedLength = 0; - mIsFirstCharCapitalized = false; - mPreferredWord = null; mTypedWord.setLength(0); + mAutoCorrection = null; mCapsCount = 0; + mIsFirstCharCapitalized = false; + mTrailingSingleQuotesCount = 0; + mIsResumed = false; + refreshSize(); + } + + public final void refreshSize() { + mCodePointSize = mTypedWord.codePointCount(0, mTypedWord.length()); } /** * Number of keystrokes in the composing word. * @return the number of keystrokes */ - public int size() { - return mCodes.size(); + public final int size() { + return mCodePointSize; } - /** - * Returns the codes at a particular position in the word. - * @param index the position in the word - * @return the unicode for the pressed and surrounding keys - */ - public int[] getCodesAt(int index) { - return mCodes.get(index); + public final boolean isComposingWord() { + return size() > 0; + } + + // TODO: make sure that the index should not exceed MAX_WORD_LENGTH + public int getCodeAt(int index) { + if (index >= BinaryDictionary.MAX_WORD_LENGTH) { + return -1; + } + return mPrimaryKeyCodes[index]; } public int[] getXCoordinates() { @@ -115,71 +124,128 @@ public class WordComposer { return mYCoordinates; } + private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { + if (index == 0) return Character.isUpperCase(codePoint); + return previous && !Character.isUpperCase(codePoint); + } + + // TODO: remove input keyDetector + public void add(int primaryCode, int x, int y, KeyDetector keyDetector) { + final int keyX; + final int keyY; + if (null == keyDetector + || x == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE + || y == KeyboardActionListener.SUGGESTION_STRIP_COORDINATE + || x == KeyboardActionListener.NOT_A_TOUCH_COORDINATE + || y == KeyboardActionListener.NOT_A_TOUCH_COORDINATE) { + keyX = x; + keyY = y; + } else { + keyX = keyDetector.getTouchX(x); + keyY = keyDetector.getTouchY(y); + } + add(primaryCode, keyX, keyY); + } + /** - * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of - * the array containing unicode for adjacent keys, sorted by reducing probability/proximity. - * @param codes the array of unicode values + * Add a new keystroke, with the pressed key's code point with the touch point coordinates. */ - public void add(int primaryCode, int[] codes, int x, int y) { - mTypedWord.append((char) primaryCode); - correctPrimaryJuxtapos(primaryCode, codes); - mCodes.add(codes); - if (mTypedLength < BinaryDictionary.MAX_WORD_LENGTH) { - mXCoordinates[mTypedLength] = x; - mYCoordinates[mTypedLength] = y; + private void add(int primaryCode, int keyX, int keyY) { + final int newIndex = size(); + mTypedWord.appendCodePoint(primaryCode); + refreshSize(); + if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { + mPrimaryKeyCodes[newIndex] = primaryCode >= Keyboard.CODE_SPACE + ? Character.toLowerCase(primaryCode) : primaryCode; + mXCoordinates[newIndex] = keyX; + mYCoordinates[newIndex] = keyY; } - ++mTypedLength; - if (Character.isUpperCase((char) primaryCode)) mCapsCount++; + mIsFirstCharCapitalized = isFirstCharCapitalized( + newIndex, primaryCode, mIsFirstCharCapitalized); + if (Character.isUpperCase(primaryCode)) mCapsCount++; + if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) { + ++mTrailingSingleQuotesCount; + } else { + mTrailingSingleQuotesCount = 0; + } + mAutoCorrection = null; + } + + /** + * Internal method to retrieve reasonable proximity info for a character. + */ + private void addKeyInfo(final int codePoint, final Keyboard keyboard) { + for (final Key key : keyboard.mKeys) { + if (key.mCode == codePoint) { + final int x = key.mX + key.mWidth / 2; + final int y = key.mY + key.mHeight / 2; + add(codePoint, x, y); + return; + } + } + add(codePoint, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); } /** - * Swaps the first and second values in the codes array if the primary code is not the first - * value in the array but the second. This happens when the preferred key is not the key that - * the user released the finger on. - * @param primaryCode the preferred character - * @param codes array of codes based on distance from touch point + * Set the currently composing word to the one passed as an argument. + * This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity. */ - private void correctPrimaryJuxtapos(int primaryCode, int[] codes) { - if (codes.length < 2) return; - if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) { - codes[1] = codes[0]; - codes[0] = primaryCode; + public void setComposingWord(final CharSequence word, final Keyboard keyboard) { + reset(); + final int length = word.length(); + for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) { + int codePoint = Character.codePointAt(word, i); + addKeyInfo(codePoint, keyboard); } + mIsResumed = true; } /** * Delete the last keystroke as a result of hitting backspace. */ public void deleteLast() { - final int codesSize = mCodes.size(); - if (codesSize > 0) { - mCodes.remove(codesSize - 1); - final int lastPos = mTypedWord.length() - 1; - char last = mTypedWord.charAt(lastPos); - mTypedWord.deleteCharAt(lastPos); - if (Character.isUpperCase(last)) mCapsCount--; + final int size = size(); + if (size > 0) { + // Note: mTypedWord.length() and mCodes.length differ when there are surrogate pairs + final int stringBuilderLength = mTypedWord.length(); + if (stringBuilderLength < size) { + throw new RuntimeException( + "In WordComposer: mCodes and mTypedWords have non-matching lengths"); + } + final int lastChar = mTypedWord.codePointBefore(stringBuilderLength); + if (Character.isSupplementaryCodePoint(lastChar)) { + mTypedWord.delete(stringBuilderLength - 2, stringBuilderLength); + } else { + mTypedWord.deleteCharAt(stringBuilderLength - 1); + } + if (Character.isUpperCase(lastChar)) mCapsCount--; + refreshSize(); } - if (mTypedLength > 0) { - --mTypedLength; + // We may have deleted the last one. + if (0 == size()) { + mIsFirstCharCapitalized = false; } + if (mTrailingSingleQuotesCount > 0) { + --mTrailingSingleQuotesCount; + } else { + int i = mTypedWord.length(); + while (i > 0) { + i = mTypedWord.offsetByCodePoints(i, -1); + if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break; + ++mTrailingSingleQuotesCount; + } + } + mAutoCorrection = null; } /** * Returns the word as it was typed, without any correction applied. - * @return the word that was typed so far + * @return the word that was typed so far. Never returns null. */ - public CharSequence getTypedWord() { - int wordSize = mCodes.size(); - if (wordSize == 0) { - return null; - } - return mTypedWord; + public String getTypedWord() { + return mTypedWord.toString(); } - public void setFirstCharCapitalized(boolean capitalized) { - mIsFirstCharCapitalized = capitalized; - } - /** * Whether or not the user typed a capital letter as the first letter in the word * @return capitalization preference @@ -188,6 +254,10 @@ public class WordComposer { return mIsFirstCharCapitalized; } + public int trailingSingleQuotesCount() { + return mTrailingSingleQuotesCount; + } + /** * Whether or not all of the user typed chars are upper case * @return true if all user typed chars are upper case, false otherwise @@ -197,29 +267,13 @@ public class WordComposer { } /** - * Stores the user's selected word, before it is actually committed to the text field. - * @param preferred - */ - public void setPreferredWord(String preferred) { - mPreferredWord = preferred; - } - - /** - * Return the word chosen by the user, or the typed word if no other word was chosen. - * @return the preferred word - */ - public CharSequence getPreferredWord() { - return mPreferredWord != null ? mPreferredWord : getTypedWord(); - } - - /** * Returns true if more than one character is upper case, otherwise returns false. */ public boolean isMostlyCaps() { return mCapsCount > 1; } - /** + /** * Saves the reason why the word is capitalized - whether it was automatic or * due to the user hitting shift in the middle of a sentence. * @param auto whether it was an automatic capitalization due to start of sentence @@ -235,4 +289,62 @@ public class WordComposer { public boolean isAutoCapitalized() { return mAutoCapitalized; } + + /** + * Sets the auto-correction for this word. + */ + public void setAutoCorrection(final CharSequence correction) { + mAutoCorrection = correction; + } + + /** + * @return the auto-correction for this word, or null if none. + */ + public CharSequence getAutoCorrectionOrNull() { + return mAutoCorrection; + } + + /** + * @return whether we started composing this word by resuming suggestion on an existing string + */ + public boolean isResumed() { + return mIsResumed; + } + + // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. + public LastComposedWord commitWord(final int type, final String committedWord, + final int separatorCode, final CharSequence prevWord) { + // Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK + // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate + // the last composed word to ensure this does not happen. + final int[] primaryKeyCodes = mPrimaryKeyCodes; + final int[] xCoordinates = mXCoordinates; + final int[] yCoordinates = mYCoordinates; + mPrimaryKeyCodes = new int[N]; + mXCoordinates = new int[N]; + mYCoordinates = new int[N]; + final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes, + xCoordinates, yCoordinates, mTypedWord.toString(), committedWord, separatorCode, + prevWord); + if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD + && type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) { + lastComposedWord.deactivate(); + } + mTypedWord.setLength(0); + refreshSize(); + mAutoCorrection = null; + mIsResumed = false; + return lastComposedWord; + } + + public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { + mPrimaryKeyCodes = lastComposedWord.mPrimaryKeyCodes; + mXCoordinates = lastComposedWord.mXCoordinates; + mYCoordinates = lastComposedWord.mYCoordinates; + mTypedWord.setLength(0); + mTypedWord.append(lastComposedWord.mTypedWord); + refreshSize(); + mAutoCorrection = null; // This will be filled by the next call to updateSuggestion. + mIsResumed = true; + } } |