diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 75f4aaccd..a61305d51 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -16,15 +16,26 @@ package com.android.inputmethod.latin.inputlogic; +import android.os.SystemClock; +import android.view.inputmethod.EditorInfo; + import com.android.inputmethod.event.EventInterpreter; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.LastComposedWord; import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.RichInputConnection; +import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.WordComposer; +import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.RecapitalizeStatus; +import com.android.inputmethod.research.ResearchLogger; import java.util.TreeSet; @@ -75,4 +86,182 @@ public final class InputLogic { public void startInput(final boolean restarting) { } + + public void onCodeInput(final int primaryCode, final int x, final int y, + // TODO: remove these three arguments + final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher, + final SubtypeSwitcher subtypeSwitcher) { + if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { + ResearchLogger.latinIME_onCodeInput(primaryCode, x, y); + } + final long when = SystemClock.uptimeMillis(); + if (primaryCode != Constants.CODE_DELETE + || when > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) { + mDeleteCount = 0; + } + mLastKeyTime = when; + mConnection.beginBatchEdit(); + final KeyboardSwitcher switcher = keyboardSwitcher; + // The space state depends only on the last character pressed and its own previous + // state. Here, we revert the space state to neutral if the key is actually modifying + // the input contents (any non-shift key), which is what we should do for + // all inputs that do not result in a special state. Each character handling is then + // free to override the state as they see fit. + final int spaceState = mSpaceState; + if (!mWordComposer.isComposingWord()) { + mIsAutoCorrectionIndicatorOn = false; + } + + // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state. + if (primaryCode != Constants.CODE_SPACE) { + handler.cancelDoubleSpacePeriodTimer(); + } + + boolean didAutoCorrect = false; + switch (primaryCode) { + case Constants.CODE_DELETE: + mSpaceState = SpaceState.NONE; + handleBackspace(spaceState); + LatinImeLogger.logOnDelete(x, y); + break; + case Constants.CODE_SHIFT: + // Note: Calling back to the keyboard on Shift key is handled in + // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. + final Keyboard currentKeyboard = switcher.getKeyboard(); + if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { + // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for + // alphabetic shift and shift while in symbol layout. + handleRecapitalize(); + } + break; + case Constants.CODE_CAPSLOCK: + // Note: Changing keyboard to shift lock state is handled in + // {@link KeyboardSwitcher#onCodeInput(int)}. + break; + case Constants.CODE_SWITCH_ALPHA_SYMBOL: + // Note: Calling back to the keyboard on symbol key is handled in + // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. + break; + case Constants.CODE_SETTINGS: + onSettingsKeyPressed(); + break; + case Constants.CODE_SHORTCUT: + subtypeSwitcher.switchToShortcutIME(mLatinIME); + break; + case Constants.CODE_ACTION_NEXT: + performEditorAction(EditorInfo.IME_ACTION_NEXT); + break; + case Constants.CODE_ACTION_PREVIOUS: + performEditorAction(EditorInfo.IME_ACTION_PREVIOUS); + break; + case Constants.CODE_LANGUAGE_SWITCH: + handleLanguageSwitchKey(); + break; + case Constants.CODE_EMOJI: + // Note: Switching emoji keyboard is being handled in + // {@link KeyboardState#onCodeInput(int,int)}. + break; + case Constants.CODE_ENTER: + final EditorInfo editorInfo = getCurrentInputEditorInfo(); + final int imeOptionsActionId = + InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo); + if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) { + // Either we have an actionLabel and we should performEditorAction with actionId + // regardless of its value. + performEditorAction(editorInfo.actionId); + } else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) { + // We didn't have an actionLabel, but we had another action to execute. + // EditorInfo.IME_ACTION_NONE explicitly means no action. In contrast, + // EditorInfo.IME_ACTION_UNSPECIFIED is the default value for an action, so it + // means there should be an action and the app didn't bother to set a specific + // code for it - presumably it only handles one. It does not have to be treated + // in any specific way: anything that is not IME_ACTION_NONE should be sent to + // performEditorAction. + performEditorAction(imeOptionsActionId); + } else { + // No action label, and the action from imeOptions is NONE: this is a regular + // enter key that should input a carriage return. + didAutoCorrect = handleNonSpecialCharacter(Constants.CODE_ENTER, x, y, spaceState); + } + break; + case Constants.CODE_SHIFT_ENTER: + didAutoCorrect = handleNonSpecialCharacter(Constants.CODE_ENTER, x, y, spaceState); + break; + default: + didAutoCorrect = handleNonSpecialCharacter(primaryCode, x, y, spaceState); + break; + } + switcher.onCodeInput(primaryCode); + // Reset after any single keystroke, except shift, capslock, and symbol-shift + if (!didAutoCorrect && primaryCode != Constants.CODE_SHIFT + && primaryCode != Constants.CODE_CAPSLOCK + && primaryCode != Constants.CODE_SWITCH_ALPHA_SYMBOL) + mLastComposedWord.deactivate(); + if (Constants.CODE_DELETE != primaryCode) { + mEnteredText = null; + } + mConnection.endBatchEdit(); + } + + /** + * Handle inputting a code point to the editor. + * + * Non-special keys are those that generate a single code point. + * This includes all letters, digits, punctuation, separators, emoji. It excludes keys that + * manage keyboard-related stuff like shift, language switch, settings, layout switch, or + * any key that results in multiple code points like the ".com" key. + * + * @param code the code point associated with the key. + * @param x the x-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable. + * @param y the y-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable. + * @param spaceState the space state at start of the batch input. + * @return whether this caused an auto-correction to happen. + */ + private boolean handleNonSpecialCharacter(final int code, final int x, final int y, + final int spaceState) { + return mLatinIME.handleNonSpecialCharacter(code, x, y, spaceState); + } + + /** + * Handle a press on the backspace key. + * @param spaceState The space state at start of this batch edit. + */ + private void handleBackspace(final int spaceState) { + mLatinIME.handleBackspace(spaceState); + } + + /** + * Handle a press on the language switch key (the "globe key") + */ + private void handleLanguageSwitchKey() { + mLatinIME.handleLanguageSwitchKey(); + } + + /** + * Processes a recapitalize event. + */ + private void handleRecapitalize() { + mLatinIME.handleRecapitalize(); + } + + /** + * @return the editor info for the current editor + */ + private EditorInfo getCurrentInputEditorInfo() { + return mLatinIME.getCurrentInputEditorInfo(); + } + + /** + * @param actionId the action to perform + */ + private void performEditorAction(final int actionId) { + mConnection.performEditorAction(actionId); + } + + /** + * Handle a press on the settings key. + */ + private void onSettingsKeyPressed() { + mLatinIME.onSettingsKeyPressed(); + } } |