aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorJean Chalard <jchalard@google.com>2013-12-19 14:34:35 +0900
committerJean Chalard <jchalard@google.com>2013-12-19 16:24:45 +0900
commitcddf4f9d781850fb4ffcfd8dfc434aa44c5d9f88 (patch)
tree9c3a004e1e93d2ef2538e10493c2546a7e08eae9 /java/src
parent7bd2a75ca180cb5da8ba75500163aa06f332caac (diff)
downloadlatinime-cddf4f9d781850fb4ffcfd8dfc434aa44c5d9f88.tar.gz
latinime-cddf4f9d781850fb4ffcfd8dfc434aa44c5d9f88.tar.xz
latinime-cddf4f9d781850fb4ffcfd8dfc434aa44c5d9f88.zip
[IL2] Move onCodeInput to InputLogic.
Bug: 8636060 Change-Id: I8c5c028d81183adb0167b2034ee01de8048edafb
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java4
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java201
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java189
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/SpaceState.java54
4 files changed, 284 insertions, 164 deletions
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index c260434d5..ebbd98ced 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -154,6 +154,9 @@ public final class Constants {
// Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
+ // Key events coming any faster than this are long-presses.
+ public static final int LONG_PRESS_MILLISECONDS = 200;
+
public static boolean isValidCoordinate(final int coordinate) {
// Detect {@link NOT_A_COORDINATE}, {@link SUGGESTION_STRIP_COORDINATE},
// and {@link SPELL_CHECKER_COORDINATE}.
@@ -242,5 +245,4 @@ public final class Constants {
private Constants() {
// This utility class is not publicly instantiable.
}
-
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 81db8dcd0..bdf4f484a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -77,6 +77,7 @@ import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.inputlogic.InputLogic;
+import com.android.inputmethod.latin.inputlogic.SpaceState;
import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever;
import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
@@ -122,8 +123,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// How many continuous deletes at which to start deleting at a higher speed.
private static final int DELETE_ACCELERATE_AT = 20;
- // Key events coming any faster than this are long-presses.
- private static final int QUICK_PRESS = 200;
private static final int PENDING_IMS_CALLBACK_DURATION = 800;
@@ -138,22 +137,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
private static final String SCHEME_PACKAGE = "package";
- private static final int SPACE_STATE_NONE = 0;
- // Double space: the state where the user pressed space twice quickly, which LatinIME
- // resolved as period-space. Undoing this converts the period to a space.
- private static final int SPACE_STATE_DOUBLE = 1;
- // Swap punctuation: the state where a weak space and a punctuation from the suggestion strip
- // have just been swapped. Undoing this swaps them back; the space is still considered weak.
- private static final int SPACE_STATE_SWAP_PUNCTUATION = 2;
- // Weak space: a space that should be swapped only by suggestion strip punctuation. Weak
- // spaces happen when the user presses space, accepting the current suggestion (whether
- // it's an auto-correction or not).
- private static final int SPACE_STATE_WEAK = 3;
- // Phantom space: a not-yet-inserted space that should get inserted on the next input,
- // character provided it's not a separator. If it's a separator, the phantom space is dropped.
- // Phantom spaces happen when a user chooses a word from the suggestion strip.
- private static final int SPACE_STATE_PHANTOM = 4;
-
private final Settings mSettings;
private final InputLogic mInputLogic = new InputLogic(this);
@@ -803,7 +786,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.mEnteredText = null;
resetComposingState(true /* alsoResetLastComposedWord */);
mInputLogic.mDeleteCount = 0;
- mInputLogic.mSpaceState = SPACE_STATE_NONE;
+ mInputLogic.mSpaceState = SpaceState.NONE;
mInputLogic.mRecapitalizeStatus.deactivate();
mInputLogic.mCurrentlyPressedHardwareKeys.clear();
@@ -1038,7 +1021,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// the call to updateShiftState.
// We set this to NONE because after a cursor move, we don't want the space
// state-related special processing to kick in.
- mInputLogic.mSpaceState = SPACE_STATE_NONE;
+ mInputLogic.mSpaceState = SpaceState.NONE;
// TODO: is it still necessary to test for composingSpan related stuff?
final boolean selectionChangedOrSafeToReset = selectionChanged
@@ -1332,7 +1315,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Warning: this depends on mSpaceState, which may not be the most current value. If
// mSpaceState gets updated later, whoever called this may need to be told about it.
return mInputLogic.mConnection.getCursorCapsMode(inputType, currentSettingsValues,
- SPACE_STATE_PHANTOM == mInputLogic.mSpaceState);
+ SpaceState.PHANTOM == mInputLogic.mSpaceState);
}
public int getCurrentRecapitalizeState() {
@@ -1441,7 +1424,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mUserDictionary.addWordToUserDictionary(wordToEdit);
}
- private void onSettingsKeyPressed() {
+ // TODO[IL]: Rework the route through which this is called.
+ public void onSettingsKeyPressed() {
if (isShowingOptionDialog()) return;
showSubtypeSelectorAndSettings();
}
@@ -1464,12 +1448,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mOptionsDialog != null && mOptionsDialog.isShowing();
}
- private void performEditorAction(final int actionId) {
- mInputLogic.mConnection.performEditorAction(actionId);
- }
-
// TODO: Revise the language switch key behavior to make it much smarter and more reasonable.
- private void handleLanguageSwitchKey() {
+ // TODO[IL]: Move a part of this to InputLogic and straighten out the interface for this.
+ public void handleLanguageSwitchKey() {
final IBinder token = getWindow().getWindow().getAttributes().token;
if (mSettings.getCurrent().mIncludesOtherImesInLanguageSwitchList) {
mRichImm.switchToNextInputMethod(token, false /* onlyCurrentIme */);
@@ -1513,121 +1494,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Implementation of {@link KeyboardActionListener}.
@Override
public void onCodeInput(final int primaryCode, final int x, final int y) {
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
- }
- final long when = SystemClock.uptimeMillis();
- if (primaryCode != Constants.CODE_DELETE
- || when > mInputLogic.mLastKeyTime + QUICK_PRESS) {
- mInputLogic.mDeleteCount = 0;
- }
- mInputLogic.mLastKeyTime = when;
- mInputLogic.mConnection.beginBatchEdit();
- final KeyboardSwitcher switcher = mKeyboardSwitcher;
- // 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 = mInputLogic.mSpaceState;
- if (!mInputLogic.mWordComposer.isComposingWord()) {
- mInputLogic.mIsAutoCorrectionIndicatorOn = false;
- }
-
- // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
- if (primaryCode != Constants.CODE_SPACE) {
- mHandler.cancelDoubleSpacePeriodTimer();
- }
-
- boolean didAutoCorrect = false;
- switch (primaryCode) {
- case Constants.CODE_DELETE:
- mInputLogic.mSpaceState = SPACE_STATE_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:
- mSubtypeSwitcher.switchToShortcutIME(this);
- 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)
- mInputLogic.mLastComposedWord.deactivate();
- if (Constants.CODE_DELETE != primaryCode) {
- mInputLogic.mEnteredText = null;
- }
- mInputLogic.mConnection.endBatchEdit();
+ mInputLogic.onCodeInput(primaryCode, x, y, mHandler, mKeyboardSwitcher, mSubtypeSwitcher);
}
- private boolean handleNonSpecialCharacter(final int primaryCode, final int x, final int y,
+ // TODO[IL]: Move this to InputLogic and make it private again.
+ public boolean handleNonSpecialCharacter(final int primaryCode, final int x, final int y,
final int spaceState) {
- mInputLogic.mSpaceState = SPACE_STATE_NONE;
+ mInputLogic.mSpaceState = SpaceState.NONE;
final boolean didAutoCorrect;
final SettingsValues settingsValues = mSettings.getCurrent();
if (settingsValues.isWordSeparator(primaryCode)
@@ -1635,7 +1508,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
} else {
didAutoCorrect = false;
- if (SPACE_STATE_PHANTOM == spaceState) {
+ if (SpaceState.PHANTOM == spaceState) {
if (settingsValues.mIsInternal) {
if (mInputLogic.mWordComposer.isComposingWord()
&& mInputLogic.mWordComposer.isBatchMode()) {
@@ -1683,7 +1556,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
final String text = specificTldProcessingOnTextInput(rawText);
- if (SPACE_STATE_PHANTOM == mInputLogic.mSpaceState) {
+ if (SpaceState.PHANTOM == mInputLogic.mSpaceState) {
promotePhantomSpace();
}
mInputLogic.mConnection.commitText(text, 1);
@@ -1692,7 +1565,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mInputLogic.mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
- mInputLogic.mSpaceState = SPACE_STATE_NONE;
+ mInputLogic.mSpaceState = SpaceState.NONE;
mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
mInputLogic.mEnteredText = text;
@@ -1737,7 +1610,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|| currentSettingsValues.isUsuallyFollowedBySpace(codePointBeforeCursor)) {
final boolean autoShiftHasBeenOverriden = mKeyboardSwitcher.getKeyboardShiftMode() !=
getCurrentAutoCapsState();
- mInputLogic.mSpaceState = SPACE_STATE_PHANTOM;
+ mInputLogic.mSpaceState = SpaceState.PHANTOM;
if (!autoShiftHasBeenOverriden) {
// When we change the space state, we need to update the shift state of the
// keyboard unless it has been overridden manually. This is happening for example
@@ -1924,7 +1797,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
batchPointers.shift(candidate.mIndexOfTouchPointOfSecondWord);
promotePhantomSpace();
mInputLogic.mConnection.commitText(commitParts[0], 0);
- mInputLogic.mSpaceState = SPACE_STATE_PHANTOM;
+ mInputLogic.mSpaceState = SpaceState.PHANTOM;
mKeyboardSwitcher.updateShiftState();
mInputLogic.mWordComposer.
setCapitalizedModeAndPreviousWordAtStartComposingTime(
@@ -1943,7 +1816,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
mInputLogic.mConnection.beginBatchEdit();
- if (SPACE_STATE_PHANTOM == mInputLogic.mSpaceState) {
+ if (SpaceState.PHANTOM == mInputLogic.mSpaceState) {
promotePhantomSpace();
}
if (mSettings.getCurrent().mPhraseGestureEnabled) {
@@ -1966,7 +1839,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ResearchLogger.latinIME_onEndBatchInput(batchInputText, 0, suggestedWords);
}
// Space state must be updated before calling updateShiftState
- mInputLogic.mSpaceState = SPACE_STATE_PHANTOM;
+ mInputLogic.mSpaceState = SpaceState.PHANTOM;
mKeyboardSwitcher.updateShiftState();
}
@@ -1983,7 +1856,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// We have a TLD (or something that looks like this): make sure we don't add
// a space even if currently in phantom mode.
- mInputLogic.mSpaceState = SPACE_STATE_NONE;
+ mInputLogic.mSpaceState = SpaceState.NONE;
// TODO: use getCodePointBeforeCursor instead to improve performance and simplify the code
final CharSequence lastOne = mInputLogic.mConnection.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
@@ -2013,7 +1886,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputUpdater.onCancelBatchInput();
}
- private void handleBackspace(final int spaceState) {
+ // TODO[IL]: Move this to InputLogic and make private again.
+ public void handleBackspace(final int spaceState) {
mInputLogic.mDeleteCount++;
// In many cases, we may have to put the keyboard in auto-shift state again. However
@@ -2073,14 +1947,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// reverting any autocorrect at this point. So we can safely return.
return;
}
- if (SPACE_STATE_DOUBLE == spaceState) {
+ if (SpaceState.DOUBLE == spaceState) {
mHandler.cancelDoubleSpacePeriodTimer();
if (mInputLogic.mConnection.revertDoubleSpacePeriod()) {
// No need to reset mSpaceState, it has already be done (that's why we
// receive it as a parameter)
return;
}
- } else if (SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
+ } else if (SpaceState.SWAP_PUNCTUATION == spaceState) {
if (mInputLogic.mConnection.revertSwapPunctuation()) {
// Likewise
return;
@@ -2167,11 +2041,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
private boolean maybeStripSpace(final int code, final int spaceState,
final boolean isFromSuggestionStrip) {
- if (Constants.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
+ if (Constants.CODE_ENTER == code && SpaceState.SWAP_PUNCTUATION == spaceState) {
mInputLogic.mConnection.removeTrailingSpace();
return false;
}
- if ((SPACE_STATE_WEAK == spaceState || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
+ if ((SpaceState.WEAK == spaceState || SpaceState.SWAP_PUNCTUATION == spaceState)
&& isFromSuggestionStrip) {
final SettingsValues currentSettings = mSettings.getCurrent();
if (currentSettings.isUsuallyPrecededBySpace(code)) return false;
@@ -2191,7 +2065,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
// See onStartBatchInput() to see how to do it.
final SettingsValues currentSettings = mSettings.getCurrent();
- if (SPACE_STATE_PHANTOM == spaceState && !currentSettings.isWordConnector(primaryCode)) {
+ if (SpaceState.PHANTOM == spaceState && !currentSettings.isWordConnector(primaryCode)) {
if (isComposingWord) {
// Sanity check
throw new RuntimeException("Should not be composing here");
@@ -2256,7 +2130,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (swapWeakSpace) {
swapSwapperAndSpace();
- mInputLogic.mSpaceState = SPACE_STATE_WEAK;
+ mInputLogic.mSpaceState = SpaceState.WEAK;
}
// In case the "add to dictionary" hint was still displayed.
if (null != mSuggestionStripView) mSuggestionStripView.dismissAddToDictionaryHint();
@@ -2267,7 +2141,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void handleRecapitalize() {
+ // TODO[IL]: Move this to InputLogic and rename to processRecapitalize.
+ public void handleRecapitalize() {
if (mInputLogic.mLastSelectionStart == mInputLogic.mLastSelectionEnd) {
return; // No selection
}
@@ -2342,7 +2217,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final boolean swapWeakSpace = maybeStripSpace(primaryCode, spaceState,
Constants.SUGGESTION_STRIP_COORDINATE == x);
- if (SPACE_STATE_PHANTOM == spaceState &&
+ if (SpaceState.PHANTOM == spaceState &&
currentSettings.isUsuallyPrecededBySpace(primaryCode)) {
promotePhantomSpace();
}
@@ -2358,9 +2233,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (Constants.CODE_SPACE == primaryCode) {
if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
if (maybeDoubleSpacePeriod()) {
- mInputLogic.mSpaceState = SPACE_STATE_DOUBLE;
+ mInputLogic.mSpaceState = SpaceState.DOUBLE;
} else if (!isShowingPunctuationList()) {
- mInputLogic.mSpaceState = SPACE_STATE_WEAK;
+ mInputLogic.mSpaceState = SpaceState.WEAK;
}
}
@@ -2369,8 +2244,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
if (swapWeakSpace) {
swapSwapperAndSpace();
- mInputLogic.mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
- } else if (SPACE_STATE_PHANTOM == spaceState
+ mInputLogic.mSpaceState = SpaceState.SWAP_PUNCTUATION;
+ } else if (SpaceState.PHANTOM == spaceState
&& currentSettings.isUsuallyFollowedBySpace(primaryCode)) {
// If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the
@@ -2382,7 +2257,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// separator does not normally need a space on the right (that's the difference
// between swappers and strippers), so we should not stay in phantom space state if
// the separator is a stripper. Hence the additional test above.
- mInputLogic.mSpaceState = SPACE_STATE_PHANTOM;
+ mInputLogic.mSpaceState = SpaceState.PHANTOM;
}
// Set punctuation right away. onUpdateSelection will fire but tests whether it is
@@ -2710,7 +2585,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.mConnection.beginBatchEdit();
final SettingsValues currentSettings = mSettings.getCurrent();
- if (SPACE_STATE_PHANTOM == mInputLogic.mSpaceState && suggestion.length() > 0
+ if (SpaceState.PHANTOM == mInputLogic.mSpaceState && suggestion.length() > 0
// In the batch input mode, a manually picked suggested word should just replace
// the current batch input text and there is no need for a phantom space.
&& !mInputLogic.mWordComposer.isBatchMode()) {
@@ -2751,7 +2626,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Don't allow cancellation of manual pick
mInputLogic.mLastComposedWord.deactivate();
// Space state must be updated before calling updateShiftState
- mInputLogic.mSpaceState = SPACE_STATE_PHANTOM;
+ mInputLogic.mSpaceState = SpaceState.PHANTOM;
mKeyboardSwitcher.updateShiftState();
// We should show the "Touch again to save" hint if the user pressed the first entry
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();
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/SpaceState.java b/java/src/com/android/inputmethod/latin/inputlogic/SpaceState.java
new file mode 100644
index 000000000..ce80c0016
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/inputlogic/SpaceState.java
@@ -0,0 +1,54 @@
+/*
+ * 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.inputlogic;
+
+/**
+ * Class for managing space states.
+ *
+ * At any given time, the input logic is in one of five possible space states. Depending on the
+ * current space state, some behavior will change; the prime example of this is the PHANTOM state,
+ * in which any subsequent letter input will input a space before the letter. Read on the
+ * description inside this class for each of the space states.
+ */
+public class SpaceState {
+ // None: the state where all the keyboard behavior is the most "standard" and no automatic
+ // input is added or removed. In this state, all self-inserting keys only insert themselves,
+ // and backspace removes one character.
+ public static final int NONE = 0;
+ // Double space: the state where the user pressed space twice quickly, which LatinIME
+ // resolved as period-space. In this state, pressing backspace will undo the
+ // double-space-to-period insertion: it will replace ". " with " ".
+ public static final int DOUBLE = 1;
+ // Swap punctuation: the state where a weak space and a punctuation from the suggestion strip
+ // have just been swapped. In this state, pressing backspace will undo the swap: the
+ // characters will be swapped back back, and the space state will go to WEAK.
+ public static final int SWAP_PUNCTUATION = 2;
+ // Weak space: a space that should be swapped only by suggestion strip punctuation. Weak
+ // spaces happen when the user presses space, accepting the current suggestion (whether
+ // it's an auto-correction or not). In this state, pressing a punctuation from the suggestion
+ // strip inserts it before the space (while it inserts it after the space in the NONE state).
+ public static final int WEAK = 3;
+ // Phantom space: a not-yet-inserted space that should get inserted on the next input,
+ // character provided it's not a separator. If it's a separator, the phantom space is dropped.
+ // Phantom spaces happen when a user chooses a word from the suggestion strip. In this state,
+ // non-separators insert a space before they get inserted.
+ public static final int PHANTOM = 4;
+
+ private SpaceState() {
+ // This class is not publicly instantiable.
+ }
+}