aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/LatinIME.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java177
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;
}