aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java7
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java70
-rw-r--r--java/src/com/android/inputmethod/latin/InputAttributes.java14
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java137
4 files changed, 119 insertions, 109 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index dce2c37f2..6e13b95b5 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -48,14 +48,17 @@ public interface KeyboardActionListener {
* presses of a key adjacent to the intended key.
* @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
* {@link PointerTracker#onTouchEvent} or so, the value should be
- * {@link #NOT_A_TOUCH_COORDINATE}.
+ * {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
+ * strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
* @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
* {@link PointerTracker#onTouchEvent} or so, the value should be
- * {@link #NOT_A_TOUCH_COORDINATE}.
+ * {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
+ * strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
*/
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y);
public static final int NOT_A_TOUCH_COORDINATE = -1;
+ public static final int SUGGESTION_STRIP_COORDINATE = -2;
/**
* Sends a sequence of characters to the listener.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index adb5f4759..e3c5da456 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -43,6 +43,8 @@ import java.util.Arrays;
public class KeySpecParser {
private static final boolean DEBUG = LatinImeLogger.sDBG;
+ private static final int MAX_STRING_REFERENCE_INDIRECTION = 10;
+
// Constants for parsing.
private static int COMMA = ',';
private static final char ESCAPE_CHAR = '\\';
@@ -274,35 +276,51 @@ public class KeySpecParser {
return resId;
}
- private static String resolveStringResource(String text, Resources res, int packageNameResId) {
- final int size = text.length();
- if (size < PREFIX_STRING.length()) {
- return text;
- }
+ private static String resolveStringResource(String rawText, Resources res,
+ int packageNameResId) {
+ int level = 0;
+ String text = rawText;
+ StringBuilder sb;
+ do {
+ level++;
+ if (level >= MAX_STRING_REFERENCE_INDIRECTION) {
+ throw new RuntimeException("too many @string/resource indirection: " + text);
+ }
- StringBuilder sb = null;
- for (int pos = 0; pos < size; pos++) {
- final char c = text.charAt(pos);
- if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) {
- if (sb == null) {
- sb = new StringBuilder(text.substring(0, pos));
- }
- final int end = searchResourceNameEnd(text, pos + PREFIX_STRING.length());
- final String resName = text.substring(pos + 1, end);
- final int resId = getResourceId(res, resName, packageNameResId);
- sb.append(res.getString(resId));
- pos = end - 1;
- } else if (c == ESCAPE_CHAR) {
- if (sb != null) {
- // Append both escape character and escaped character.
- sb.append(text.substring(pos, Math.min(pos + 2, size)));
+ final int size = text.length();
+ if (size < PREFIX_STRING.length()) {
+ return text;
+ }
+
+ sb = null;
+ for (int pos = 0; pos < size; pos++) {
+ final char c = text.charAt(pos);
+ if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) {
+ if (sb == null) {
+ sb = new StringBuilder(text.substring(0, pos));
+ }
+ final int end = searchResourceNameEnd(text, pos + PREFIX_STRING.length());
+ final String resName = text.substring(pos + 1, end);
+ final int resId = getResourceId(res, resName, packageNameResId);
+ sb.append(res.getString(resId));
+ pos = end - 1;
+ } else if (c == ESCAPE_CHAR) {
+ if (sb != null) {
+ // Append both escape character and escaped character.
+ sb.append(text.substring(pos, Math.min(pos + 2, size)));
+ }
+ pos++;
+ } else if (sb != null) {
+ sb.append(c);
}
- pos++;
- } else if (sb != null) {
- sb.append(c);
}
- }
- return (sb == null) ? text : sb.toString();
+
+ if (sb != null) {
+ text = sb.toString();
+ }
+ } while (sb != null);
+
+ return text;
}
private static int searchResourceNameEnd(String text, int start) {
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index f5cf953c4..3de5c1d48 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -28,7 +28,6 @@ import com.android.inputmethod.compat.InputTypeCompatUtils;
public class InputAttributes {
private final String TAG = InputAttributes.class.getSimpleName();
- final public boolean mInsertSpaceOnPickSuggestionManually;
final public boolean mInputTypeNoAutoCorrect;
final public boolean mIsSettingsSuggestionStripOn;
final public boolean mApplicationSpecifiedCompletionOn;
@@ -52,7 +51,6 @@ public class InputAttributes {
+ " imeOptions=0x%08x",
inputType, editorInfo.imeOptions));
}
- mInsertSpaceOnPickSuggestionManually = false;
mIsSettingsSuggestionStripOn = false;
mInputTypeNoAutoCorrect = false;
mApplicationSpecifiedCompletionOn = false;
@@ -80,15 +78,6 @@ public class InputAttributes {
mIsSettingsSuggestionStripOn = true;
}
- if (InputTypeCompatUtils.isEmailVariation(variation)
- || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
- // The point in turning this off is that we don't want to insert a space after
- // a name when filling a form: we can't delete trailing spaces when changing fields
- mInsertSpaceOnPickSuggestionManually = false;
- } else {
- mInsertSpaceOnPickSuggestionManually = true;
- }
-
// If it's a browser edit field and auto correct is not ON explicitly, then
// disable auto correction, but keep suggestions on.
// If NO_SUGGESTIONS is set, don't do prediction.
@@ -109,8 +98,7 @@ public class InputAttributes {
// Pretty print
@Override
public String toString() {
- return "\n mInsertSpaceOnPickSuggestionManually = " + mInsertSpaceOnPickSuggestionManually
- + "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect
+ return "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect
+ "\n mIsSettingsSuggestionStripOn = " + mIsSettingsSuggestionStripOn
+ "\n mApplicationSpecifiedCompletionOn = " + mApplicationSpecifiedCompletionOn;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1bc55a583..24007f95a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -160,18 +160,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
SUGGESTION_VISIBILILTY_HIDE_VALUE
};
- // Magic space: a space that should disappear on space/apostrophe insertion, move after the
- // punctuation on punctuation insertion, and become a real space on alpha char insertion.
- // Weak space: a space that should be swapped only by suggestion strip punctuation.
+ 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 or magic) space and a punctuation from the
// suggestion strip have just been swapped. Undoing this swaps them back.
- private static final int SPACE_STATE_NONE = 0;
- private static final int SPACE_STATE_DOUBLE = 1;
private static final int SPACE_STATE_SWAP_PUNCTUATION = 2;
- private static final int SPACE_STATE_MAGIC = 3;
- private static final int SPACE_STATE_WEAK = 4;
+ // 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;
// Current space state of the input method. This can be any of the above constants.
private int mSpaceState;
@@ -1162,18 +1165,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return false;
}
- // "ic" must not be null
- private static void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) {
- // When the text's first character is '.', remove the previous period
- // if there is one.
- final CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
- if (lastOne != null && lastOne.length() == 1
- && lastOne.charAt(0) == Keyboard.CODE_PERIOD
- && text.charAt(0) == Keyboard.CODE_PERIOD) {
- ic.deleteSurroundingText(1, 0);
- }
- }
-
// "ic" may be null
private static void removeTrailingSpaceWhileInBatchEdit(final InputConnection ic) {
if (ic == null) return;
@@ -1234,26 +1225,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
private void insertPunctuationFromSuggestionStrip(final InputConnection ic, final int code) {
- final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : null;
- final int toLeft = TextUtils.isEmpty(beforeText) ? 0 : beforeText.charAt(0);
- final boolean shouldRegisterSwapPunctuation;
- // If we have a space left of the cursor and it's a weak or a magic space, then we should
- // swap it, and override the space state with SPACESTATE_SWAP_PUNCTUATION.
- // To swap it, we fool handleSeparator to think the previous space state was a
- // magic space.
- if (Keyboard.CODE_SPACE == toLeft && mSpaceState == SPACE_STATE_WEAK
- && mSettingsValues.isMagicSpaceSwapper(code)) {
- mSpaceState = SPACE_STATE_MAGIC;
- shouldRegisterSwapPunctuation = true;
- } else {
- shouldRegisterSwapPunctuation = false;
- }
onCodeInput(code, new int[] { code },
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
- if (shouldRegisterSwapPunctuation) {
- mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
- }
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
}
// Implementation of {@link KeyboardActionListener}.
@@ -1331,7 +1305,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ic == null) return;
ic.beginBatchEdit();
commitTyped(ic);
- maybeRemovePreviousPeriod(ic, text);
+ text = specificTldProcessingOnTextInput(ic, text);
+ if (SPACE_STATE_PHANTOM == mSpaceState) {
+ sendKeyChar((char)Keyboard.CODE_SPACE);
+ }
ic.commitText(text, 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
@@ -1341,6 +1318,24 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
resetComposingState(true /* alsoResetLastComposedWord */);
}
+ // ic may not be null
+ private CharSequence specificTldProcessingOnTextInput(final InputConnection ic,
+ final CharSequence text) {
+ if (text.length() <= 1 || text.charAt(0) != Keyboard.CODE_PERIOD
+ || !Character.isLetter(text.charAt(1))) {
+ // Not a tld: do nothing.
+ return text;
+ }
+ 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;
+ }
+ }
+
@Override
public void onCancelInput() {
// User released a finger outside any key
@@ -1492,13 +1487,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// "ic" may be null without this crashing, but the behavior will be really strange
private void handleCharacterWhileInBatchEdit(final int primaryCode, final int[] keyCodes,
final int x, final int y, final int spaceState, final InputConnection ic) {
- if (SPACE_STATE_MAGIC == spaceState
- && mSettingsValues.isMagicSpaceStripper(primaryCode)) {
- if (null != ic) removeTrailingSpaceWhileInBatchEdit(ic);
- }
-
boolean isComposingWord = mWordComposer.isComposingWord();
int code = primaryCode;
+
+ if (SPACE_STATE_PHANTOM == spaceState &&
+ !mSettingsValues.isSymbolExcludedFromWordSeparators(primaryCode)) {
+ if (isComposingWord) {
+ // Sanity check
+ throw new RuntimeException("Should not be composing here");
+ }
+ sendKeyChar((char)Keyboard.CODE_SPACE);
+ }
+
if ((isAlphabet(code) || mSettingsValues.isSymbolExcludedFromWordSeparators(code))
&& isSuggestionsRequested() && !isCursorTouchingWord()) {
if (!isComposingWord) {
@@ -1530,10 +1530,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else {
sendKeyChar((char)code);
}
- if (SPACE_STATE_MAGIC == spaceState
- && mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
- if (null != ic) swapSwapperAndSpaceWhileInBatchEdit(ic);
- }
if (mSettingsValues.isWordSeparator(code)) {
Utils.Stats.onSeparator((char)code, x, y);
@@ -1575,24 +1571,28 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
- final boolean swapMagicSpace;
- if (Keyboard.CODE_ENTER == primaryCode && (SPACE_STATE_MAGIC == spaceState
- || SPACE_STATE_SWAP_PUNCTUATION == spaceState)) {
+ final boolean swapWeakSpace;
+ if (Keyboard.CODE_ENTER == primaryCode && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
removeTrailingSpaceWhileInBatchEdit(ic);
- swapMagicSpace = false;
- } else if (SPACE_STATE_MAGIC == spaceState) {
+ swapWeakSpace = false;
+ } else if ((SPACE_STATE_WEAK == spaceState || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
+ && KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x) {
if (mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
- swapMagicSpace = true;
+ swapWeakSpace = true;
} else {
- swapMagicSpace = false;
+ swapWeakSpace = false;
if (mSettingsValues.isMagicSpaceStripper(primaryCode)) {
removeTrailingSpaceWhileInBatchEdit(ic);
}
}
} else {
- swapMagicSpace = false;
+ swapWeakSpace = false;
}
+ // 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);
if (Keyboard.CODE_SPACE == primaryCode) {
@@ -1610,9 +1610,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHandler.postUpdateBigramPredictions();
}
} else {
- if (swapMagicSpace) {
+ if (swapWeakSpace) {
swapSwapperAndSpaceWhileInBatchEdit(ic);
- mSpaceState = SPACE_STATE_MAGIC;
+ mSpaceState = SPACE_STATE_WEAK;
+ } 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
+ // 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.
+ mSpaceState = SPACE_STATE_PHANTOM;
}
// Set punctuation right away. onUpdateSelection will fire but tests whether it is
@@ -1921,10 +1929,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else {
addToOnlyBigramDictionary(suggestion, 1);
}
- // Follow it with a space
- if (mInputAttributes.mInsertSpaceOnPickSuggestionManually) {
- sendMagicSpace();
- }
+ mSpaceState = SPACE_STATE_PHANTOM;
+ // TODO: is this necessary?
+ mKeyboardSwitcher.updateShiftState();
// We should show the "Touch again to save" hint if the user pressed the first entry
// AND either:
@@ -2259,12 +2266,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return mSettingsValues.isWordSeparator(code);
}
- private void sendMagicSpace() {
- sendKeyChar((char)Keyboard.CODE_SPACE);
- mSpaceState = SPACE_STATE_MAGIC;
- mKeyboardSwitcher.updateShiftState();
- }
-
public boolean preferCapitalization() {
return mWordComposer.isFirstCharCapitalized();
}