diff options
Diffstat (limited to 'java/src')
8 files changed, 259 insertions, 266 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java index 2632796dd..feb56ab3a 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java @@ -447,7 +447,8 @@ public class KeyboardParser { textAttr(KeyboardId.modeName( a.getInt(R.styleable.Keyboard_Case_mode, -1)), "mode"), textAttr(KeyboardId.colorSchemeName( - a.getInt(R.styleable.KeyboardView_colorScheme, -1)), "colorSchemeName"), + viewAttr.getInt( + R.styleable.KeyboardView_colorScheme, -1)), "colorSchemeName"), booleanAttr(a, R.styleable.Keyboard_Case_passwordInput, "passwordInput"), booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"), booleanAttr(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"), diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 3d34e71a0..64a23ab92 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -194,7 +194,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // displayed on its spacebar, it might have had arbitrary text fade factor. In such case, // we should reset the text fade factor. It is also applicable to shortcut key. keyboard.setSpacebarTextFadeFactor(0.0f, null); - keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutAvailable(), null); + keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady(), null); return keyboard; } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index d866ec148..08ddd25fa 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -58,6 +58,25 @@ public class BinaryDictionary extends Dictionary { private final int[] mFrequencies_bigrams = new int[MAX_BIGRAMS]; private final KeyboardSwitcher mKeyboardSwitcher = KeyboardSwitcher.getInstance(); + private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance(); + + private static class Flags { + private static class FlagEntry { + public final String mName; + public final int mValue; + public FlagEntry(String name, int value) { + mName = name; + mValue = value; + } + } + public static final FlagEntry[] ALL_FLAGS = { + // Here should reside all flags that trigger some special processing + // These *must* match the definition in UnigramDictionary enum in + // unigram_dictionary.h so please update both at the same time. + new FlagEntry("requiresGermanUmlautProcessing", 0x1) + }; + } + private int mFlags = 0; private BinaryDictionary() { } @@ -91,6 +110,7 @@ public class BinaryDictionary extends Dictionary { return null; } } + sInstance.initFlags(); return sInstance; } @@ -109,16 +129,26 @@ public class BinaryDictionary extends Dictionary { return sInstance; } + private void initFlags() { + int flags = 0; + for (Flags.FlagEntry entry : Flags.ALL_FLAGS) { + if (mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(entry.mName)) + flags |= entry.mValue; + } + mFlags = flags; + } + static { Utils.loadNativeLibrary(); } + private native int openNative(String sourceDir, long dictOffset, long dictSize, int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords, int maxAlternatives); private native void closeNative(int dict); private native boolean isValidWordNative(int nativeData, char[] word, int wordLength); private native int getSuggestionsNative(int dict, int proximityInfo, int[] xCoordinates, - int[] yCoordinates, int[] inputCodes, int codesSize, char[] outputChars, + int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars, int[] frequencies); private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength, int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies, @@ -207,7 +237,7 @@ public class BinaryDictionary extends Dictionary { return getSuggestionsNative( mNativeDict, keyboard.getProximityInfo(), codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, - outputChars, frequencies); + mFlags, outputChars, frequencies); } @Override diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java index 9699ad136..5719b9012 100644 --- a/java/src/com/android/inputmethod/latin/CandidateView.java +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -347,9 +347,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo if (mShowingAddToDictionary && index == 0) { addToDictionary(word); } else { - if (!mSuggestions.mIsApplicationSpecifiedCompletions) { - TextEntryState.acceptedSuggestion(mSuggestions.getWord(0), word); - } mService.pickSuggestionManually(index, word); } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 611d36216..646de66c2 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -542,12 +542,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mSubtypeSwitcher.updateParametersOnStartInputView(); - TextEntryState.newSession(this); + TextEntryState.reset(); // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to // know now whether this is a password text field, because we need to know now whether we // want to enable the voice button. - mVoiceConnector.resetVoiceStates(Utils.isPasswordInputType(attribute.inputType) + final VoiceIMEConnector voiceIme = mVoiceConnector; + voiceIme.resetVoiceStates(Utils.isPasswordInputType(attribute.inputType) || Utils.isVisiblePasswordInputType(attribute.inputType)); initializeInputAttributes(attribute); @@ -562,8 +563,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen loadSettings(attribute); if (mSubtypeSwitcher.isKeyboardMode()) { switcher.loadKeyboard(attribute, - mVoiceConnector.isVoiceButtonEnabled(), - mVoiceConnector.isVoiceButtonOnPrimary()); + mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(), + voiceIme.isVoiceButtonOnPrimary()); switcher.updateShiftState(); } @@ -583,7 +584,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen checkRecorrectionOnStart(); inputView.setForeground(true); - mVoiceConnector.onStartInputView(inputView.getWindowToken()); + voiceIme.onStartInputView(inputView.getWindowToken()); if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } @@ -746,15 +747,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } mVoiceConnector.setVoiceInputHighlighted(false); } else if (!mHasValidSuggestions && !mJustAccepted) { - switch (TextEntryState.getState()) { - case ACCEPTED_DEFAULT: - TextEntryState.reset(); - // $FALL-THROUGH$ - case SPACE_AFTER_PICKED: + if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) { + if (TextEntryState.isAcceptedDefault()) + TextEntryState.reset(); mJustAddedAutoSpace = false; // The user moved the cursor. - break; - default: - break; } } mJustAccepted = false; @@ -832,7 +828,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mVoiceConnector.hideVoiceWindow(mConfigurationChanging); mWordHistory.clear(); super.hideWindow(); - TextEntryState.endSession(); } @Override @@ -1231,7 +1226,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mHandler.postUpdateShiftKeyState(); TextEntryState.backspace(); - if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) { + if (TextEntryState.isUndoCommit()) { revertLastWord(deleteChar); ic.endBatchEdit(); return; @@ -1391,14 +1386,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Handle the case of ". ." -> " .." with auto-space if necessary // before changing the TextEntryState. - if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED - && primaryCode == Keyboard.CODE_PERIOD) { + if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) { reswapPeriodAndSpace(); } TextEntryState.typedCharacter((char) primaryCode, true); - if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED - && primaryCode != Keyboard.CODE_ENTER) { + if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) { swapPunctuationAndSpace(); } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { doubleSpace(); @@ -1430,7 +1423,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); if (inputView != null) inputView.closing(); - TextEntryState.endSession(); } private void saveWordInHistory(CharSequence result) { @@ -1939,7 +1931,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // Reload keyboard because the current language has been changed. mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), - mVoiceConnector.isVoiceButtonEnabled(), mVoiceConnector.isVoiceButtonOnPrimary()); + mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceConnector.isVoiceButtonEnabled(), + mVoiceConnector.isVoiceButtonOnPrimary()); initSuggest(); mKeyboardSwitcher.updateShiftState(); } diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index c43f5b532..dc14d770a 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -46,7 +46,7 @@ import java.util.Map; public class SubtypeSwitcher { private static boolean DBG = LatinImeLogger.sDBG; - private static final String TAG = "SubtypeSwitcher"; + private static final String TAG = SubtypeSwitcher.class.getSimpleName(); private static final char LOCALE_SEPARATER = '_'; private static final String KEYBOARD_MODE = "keyboard"; @@ -74,10 +74,10 @@ public class SubtypeSwitcher { private InputMethodInfo mShortcutInputMethodInfo; private InputMethodSubtype mShortcutSubtype; private List<InputMethodSubtype> mAllEnabledSubtypesOfCurrentInputMethod; + private InputMethodSubtype mCurrentSubtype; private Locale mSystemLocale; private Locale mInputLocale; private String mInputLocaleStr; - private String mMode; private VoiceInput mVoiceInput; /*-----------------------------------------------------------*/ @@ -110,8 +110,7 @@ public class SubtypeSwitcher { mSystemLocale = null; mInputLocale = null; mInputLocaleStr = null; - // Mode is initialized to KEYBOARD_MODE, in case that LatinIME can't obtain currentSubtype - mMode = KEYBOARD_MODE; + mCurrentSubtype = null; mAllEnabledSubtypesOfCurrentInputMethod = null; // TODO: Voice input should be created here mVoiceInput = null; @@ -145,6 +144,7 @@ public class SubtypeSwitcher { // Reload enabledSubtypes from the framework. private void updateEnabledSubtypes() { + final String currentMode = getCurrentSubtypeMode(); boolean foundCurrentSubtypeBecameDisabled = true; mAllEnabledSubtypesOfCurrentInputMethod = mImm.getEnabledInputMethodSubtypeList( null, true); @@ -157,7 +157,7 @@ public class SubtypeSwitcher { if (mLocaleSplitter.hasNext()) { mEnabledLanguagesOfCurrentInputMethod.add(mLocaleSplitter.next()); } - if (locale.equals(mInputLocaleStr) && mode.equals(mMode)) { + if (locale.equals(mInputLocaleStr) && mode.equals(currentMode)) { foundCurrentSubtypeBecameDisabled = false; } if (KEYBOARD_MODE.equals(ims.getMode())) { @@ -168,7 +168,7 @@ public class SubtypeSwitcher { && mIsSystemLanguageSameAsInputLanguage); if (foundCurrentSubtypeBecameDisabled) { if (DBG) { - Log.w(TAG, "Current subtype: " + mInputLocaleStr + ", " + mMode); + Log.w(TAG, "Current subtype: " + mInputLocaleStr + ", " + currentMode); Log.w(TAG, "Last subtype was disabled. Update to the current one."); } updateSubtype(mImm.getCurrentInputMethodSubtype()); @@ -209,9 +209,10 @@ public class SubtypeSwitcher { public void updateSubtype(InputMethodSubtype newSubtype) { final String newLocale; final String newMode; + final String oldMode = getCurrentSubtypeMode(); if (newSubtype == null) { // Normally, newSubtype shouldn't be null. But just in case newSubtype was null, - // fallback to the default locale and mode. + // fallback to the default locale. Log.w(TAG, "Couldn't get the current subtype."); newLocale = "en_US"; newMode = KEYBOARD_MODE; @@ -221,7 +222,7 @@ public class SubtypeSwitcher { } if (DBG) { Log.w(TAG, "Update subtype to:" + newLocale + "," + newMode - + ", from: " + mInputLocaleStr + ", " + mMode); + + ", from: " + mInputLocaleStr + ", " + oldMode); } boolean languageChanged = false; if (!newLocale.equals(mInputLocaleStr)) { @@ -231,13 +232,12 @@ public class SubtypeSwitcher { updateInputLocale(newLocale); } boolean modeChanged = false; - String oldMode = mMode; - if (!newMode.equals(mMode)) { - if (mMode != null) { + if (!newMode.equals(oldMode)) { + if (oldMode != null) { modeChanged = true; } - mMode = newMode; } + mCurrentSubtype = newSubtype; // If the old mode is voice input, we need to reset or cancel its status. // We cancel its status when we change mode, while we reset otherwise. @@ -262,7 +262,7 @@ public class SubtypeSwitcher { triggerVoiceIME(); } } else { - Log.w(TAG, "Unknown subtype mode: " + mMode); + Log.w(TAG, "Unknown subtype mode: " + newMode); if (VOICE_MODE.equals(oldMode) && mVoiceInput != null) { // We need to reset the voice input to release the resources and to reset its status // as it is not the current input mode. @@ -355,11 +355,27 @@ public class SubtypeSwitcher { return false; } - public boolean isShortcutAvailable() { + public boolean isShortcutImeEnabled() { if (mShortcutInputMethodInfo == null) return false; - if (mShortcutSubtype != null && contains(mShortcutSubtype.getExtraValue().split(","), - SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY)) { + if (mShortcutSubtype == null) + return true; + final boolean allowsImplicitlySelectedSubtypes = true; + for (final InputMethodSubtype enabledSubtype : mImm.getEnabledInputMethodSubtypeList( + mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) { + if (enabledSubtype.equals(mShortcutSubtype)) + return true; + } + return false; + } + + public boolean isShortcutImeReady() { + if (mShortcutInputMethodInfo == null) + return false; + if (mShortcutSubtype == null) + return true; + if (contains(mShortcutSubtype.getExtraValue().split(","), + SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY)) { return mIsNetworkConnected; } return true; @@ -373,7 +389,7 @@ public class SubtypeSwitcher { final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance(); final LatinKeyboard keyboard = switcher.getLatinKeyboard(); if (keyboard != null) { - keyboard.updateShortcutKey(isShortcutAvailable(), switcher.getInputView()); + keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getInputView()); } } @@ -483,7 +499,7 @@ public class SubtypeSwitcher { } public boolean isKeyboardMode() { - return KEYBOARD_MODE.equals(mMode); + return KEYBOARD_MODE.equals(getCurrentSubtypeMode()); } @@ -506,7 +522,7 @@ public class SubtypeSwitcher { } public boolean isVoiceMode() { - return VOICE_MODE.equals(mMode); + return null == mCurrentSubtype ? false : VOICE_MODE.equals(getCurrentSubtypeMode()); } private void triggerVoiceIME() { @@ -572,6 +588,30 @@ public class SubtypeSwitcher { } } + ///////////////////////////// + // Other utility functions // + ///////////////////////////// + + public String getCurrentSubtypeExtraValue() { + // If null, return what an empty ExtraValue would return : the empty string. + return null != mCurrentSubtype ? mCurrentSubtype.getExtraValue() : ""; + } + + public boolean currentSubtypeContainsExtraValueKey(String key) { + // If null, return what an empty ExtraValue would return : false. + return null != mCurrentSubtype ? mCurrentSubtype.containsExtraValueKey(key) : false; + } + + public String getCurrentSubtypeExtraValueOf(String key) { + // If null, return what an empty ExtraValue would return : null. + return null != mCurrentSubtype ? mCurrentSubtype.getExtraValueOf(key) : null; + } + + public String getCurrentSubtypeMode() { + return null != mCurrentSubtype ? mCurrentSubtype.getMode() : KEYBOARD_MODE; + } + + // A list of locales which are supported by default for voice input, unless we get a // different list from Gservices. private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index f774ce3a5..fe7aac7c2 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -24,23 +24,20 @@ import java.util.HashSet; import java.util.List; public class SuggestedWords { - public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, null); + public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, null); public final List<CharSequence> mWords; - public final boolean mIsApplicationSpecifiedCompletions; public final boolean mTypedWordValid; public final boolean mHasMinimalSuggestion; public final List<SuggestedWordInfo> mSuggestedWordInfoList; - private SuggestedWords(List<CharSequence> words, boolean isApplicationSpecifiedCompletions, - boolean typedWordValid, boolean hasMinamlSuggestion, - List<SuggestedWordInfo> suggestedWordInfoList) { + private SuggestedWords(List<CharSequence> words, boolean typedWordValid, + boolean hasMinamlSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) { if (words != null) { mWords = words; } else { mWords = Collections.emptyList(); } - mIsApplicationSpecifiedCompletions = isApplicationSpecifiedCompletions; mTypedWordValid = typedWordValid; mHasMinimalSuggestion = hasMinamlSuggestion; mSuggestedWordInfoList = suggestedWordInfoList; @@ -64,7 +61,6 @@ public class SuggestedWords { public static class Builder { private List<CharSequence> mWords = new ArrayList<CharSequence>(); - private boolean mIsCompletions; private boolean mTypedWordValid; private boolean mHasMinimalSuggestion; private List<SuggestedWordInfo> mSuggestedWordInfoList = @@ -109,7 +105,6 @@ public class SuggestedWords { public Builder setApplicationSpecifiedCompletions(CompletionInfo[] infos) { for (CompletionInfo info : infos) addWord(info.getText()); - mIsCompletions = true; return this; } @@ -141,15 +136,14 @@ public class SuggestedWords { alreadySeen.add(prevWord); } } - mIsCompletions = false; mTypedWordValid = false; mHasMinimalSuggestion = false; return this; } public SuggestedWords build() { - return new SuggestedWords(mWords, mIsCompletions, mTypedWordValid, - mHasMinimalSuggestion, mSuggestedWordInfoList); + return new SuggestedWords(mWords, mTypedWordValid, mHasMinimalSuggestion, + mSuggestedWordInfoList); } public int size() { diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java index c8b8c334d..a4e0b359b 100644 --- a/java/src/com/android/inputmethod/latin/TextEntryState.java +++ b/java/src/com/android/inputmethod/latin/TextEntryState.java @@ -16,117 +16,39 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.keyboard.Key; - -import android.content.Context; -import android.text.format.DateFormat; import android.util.Log; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Calendar; - public class TextEntryState { - - private static final boolean DBG = false; - - private static final String TAG = "TextEntryState"; - - private static boolean LOGGING = false; - - private static int sBackspaceCount = 0; - - private static int sAutoSuggestCount = 0; - - private static int sAutoSuggestUndoneCount = 0; - - private static int sManualSuggestCount = 0; - - private static int sWordNotInDictionaryCount = 0; - - private static int sSessionCount = 0; - - private static int sTypedChars; - - private static int sActualChars; - - public enum State { - UNKNOWN, - START, - IN_WORD, - ACCEPTED_DEFAULT, - PICKED_SUGGESTION, - PUNCTUATION_AFTER_WORD, - PUNCTUATION_AFTER_ACCEPTED, - SPACE_AFTER_ACCEPTED, - SPACE_AFTER_PICKED, - UNDO_COMMIT, - RECORRECTING, - PICKED_RECORRECTION, + private static final String TAG = TextEntryState.class.getSimpleName(); + private static final boolean DEBUG = true; + + private static final int UNKNOWN = 0; + private static final int START = 1; + private static final int IN_WORD = 2; + private static final int ACCEPTED_DEFAULT = 3; + private static final int PICKED_SUGGESTION = 4; + private static final int PUNCTUATION_AFTER_WORD = 5; + private static final int PUNCTUATION_AFTER_ACCEPTED = 6; + private static final int SPACE_AFTER_ACCEPTED = 7; + private static final int SPACE_AFTER_PICKED = 8; + private static final int UNDO_COMMIT = 9; + private static final int RECORRECTING = 10; + private static final int PICKED_RECORRECTION = 11; + + private static int sState = UNKNOWN; + private static int sPreviousState = UNKNOWN; + + private static void setState(final int newState) { + sPreviousState = sState; + sState = newState; } - private static State sState = State.UNKNOWN; - - private static FileOutputStream sKeyLocationFile; - private static FileOutputStream sUserActionFile; - - public static void newSession(Context context) { - sSessionCount++; - sAutoSuggestCount = 0; - sBackspaceCount = 0; - sAutoSuggestUndoneCount = 0; - sManualSuggestCount = 0; - sWordNotInDictionaryCount = 0; - sTypedChars = 0; - sActualChars = 0; - sState = State.START; - - if (LOGGING) { - try { - sKeyLocationFile = context.openFileOutput("key.txt", Context.MODE_APPEND); - sUserActionFile = context.openFileOutput("action.txt", Context.MODE_APPEND); - } catch (IOException ioe) { - Log.e("TextEntryState", "Couldn't open file for output: " + ioe); - } - } - } - - public static void endSession() { - if (sKeyLocationFile == null) { - return; - } - try { - sKeyLocationFile.close(); - // Write to log file - // Write timestamp, settings, - String out = DateFormat.format("MM:dd hh:mm:ss", Calendar.getInstance().getTime()) - .toString() - + " BS: " + sBackspaceCount - + " auto: " + sAutoSuggestCount - + " manual: " + sManualSuggestCount - + " typed: " + sWordNotInDictionaryCount - + " undone: " + sAutoSuggestUndoneCount - + " saved: " + ((float) (sActualChars - sTypedChars) / sActualChars) - + "\n"; - sUserActionFile.write(out.getBytes()); - sUserActionFile.close(); - sKeyLocationFile = null; - sUserActionFile = null; - } catch (IOException ioe) { - // ignore - } - } - public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) { if (typedWord == null) return; - if (!typedWord.equals(actualWord)) { - sAutoSuggestCount++; - } - sTypedChars += typedWord.length(); - sActualChars += actualWord.length(); - sState = State.ACCEPTED_DEFAULT; + setState(ACCEPTED_DEFAULT); LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString()); - displayState(); + if (DEBUG) + displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord); } // State.ACCEPTED_DEFAULT will be changed to other sub-states @@ -138,151 +60,167 @@ public class TextEntryState { case SPACE_AFTER_ACCEPTED: case PUNCTUATION_AFTER_ACCEPTED: case IN_WORD: - sState = State.ACCEPTED_DEFAULT; + setState(ACCEPTED_DEFAULT); break; default: break; } - displayState(); + if (DEBUG) displayState("backToAcceptedDefault", "typedWord", typedWord); } - public static void acceptedTyped(@SuppressWarnings("unused") CharSequence typedWord) { - sWordNotInDictionaryCount++; - sState = State.PICKED_SUGGESTION; - displayState(); + public static void acceptedTyped(CharSequence typedWord) { + setState(PICKED_SUGGESTION); + if (DEBUG) displayState("acceptedTyped", "typedWord", typedWord); } public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) { - sManualSuggestCount++; - State oldState = sState; - if (typedWord.equals(actualWord)) { - acceptedTyped(typedWord); - } - if (oldState == State.RECORRECTING || oldState == State.PICKED_RECORRECTION) { - sState = State.PICKED_RECORRECTION; + if (sState == RECORRECTING || sState == PICKED_RECORRECTION) { + setState(PICKED_RECORRECTION); } else { - sState = State.PICKED_SUGGESTION; + setState(PICKED_SUGGESTION); } - displayState(); + if (DEBUG) + displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord); } public static void selectedForRecorrection() { - sState = State.RECORRECTING; - displayState(); + setState(RECORRECTING); + if (DEBUG) displayState("selectedForRecorrection"); } public static void onAbortRecorrection() { - if (isRecorrecting()) { - sState = State.START; + if (sState == RECORRECTING || sState == PICKED_RECORRECTION) { + setState(START); } - displayState(); + if (DEBUG) displayState("onAbortRecorrection"); } public static void typedCharacter(char c, boolean isSeparator) { - boolean isSpace = c == ' '; + final boolean isSpace = (c == ' '); switch (sState) { - case IN_WORD: - if (isSpace || isSeparator) { - sState = State.START; - } else { - // State hasn't changed. - } - break; - case ACCEPTED_DEFAULT: - case SPACE_AFTER_PICKED: - if (isSpace) { - sState = State.SPACE_AFTER_ACCEPTED; - } else if (isSeparator) { - sState = State.PUNCTUATION_AFTER_ACCEPTED; - } else { - sState = State.IN_WORD; - } - break; - case PICKED_SUGGESTION: - case PICKED_RECORRECTION: - if (isSpace) { - sState = State.SPACE_AFTER_PICKED; - } else if (isSeparator) { - // Swap - sState = State.PUNCTUATION_AFTER_ACCEPTED; - } else { - sState = State.IN_WORD; - } - break; - case START: - case UNKNOWN: - case SPACE_AFTER_ACCEPTED: - case PUNCTUATION_AFTER_ACCEPTED: - case PUNCTUATION_AFTER_WORD: - if (!isSpace && !isSeparator) { - sState = State.IN_WORD; - } else { - sState = State.START; - } - break; - case UNDO_COMMIT: - if (isSpace || isSeparator) { - sState = State.ACCEPTED_DEFAULT; - } else { - sState = State.IN_WORD; - } - break; - case RECORRECTING: - sState = State.START; - break; + case IN_WORD: + if (isSpace || isSeparator) { + setState(START); + } else { + // State hasn't changed. + } + break; + case ACCEPTED_DEFAULT: + case SPACE_AFTER_PICKED: + case PUNCTUATION_AFTER_ACCEPTED: + if (isSpace) { + setState(SPACE_AFTER_ACCEPTED); + } else if (isSeparator) { + // Swap + setState(PUNCTUATION_AFTER_ACCEPTED); + } else { + setState(IN_WORD); + } + break; + case PICKED_SUGGESTION: + case PICKED_RECORRECTION: + if (isSpace) { + setState(SPACE_AFTER_PICKED); + } else if (isSeparator) { + // Swap + setState(PUNCTUATION_AFTER_ACCEPTED); + } else { + setState(IN_WORD); + } + break; + case START: + case UNKNOWN: + case SPACE_AFTER_ACCEPTED: + case PUNCTUATION_AFTER_WORD: + if (!isSpace && !isSeparator) { + setState(IN_WORD); + } else { + setState(START); + } + break; + case UNDO_COMMIT: + if (isSpace || isSeparator) { + setState(ACCEPTED_DEFAULT); + } else { + setState(IN_WORD); + } + break; + case RECORRECTING: + setState(START); + break; } - displayState(); + if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator); } public static void backspace() { - if (sState == State.ACCEPTED_DEFAULT) { - sState = State.UNDO_COMMIT; - sAutoSuggestUndoneCount++; + if (sState == ACCEPTED_DEFAULT) { + setState(UNDO_COMMIT); LatinImeLogger.logOnAutoSuggestionCanceled(); - } else if (sState == State.UNDO_COMMIT) { - sState = State.IN_WORD; + } else if (sState == UNDO_COMMIT) { + setState(IN_WORD); } - sBackspaceCount++; - displayState(); + if (DEBUG) displayState("backspace"); } public static void reset() { - sState = State.START; - displayState(); + setState(START); + if (DEBUG) displayState("reset"); } - public static State getState() { - if (DBG) { - Log.d(TAG, "Returning state = " + sState); - } - return sState; + public static boolean isAcceptedDefault() { + return sState == ACCEPTED_DEFAULT; } - public static boolean isRecorrecting() { - return sState == State.RECORRECTING || sState == State.PICKED_RECORRECTION; + public static boolean isSpaceAfterPicked() { + return sState == SPACE_AFTER_PICKED; } - public static void keyPressedAt(Key key, int x, int y) { - if (LOGGING && sKeyLocationFile != null && key.mCode >= 32) { - String out = - "KEY: " + (char) key.mCode - + " X: " + x - + " Y: " + y - + " MX: " + (key.mX + key.mWidth / 2) - + " MY: " + (key.mY + key.mHeight / 2) - + "\n"; - try { - sKeyLocationFile.write(out.getBytes()); - } catch (IOException ioe) { - // TODO: May run out of space - } + public static boolean isUndoCommit() { + return sState == UNDO_COMMIT; + } + + public static boolean isPunctuationAfterAccepted() { + return sState == PUNCTUATION_AFTER_ACCEPTED; + } + + public static boolean isRecorrecting() { + return sState == RECORRECTING || sState == PICKED_RECORRECTION; + } + + public static String getState() { + return stateName(sState); + } + + private static String stateName(int state) { + switch (state) { + case START: return "START"; + case IN_WORD: return "IN_WORD"; + case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT"; + case PICKED_SUGGESTION: return "PICKED_SUGGESTION"; + case PUNCTUATION_AFTER_WORD: return "PUNCTUATION_AFTER_WORD"; + case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED"; + case SPACE_AFTER_ACCEPTED: return "SPACE_AFTER_ACCEPTED"; + case SPACE_AFTER_PICKED: return "SPACE_AFTER_PICKED"; + case UNDO_COMMIT: return "UNDO_COMMIT"; + case RECORRECTING: return "RECORRECTING"; + case PICKED_RECORRECTION: return "PICKED_RECORRECTION"; + default: return "UNKNOWN"; } } - private static void displayState() { - if (DBG) { - Log.d(TAG, "State = " + sState); + private static void displayState(String title, Object ... args) { + final StringBuilder sb = new StringBuilder(title); + sb.append(':'); + for (int i = 0; i < args.length; i += 2) { + sb.append(' '); + sb.append(args[i]); + sb.append('='); + sb.append(args[i+1].toString()); } + sb.append(" state="); + sb.append(stateName(sState)); + sb.append(" previous="); + sb.append(stateName(sPreviousState)); + Log.d(TAG, sb.toString()); } } - |