diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/inputlogic')
-rw-r--r-- | java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java | 118 |
1 files changed, 92 insertions, 26 deletions
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 6e9bdc34a..43d75330d 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -36,14 +36,12 @@ 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.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.define.ProductionFlag; -import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.AsyncResultHolder; @@ -181,6 +179,67 @@ public final class InputLogic { } /** + * Consider an update to the cursor position. Evaluate whether this update has happened as + * part of normal typing or whether it was an explicit cursor move by the user. In any case, + * do the necessary adjustments. + * @param settingsValues the current settings + * @param oldSelStart old selection start + * @param oldSelEnd old selection end + * @param newSelStart new selection start + * @param newSelEnd new selection end + * @param composingSpanStart composing span start + * @param composingSpanEnd composing span end + * @return whether the cursor has moved as a result of user interaction. + */ + public boolean onUpdateSelection(final SettingsValues settingsValues, + final int oldSelStart, final int oldSelEnd, + final int newSelStart, final int newSelEnd, + final int composingSpanStart, final int composingSpanEnd) { + if (mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart, oldSelEnd, newSelEnd)) { + return false; + } + // TODO: the following is probably better done in resetEntireInputState(). + // it should only happen when the cursor moved, and the very purpose of the + // test below is to narrow down whether this happened or not. Likewise with + // 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. + mSpaceState = SpaceState.NONE; + + final boolean selectionChangedOrSafeToReset = + oldSelStart != newSelStart || oldSelEnd != newSelEnd // selection changed + || !mWordComposer.isComposingWord(); // safe to reset + final boolean hasOrHadSelection = (oldSelStart != oldSelEnd || newSelStart != newSelEnd); + final int moveAmount = newSelStart - oldSelStart; + if (selectionChangedOrSafeToReset && (hasOrHadSelection + || !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) { + // If we are composing a word and moving the cursor, we would want to set a + // suggestion span for recorrection to work correctly. Unfortunately, that + // would involve the keyboard committing some new text, which would move the + // cursor back to where it was. Latin IME could then fix the position of the cursor + // again, but the asynchronous nature of the calls results in this wreaking havoc + // with selection on double tap and the like. + // Another option would be to send suggestions each time we set the composing + // text, but that is probably too expensive to do, so we decided to leave things + // as is. + resetEntireInputState(settingsValues, newSelStart, newSelEnd); + } else { + // resetEntireInputState calls resetCachesUponCursorMove, but forcing the + // composition to end. But in all cases where we don't reset the entire input + // state, we still want to tell the rich input connection about the new cursor + // position so that it can update its caches. + mConnection.resetCachesUponCursorMoveAndReturnSuccess( + newSelStart, newSelEnd, false /* shouldFinishComposition */); + } + + // We moved the cursor. If we are touching a word, we need to resume suggestion. + mLatinIME.mHandler.postResumeSuggestions(); + // Reset the last recapitalization. + mRecapitalizeStatus.deactivate(); + return true; + } + + /** * React to a code input. It may be a code point to insert, or a symbolic value that influences * the keyboard behavior. * @@ -192,13 +251,12 @@ public final class InputLogic { * @param y the y-coordinate where the user pressed the key, or NOT_A_COORDINATE. */ public void onCodeInput(final int code, final int x, final int y, - // TODO: remove these three arguments - final LatinIME.UIHandler handler, - final KeyboardSwitcher keyboardSwitcher, final SubtypeSwitcher subtypeSwitcher) { + final SettingsValues settingsValues, + // TODO: remove these two arguments + final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.latinIME_onCodeInput(code, x, y); } - final SettingsValues settingsValues = Settings.getInstance().getCurrent(); final long when = SystemClock.uptimeMillis(); if (code != Constants.CODE_DELETE || when > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) { @@ -247,7 +305,8 @@ public final class InputLogic { onSettingsKeyPressed(); break; case Constants.CODE_SHORTCUT: - subtypeSwitcher.switchToShortcutIME(mLatinIME); + // We need to switch to the shortcut IME. This is handled by LatinIME since the + // input logic has no business with IME switching. break; case Constants.CODE_ACTION_NEXT: performEditorAction(EditorInfo.IME_ACTION_NEXT); @@ -602,8 +661,21 @@ public final class InputLogic { final boolean swapWeakSpace = maybeStripSpace(settingsValues, codePoint, spaceState, isFromSuggestionStrip); - if (SpaceState.PHANTOM == spaceState && - settingsValues.isUsuallyPrecededBySpace(codePoint)) { + final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint + && mConnection.isInsideDoubleQuoteOrAfterDigit(); + + final boolean needsPrecedingSpace; + if (SpaceState.PHANTOM != spaceState) { + needsPrecedingSpace = false; + } else if (Constants.CODE_DOUBLE_QUOTE == codePoint) { + // Double quotes behave like they are usually preceded by space iff we are + // not inside a double quote or after a digit. + needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit; + } else { + needsPrecedingSpace = settingsValues.isUsuallyPrecededBySpace(codePoint); + } + + if (needsPrecedingSpace) { promotePhantomSpace(settingsValues); } if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { @@ -630,14 +702,17 @@ public final class InputLogic { if (swapWeakSpace) { swapSwapperAndSpace(keyboardSwitcher); mSpaceState = SpaceState.SWAP_PUNCTUATION; - } else if (SpaceState.PHANTOM == spaceState - && settingsValues.isUsuallyFollowedBySpace(codePoint)) { + } else if ((SpaceState.PHANTOM == spaceState + && settingsValues.isUsuallyFollowedBySpace(codePoint)) + || (Constants.CODE_DOUBLE_QUOTE == codePoint + && isInsideDoubleQuoteOrAfterDigit)) { // 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 // space. For example, if I type "Good dat", pick "day" from the suggestion strip // then insert a comma and go on to typing the next word, I want the space to be // inserted automatically before the next word, the same way it is when I don't - // input the comma. + // input the comma. A double quote behaves like it's usually followed by space if + // we're inside a double quote. // The case is a little different if the separator is a space stripper. Such a // 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 @@ -647,7 +722,7 @@ public final class InputLogic { // Set punctuation right away. onUpdateSelection will fire but tests whether it is // already displayed or not, so it's okay. - mLatinIME.setPunctuationSuggestions(); + mLatinIME.setNeutralSuggestionStrip(); } keyboardSwitcher.updateShiftState(); @@ -1000,7 +1075,7 @@ public final class InputLogic { } if (!mWordComposer.isComposingWord() && !settingsValues.mBigramPredictionEnabled) { - mLatinIME.setPunctuationSuggestions(); + mLatinIME.setNeutralSuggestionStrip(); return; } @@ -1256,15 +1331,10 @@ public final class InputLogic { * This is called from the KeyboardSwitcher (through a trampoline in LatinIME) because it * needs to know auto caps state to display the right layout. * - * @param optionalSettingsValues settings values, or null if we should just get the current ones - * from the singleton. + * @param settingsValues the relevant settings values * @return a caps mode from TextUtils.CAP_MODE_* or Constants.TextUtils.CAP_MODE_OFF. */ - public int getCurrentAutoCapsState(final SettingsValues optionalSettingsValues) { - // If we are in a batch edit, we need to use the same settings values as the outside - // code, that will pass it to us. Otherwise, we can just take the current values. - final SettingsValues settingsValues = null != optionalSettingsValues - ? optionalSettingsValues : Settings.getInstance().getCurrent(); + public int getCurrentAutoCapsState(final SettingsValues settingsValues) { if (!settingsValues.mAutoCap) return Constants.TextUtils.CAP_MODE_OFF; final EditorInfo ei = getCurrentInputEditorInfo(); @@ -1390,11 +1460,7 @@ public final class InputLogic { final int newSelStart, final int newSelEnd) { final boolean shouldFinishComposition = mWordComposer.isComposingWord(); resetComposingState(true /* alsoResetLastComposedWord */); - if (settingsValues.mBigramPredictionEnabled) { - mLatinIME.clearSuggestionStrip(); - } else { - mLatinIME.setSuggestedWords(settingsValues.mSpacingAndPunctuations.mSuggestPuncList); - } + mLatinIME.setNeutralSuggestionStrip(); mConnection.resetCachesUponCursorMoveAndReturnSuccess(newSelStart, newSelEnd, shouldFinishComposition); } |