diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 177 |
1 files changed, 101 insertions, 76 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 8aaa0692f..1cb79e707 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -187,7 +187,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private View mKeyPreviewBackingView; private View mSuggestionsContainer; private SuggestionsView mSuggestionsView; - private Suggest mSuggest; + /* package for tests */ Suggest mSuggest; private CompletionInfo[] mApplicationSpecifiedCompletions; private InputMethodManagerCompatWrapper mImm; @@ -1225,12 +1225,41 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return mOptionsDialog != null && mOptionsDialog.isShowing(); } - private void insertPunctuationFromSuggestionStrip(final InputConnection ic, final int code) { + private void insertPunctuationFromSuggestionStrip(final int code) { onCodeInput(code, new int[] { code }, KeyboardActionListener.SUGGESTION_STRIP_COORDINATE, KeyboardActionListener.SUGGESTION_STRIP_COORDINATE); } + private static int getEditorActionId(EditorInfo editorInfo) { + if (editorInfo == null) return 0; + return (editorInfo.actionLabel != null) + ? editorInfo.actionId + : (editorInfo.imeOptions & EditorInfo.IME_MASK_ACTION); + } + + private void performeEditorAction(int actionId) { + final InputConnection ic = getCurrentInputConnection(); + if (ic != null) { + ic.performEditorAction(actionId); + } + } + + private void sendKeyCodePoint(int code) { + // TODO: Remove this special handling of digit letters. + // For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}. + if (code >= '0' && code <= '9') { + super.sendKeyChar((char)code); + return; + } + + final InputConnection ic = getCurrentInputConnection(); + if (ic != null) { + final String text = new String(new int[] { code }, 0, 1); + ic.commitText(text, text.length()); + } + } + // Implementation of {@link KeyboardActionListener}. @Override public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { @@ -1271,6 +1300,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar case Keyboard.CODE_SHORTCUT: mSubtypeSwitcher.switchToShortcutIME(); break; + case Keyboard.CODE_ACTION_ENTER: + performeEditorAction(getEditorActionId(getCurrentInputEditorInfo())); + break; case Keyboard.CODE_TAB: handleTab(); // There are two cases for tab. Either we send a "next" event, that may change the @@ -1308,7 +1340,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar commitTyped(ic); text = specificTldProcessingOnTextInput(ic, text); if (SPACE_STATE_PHANTOM == mSpaceState) { - sendKeyChar((char)Keyboard.CODE_SPACE); + sendKeyCodePoint(Keyboard.CODE_SPACE); } ic.commitText(text, 1); ic.endBatchEdit(); @@ -1327,10 +1359,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Not a tld: do nothing. return text; } + // We have a TLD (or something that looks like this): make sure we don't add + // a space even if currently in phantom mode. + mSpaceState = SPACE_STATE_NONE; final CharSequence lastOne = ic.getTextBeforeCursor(1, 0); if (lastOne != null && lastOne.length() == 1 && lastOne.charAt(0) == Keyboard.CODE_PERIOD) { - mSpaceState = SPACE_STATE_NONE; return text.subSequence(1, text.length()); } else { return text; @@ -1399,7 +1433,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } if (SPACE_STATE_DOUBLE == spaceState) { - if (revertDoubleSpace(ic)) { + if (revertDoubleSpaceWhileInBatchEdit(ic)) { // No need to reset mSpaceState, it has already be done (that's why we // receive it as a parameter) return; @@ -1453,10 +1487,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } + // TODO: Implement next and previous actions using other key code than tab's code. private void handleTab() { final int imeOptions = getCurrentInputEditorInfo().imeOptions; if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) && !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) { + // TODO: This should be {@link #sendKeyCodePoint(int)}. sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); return; } @@ -1475,6 +1511,28 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } + // ic may be null + private boolean maybeStripSpaceWhileInBatchEdit(final InputConnection ic, final int code, + final int spaceState, final boolean isFromSuggestionStrip) { + if (Keyboard.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) { + removeTrailingSpaceWhileInBatchEdit(ic); + return false; + } else if ((SPACE_STATE_WEAK == spaceState + || SPACE_STATE_SWAP_PUNCTUATION == spaceState) + && isFromSuggestionStrip) { + if (mSettingsValues.isMagicSpaceSwapper(code)) { + return true; + } else { + if (mSettingsValues.isMagicSpaceStripper(code)) { + removeTrailingSpaceWhileInBatchEdit(ic); + } + return false; + } + } else { + return false; + } + } + private void handleCharacter(final int primaryCode, final int[] keyCodes, final int x, final int y, final int spaceState) { mVoiceProxy.handleCharacter(); @@ -1489,7 +1547,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private void handleCharacterWhileInBatchEdit(final int primaryCode, final int[] keyCodes, final int x, final int y, final int spaceState, final InputConnection ic) { boolean isComposingWord = mWordComposer.isComposingWord(); - int code = primaryCode; if (SPACE_STATE_PHANTOM == spaceState && !mSettingsValues.isSymbolExcludedFromWordSeparators(primaryCode)) { @@ -1497,17 +1554,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Sanity check throw new RuntimeException("Should not be composing here"); } - sendKeyChar((char)Keyboard.CODE_SPACE); + sendKeyCodePoint(Keyboard.CODE_SPACE); } - if ((isAlphabet(code) || mSettingsValues.isSymbolExcludedFromWordSeparators(code)) + if ((isAlphabet(primaryCode) + || mSettingsValues.isSymbolExcludedFromWordSeparators(primaryCode)) && isSuggestionsRequested() && !isCursorTouchingWord()) { if (!isComposingWord) { // Reset entirely the composing state anyway, then start composing a new word unless // the character is a single quote. The idea here is, single quote is not a // separator and it should be treated as a normal character, except in the first // position where it should not start composing a word. - isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != code); + isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != primaryCode); // Here we don't need to reset the last composed word. It will be reset // when we commit this one, if we ever do; if on the other hand we backspace // it entirely and resume suggestions on the previous word, we'd like to still @@ -1518,7 +1576,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } if (isComposingWord) { - mWordComposer.add(code, keyCodes, x, y); + mWordComposer.add(primaryCode, keyCodes, x, y); if (ic != null) { // If it's the first letter, make note of auto-caps state if (mWordComposer.size() == 1) { @@ -1529,14 +1587,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } mHandler.postUpdateSuggestions(); } else { - sendKeyChar((char)code); - } + final boolean swapWeakSpace = maybeStripSpaceWhileInBatchEdit(ic, primaryCode, + spaceState, KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x); - if (mSettingsValues.isWordSeparator(code)) { - Utils.Stats.onSeparator((char)code, x, y); - } else { - Utils.Stats.onNonSeparator((char)code, x, y); + sendKeyCodePoint(primaryCode); + + if (swapWeakSpace) { + swapSwapperAndSpaceWhileInBatchEdit(ic); + mSpaceState = SPACE_STATE_WEAK; + } } + Utils.Stats.onNonSeparator((char)primaryCode, x, y); } // Returns true if we did an autocorrection, false otherwise. @@ -1572,29 +1633,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - final boolean swapWeakSpace; - if (Keyboard.CODE_ENTER == primaryCode && SPACE_STATE_SWAP_PUNCTUATION == spaceState) { - removeTrailingSpaceWhileInBatchEdit(ic); - swapWeakSpace = false; - } else if ((SPACE_STATE_WEAK == spaceState || SPACE_STATE_SWAP_PUNCTUATION == spaceState) - && KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x) { - if (mSettingsValues.isMagicSpaceSwapper(primaryCode)) { - swapWeakSpace = true; - } else { - swapWeakSpace = false; - if (mSettingsValues.isMagicSpaceStripper(primaryCode)) { - removeTrailingSpaceWhileInBatchEdit(ic); - } - } - } else { - swapWeakSpace = false; - } + final boolean swapWeakSpace = maybeStripSpaceWhileInBatchEdit(ic, primaryCode, spaceState, + KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x); - // TODO: rethink interactions of sendKeyChar, commitText("\n") and actions. sendKeyChar - // with a CODE_ENTER parameter will have the default InputMethodService implementation - // possibly redirect on the keyboard action. That may be the right thing to do, but - // on Shift+Enter, it's generally not, so we may want to do the redirection right here. - sendKeyChar((char)primaryCode); + sendKeyCodePoint(primaryCode); if (Keyboard.CODE_SPACE == primaryCode) { if (isSuggestionsRequested()) { @@ -1613,7 +1655,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } else { if (swapWeakSpace) { swapSwapperAndSpaceWhileInBatchEdit(ic); - mSpaceState = SPACE_STATE_WEAK; + mSpaceState = SPACE_STATE_SWAP_PUNCTUATION; } else if (SPACE_STATE_PHANTOM == spaceState) { // 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 @@ -1869,52 +1911,40 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } @Override - public void pickSuggestionManually(int index, CharSequence suggestion) { + public void pickSuggestionManually(final int index, final CharSequence suggestion) { mComposingStateManager.onFinishComposingText(); - SuggestedWords suggestions = mSuggestionsView.getSuggestions(); + final SuggestedWords suggestions = mSuggestionsView.getSuggestions(); mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, mSettingsValues.mWordSeparators); - final InputConnection ic = getCurrentInputConnection(); - if (ic != null) { - ic.beginBatchEdit(); - } if (mInputAttributes.mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null && index >= 0 && index < mApplicationSpecifiedCompletions.length) { - if (ic != null) { - final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index]; - ic.commitCompletion(completionInfo); - } if (mSuggestionsView != null) { mSuggestionsView.clear(); } mKeyboardSwitcher.updateShiftState(); + final InputConnection ic = getCurrentInputConnection(); if (ic != null) { + ic.beginBatchEdit(); + final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index]; + ic.commitCompletion(completionInfo); ic.endBatchEdit(); } return; } - // If this is a punctuation, apply it through the normal key press - if (suggestion.length() == 1 && (mSettingsValues.isWordSeparator(suggestion.charAt(0)) - || mSettingsValues.isSuggestedPunctuation(suggestion.charAt(0)))) { + // If this is a punctuation picked from the suggestion strip, pass it to onCodeInput + if (suggestion.length() == 1 && isShowingPunctuationList()) { // Word separators are suggested before the user inputs something. // So, LatinImeLogger logs "" as a user's input. LatinImeLogger.logOnManualSuggestion( "", suggestion.toString(), index, suggestions.mWords); - final CharSequence outputText = mSettingsValues.mSuggestPuncOutputTextList - .getWord(index); - final int primaryCode = outputText.charAt(0); - // Find out whether the previous character is a space. If it is, as a special case - // for punctuation entered through the suggestion strip, it should be swapped - // if it was a magic or a weak space. This is meant to help in case the user - // pressed space on purpose of displaying the suggestion strip punctuation. - insertPunctuationFromSuggestionStrip(ic, primaryCode); - // TODO: the following endBatchEdit seems useless, check - if (ic != null) { - ic.endBatchEdit(); - } + // Rely on onCodeInput to do the complicated swapping/stripping logic consistently. + final int primaryCode = suggestion.charAt(0); + onCodeInput(primaryCode, new int[] { primaryCode }, + KeyboardActionListener.SUGGESTION_STRIP_COORDINATE, + KeyboardActionListener.SUGGESTION_STRIP_COORDINATE); return; } // We need to log before we commit, because the word composer will store away the user @@ -1967,9 +1997,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.postUpdateSuggestions(); } } - if (ic != null) { - ic.endBatchEdit(); - } } /** @@ -2081,21 +2108,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar CharSequence toLeft = ic.getTextBeforeCursor(1, 0); CharSequence toRight = ic.getTextAfterCursor(1, 0); if (!TextUtils.isEmpty(toLeft) - && !mSettingsValues.isWordSeparator(toLeft.charAt(0)) - && !mSettingsValues.isSuggestedPunctuation(toLeft.charAt(0))) { + && !mSettingsValues.isWordSeparator(toLeft.charAt(0))) { return true; } if (!TextUtils.isEmpty(toRight) - && !mSettingsValues.isWordSeparator(toRight.charAt(0)) - && !mSettingsValues.isSuggestedPunctuation(toRight.charAt(0))) { + && !mSettingsValues.isWordSeparator(toRight.charAt(0))) { return true; } return false; } // "ic" must not be null - private static boolean sameAsTextBeforeCursor(final InputConnection ic, CharSequence text) { - CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); + private static boolean sameAsTextBeforeCursor(final InputConnection ic, + final CharSequence text) { + final CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); return TextUtils.equals(text, beforeText); } @@ -2212,13 +2238,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } ic.deleteSurroundingText(restartLength, 0); + mComposingStateManager.onStartComposingText(); ic.setComposingText(mWordComposer.getTypedWord(), 1); mHandler.cancelUpdateBigramPredictions(); mHandler.postUpdateSuggestions(); } // "ic" must not be null - private boolean revertDoubleSpace(final InputConnection ic) { + private boolean revertDoubleSpaceWhileInBatchEdit(final InputConnection ic) { mHandler.cancelDoubleSpacesTimer(); // Here we test whether we indeed have a period and a space before us. This should not // be needed, but it's there just in case something went wrong. @@ -2231,10 +2258,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar + "\". \" just before the cursor."); return false; } - ic.beginBatchEdit(); ic.deleteSurroundingText(2, 0); ic.commitText(" ", 1); - ic.endBatchEdit(); return true; } |