diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index f91b0a3db..a5d590e04 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -355,7 +355,8 @@
-
+
+
diff --git a/java/res/values/donottranslate-more-keys.xml b/java/res/values/donottranslate-more-keys.xml
index f1c2d2bfc..02fd20015 100644
--- a/java/res/values/donottranslate-more-keys.xml
+++ b/java/res/values/donottranslate-more-keys.xml
@@ -118,6 +118,8 @@
\@icon/settingsKey|\@integer/key_settings
,
+ \@string/label_next_key|\@integer/key_action_next
+ \@string/label_previous_key|\@integer/key_action_previous
\?
;
%
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
index c85c02263..7f9e4bda4 100644
--- a/java/res/values/keycodes.xml
+++ b/java/res/values/keycodes.xml
@@ -30,5 +30,7 @@
-5
-6
-7
- -9
+ -8
+ -9
+ -10
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index bb75b1c82..2fa8b3812 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -73,7 +73,7 @@
latin:keyActionFlags="isRepeatable|noKeyPreview"
latin:backgroundType="functional" />
+ latin:keyboardLayout="@xml/key_styles_enter" />
-
+
+
+
+
+
+
+
+
+ latin:keyboardLayout="@xml/key_styles_enter" />
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/res/xml/key_navigation_tab.xml b/java/res/xml/key_navigation_tab.xml
deleted file mode 100644
index c77189fda..000000000
--- a/java/res/xml/key_navigation_tab.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index eabbdb399..f0ea8ce5a 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -27,13 +27,13 @@
latin:clobberSettingsKey="true"
>
@@ -77,7 +77,22 @@
latin:keyActionFlags="isRepeatable|noKeyPreview"
latin:backgroundType="functional" />
+ latin:keyboardLayout="@xml/key_styles_enter" />
+
+
+
+
+
+
+ latin:parentStyle="f1MoreKeysStyle" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ latin:backgroundType="functional"
+ latin:parentStyle="navigateMoreKeysStyle" />
-
-
-
-
diff --git a/java/res/xml/key_styles_enter_tablet.xml b/java/res/xml/key_styles_enter_tablet.xml
deleted file mode 100644
index 702089181..000000000
--- a/java/res/xml/key_styles_enter_tablet.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/res/xml/key_symbols_f1.xml b/java/res/xml/key_symbols_f1.xml
deleted file mode 100644
index ac4031fcc..000000000
--- a/java/res/xml/key_symbols_f1.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/res/xml/row_qwerty4.xml b/java/res/xml/row_qwerty4.xml
index 2f8b82c3a..df9c8fe3f 100644
--- a/java/res/xml/row_qwerty4.xml
+++ b/java/res/xml/row_qwerty4.xml
@@ -24,44 +24,46 @@
+
-
-
-
-
+ latin:keyLabel="/"
+ latin:keyStyle="f1MoreKeysStyle" />
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+ latin:keyLabel="@string/keylabel_for_comma"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:additionalMoreKeys="@string/more_keys_for_comma"
+ latin:keyStyle="f1MoreKeysStyle" />
+
+
+
diff --git a/java/res/xml/row_symbols4.xml b/java/res/xml/row_symbols4.xml
deleted file mode 100644
index ef77bc3cd..000000000
--- a/java/res/xml/row_symbols4.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/res/xml/row_symbols_shift4.xml b/java/res/xml/row_symbols_shift4.xml
deleted file mode 100644
index 632aafc74..000000000
--- a/java/res/xml/row_symbols_shift4.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/res/xml/rows_symbols.xml b/java/res/xml/rows_symbols.xml
index 27f75b564..21f7d1d27 100644
--- a/java/res/xml/rows_symbols.xml
+++ b/java/res/xml/rows_symbols.xml
@@ -128,6 +128,35 @@
latin:keyWidth="fillRight"
latin:visualInsetsLeft="1%p" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/res/xml/rows_symbols_shift.xml b/java/res/xml/rows_symbols_shift.xml
index 3fb821486..a7d0499e1 100644
--- a/java/res/xml/rows_symbols_shift.xml
+++ b/java/res/xml/rows_symbols_shift.xml
@@ -119,6 +119,29 @@
latin:keyWidth="fillRight"
latin:visualInsetsLeft="1%p" />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
index 3247997f6..938388d6c 100644
--- a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
@@ -39,30 +39,30 @@ public class EditorInfoCompatUtils {
private static final Integer OBJ_IME_ACTION_PREVIOUS = (Integer) CompatUtils
.getFieldValue(null, null, FIELD_IME_ACTION_PREVIOUS);
+ // EditorInfo.IME_FLAG_NAVIGATE_NEXT has been introduced since API#11 (Honeycomb).
public static boolean hasFlagNavigateNext(int imeOptions) {
if (OBJ_IME_FLAG_NAVIGATE_NEXT == null)
return false;
return (imeOptions & OBJ_IME_FLAG_NAVIGATE_NEXT) != 0;
}
+ // EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS has been introduced since API#11 (Honeycomb).
public static boolean hasFlagNavigatePrevious(int imeOptions) {
if (OBJ_IME_FLAG_NAVIGATE_PREVIOUS == null)
return false;
return (imeOptions & OBJ_IME_FLAG_NAVIGATE_PREVIOUS) != 0;
}
+ // EditorInfo.IME_FLAG_FORCE_ASCII has been introduced since API#16 (JellyBean).
public static boolean hasFlagForceAscii(int imeOptions) {
if (OBJ_IME_FLAG_FORCE_ASCII == null)
return false;
return (imeOptions & OBJ_IME_FLAG_FORCE_ASCII) != 0;
}
- public static void performEditorActionNext(InputConnection ic) {
- ic.performEditorAction(EditorInfo.IME_ACTION_NEXT);
- }
-
+ // EditorInfo.IME_ACTION_PREVIOUS has been introduced since API#11 (Honeycomb).
public static void performEditorActionPrevious(InputConnection ic) {
- if (OBJ_IME_ACTION_PREVIOUS == null)
+ if (OBJ_IME_ACTION_PREVIOUS == null || ic == null)
return;
ic.performEditorAction(OBJ_IME_ACTION_PREVIOUS);
}
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 60e506914..30ed59e18 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -99,8 +99,10 @@ public class Keyboard {
public static final int CODE_SETTINGS = -5;
public static final int CODE_SHORTCUT = -6;
public static final int CODE_ACTION_ENTER = -7;
+ public static final int CODE_ACTION_NEXT = -8;
+ public static final int CODE_ACTION_PREVIOUS = -9;
// Code value representing the code is not specified.
- public static final int CODE_UNSPECIFIED = -9;
+ public static final int CODE_UNSPECIFIED = -10;
public final KeyboardId mId;
public final int mThemeId;
@@ -381,6 +383,8 @@ public class Keyboard {
case CODE_SETTINGS: return "settings";
case CODE_SHORTCUT: return "shortcut";
case CODE_ACTION_ENTER: return "actionEnter";
+ case CODE_ACTION_NEXT: return "actionNext";
+ case CODE_ACTION_PREVIOUS: return "actionPrevious";
case CODE_UNSPECIFIED: return "unspec";
case CODE_TAB: return "tab";
case CODE_ENTER: return "enter";
@@ -1069,8 +1073,10 @@ public class Keyboard {
KeyboardId.elementIdToName(id.mElementId));
final boolean modeMatched = matchTypedValue(a,
R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
- final boolean navigateActionMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_navigateAction, id.navigateAction());
+ final boolean navigateNextMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_navigateNext, id.navigateNext());
+ final boolean navigatePreviousMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_navigatePrevious, id.navigatePrevious());
final boolean passwordInputMatched = matchBoolean(a,
R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
final boolean clobberSettingsKeyMatched = matchBoolean(a,
@@ -1090,30 +1096,32 @@ public class Keyboard {
final boolean countryCodeMatched = matchString(a,
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
final boolean selected = keyboardSetElementMatched && modeMatched
- && navigateActionMatched && passwordInputMatched
+ && navigateNextMatched && navigatePreviousMatched && passwordInputMatched
&& clobberSettingsKeyMatched && shortcutKeyEnabledMatched
&& hasShortcutKeyMatched && isMultiLineMatched && imeActionMatched
&& localeCodeMatched && languageCodeMatched && countryCodeMatched;
if (DEBUG) {
- startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
+ startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement),
"keyboardSetElement"),
textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
- booleanAttr(a, R.styleable.Keyboard_Case_navigateAction,
- "navigateAction"),
- booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
- "passwordInput"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_imeAction),
+ "imeAction"),
+ booleanAttr(a, R.styleable.Keyboard_Case_navigateNext,
+ "navigateNext"),
+ booleanAttr(a, R.styleable.Keyboard_Case_navigatePrevious,
+ "navigatePrevious"),
booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
"clobberSettingsKey"),
+ booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
+ "passwordInput"),
booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyEnabled,
"shortcutKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey,
"hasShortcutKey"),
booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine,
"isMultiLine"),
- textAttr(a.getString(R.styleable.Keyboard_Case_imeAction),
- "imeAction"),
textAttr(a.getString(R.styleable.Keyboard_Case_localeCode),
"localeCode"),
textAttr(a.getString(R.styleable.Keyboard_Case_languageCode),
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index a75caf262..ed4a89e0f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -87,7 +87,6 @@ public class KeyboardId {
id.mElementId,
id.mMode,
id.mWidth,
- id.navigateAction(),
id.passwordInput(),
id.mClobberSettingsKey,
id.mShortcutKeyEnabled,
@@ -95,6 +94,8 @@ public class KeyboardId {
id.isMultiLine(),
id.imeAction(),
id.mCustomActionLabel,
+ id.navigateNext(),
+ id.navigatePrevious(),
id.mLocale
});
}
@@ -106,7 +107,6 @@ public class KeyboardId {
&& other.mElementId == this.mElementId
&& other.mMode == this.mMode
&& other.mWidth == this.mWidth
- && other.navigateAction() == this.navigateAction()
&& other.passwordInput() == this.passwordInput()
&& other.mClobberSettingsKey == this.mClobberSettingsKey
&& other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
@@ -114,6 +114,8 @@ public class KeyboardId {
&& other.isMultiLine() == this.isMultiLine()
&& other.imeAction() == this.imeAction()
&& TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
+ && other.navigateNext() == this.navigateNext()
+ && other.navigatePrevious() == this.navigatePrevious()
&& other.mLocale.equals(this.mLocale);
}
@@ -146,12 +148,12 @@ public class KeyboardId {
return mElementId == ELEMENT_PHONE_SYMBOLS;
}
- public boolean navigateAction() {
- // Note: Turn off checking navigation flag to show TAB key for now.
- boolean navigateAction = InputTypeCompatUtils.isWebInputType(mEditorInfo.inputType);
-// || EditorInfoCompatUtils.hasFlagNavigateNext(mImeOptions)
-// || EditorInfoCompatUtils.hasFlagNavigatePrevious(mImeOptions);
- return navigateAction;
+ public boolean navigateNext() {
+ return EditorInfoCompatUtils.hasFlagNavigateNext(mEditorInfo.imeOptions);
+ }
+
+ public boolean navigatePrevious() {
+ return EditorInfoCompatUtils.hasFlagNavigatePrevious(mEditorInfo.imeOptions);
}
public boolean passwordInput() {
@@ -165,15 +167,21 @@ public class KeyboardId {
}
public int imeAction() {
+ final int actionId = mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION;
if ((mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
return EditorInfo.IME_ACTION_NONE;
} else if (mEditorInfo.actionLabel != null) {
return IME_ACTION_CUSTOM_LABEL;
} else {
- return mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION;
+ return actionId;
}
}
+ public int imeActionId() {
+ final int actionId = imeAction();
+ return actionId == IME_ACTION_CUSTOM_LABEL ? mEditorInfo.actionId : actionId;
+ }
+
@Override
public boolean equals(Object other) {
return other instanceof KeyboardId && equals((KeyboardId) other);
@@ -186,17 +194,19 @@ public class KeyboardId {
@Override
public String toString() {
- return String.format("[%s %s %s%d %s %s %s%s%s%s%s]",
+ return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]",
elementIdToName(mElementId),
mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode),
imeAction(),
+ (navigateNext() ? "navigateNext" : ""),
+ (navigatePrevious() ? "navigatePrevious" : ""),
(mClobberSettingsKey ? " clobberSettingsKey" : ""),
- (navigateAction() ? " navigateAction" : ""),
(passwordInput() ? " passwordInput" : ""),
(mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
- (mHasShortcutKey ? " hasShortcutKey" : "")
+ (mHasShortcutKey ? " hasShortcutKey" : ""),
+ (isMultiLine() ? "isMultiLine" : "")
);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 12a9c51f2..9e5c227eb 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -163,10 +163,10 @@ public class KeyStyles {
if (DEBUG) {
Log.d(TAG, String.format("<%s styleName=%s />",
Keyboard.Builder.TAG_KEY_STYLE, styleName));
- }
- if (mStyles.containsKey(styleName)) {
- throw new XmlParseUtils.ParseException(
- "duplicate key style declared: " + styleName, parser);
+ if (mStyles.containsKey(styleName)) {
+ Log.d(TAG, "key-style " + styleName + " is overridden at "
+ + parser.getPositionDescription());
+ }
}
final DeclaredKeyStyle style = new DeclaredKeyStyle();
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 730992b13..aef248e19 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1232,11 +1232,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
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 static int getActionId(Keyboard keyboard) {
+ return keyboard != null ? keyboard.mId.imeActionId() : EditorInfo.IME_ACTION_NONE;
}
private void performeEditorAction(int actionId) {
@@ -1302,18 +1299,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSubtypeSwitcher.switchToShortcutIME();
break;
case Keyboard.CODE_ACTION_ENTER:
- performeEditorAction(getEditorActionId(getCurrentInputEditorInfo()));
+ performeEditorAction(getActionId(switcher.getKeyboard()));
break;
- case Keyboard.CODE_TAB:
- handleTab();
- // There are two cases for tab. Either we send a "next" event, that may change the
- // focus but will never move the cursor. Or, we send a real tab keycode, which some
- // applications may accept or ignore, and we don't know whether this will move the
- // cursor or not. So actually, we don't really know.
- // So to go with the safer option, we'd rather behave as if the user moved the
- // cursor when they didn't than the opposite. We also expect that most applications
- // will actually use tab only for focus movement.
- // To sum it up: do not update mExpectingUpdateSelection here.
+ case Keyboard.CODE_ACTION_NEXT:
+ performeEditorAction(EditorInfo.IME_ACTION_NEXT);
+ break;
+ case Keyboard.CODE_ACTION_PREVIOUS:
+ EditorInfoCompatUtils.performEditorActionPrevious(getCurrentInputConnection());
break;
default:
mSpaceState = SPACE_STATE_NONE;
@@ -1488,30 +1480,6 @@ 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;
- }
-
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null)
- return;
-
- final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
- // True if keyboard is in either shift chording or manual shifted state.
- final boolean isManualShifted = (keyboard != null && keyboard.isManualShifted());
- if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) && !isManualShifted) {
- EditorInfoCompatUtils.performEditorActionNext(ic);
- } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions) && isManualShifted) {
- EditorInfoCompatUtils.performEditorActionPrevious(ic);
- }
- }
-
// ic may be null
private boolean maybeStripSpaceWhileInBatchEdit(final InputConnection ic, final int code,
final int spaceState, final boolean isFromSuggestionStrip) {
diff --git a/java/src/com/android/inputmethod/latin/XmlParseUtils.java b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
index d747a024c..e14c71cb5 100644
--- a/java/src/com/android/inputmethod/latin/XmlParseUtils.java
+++ b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
@@ -27,8 +27,7 @@ public class XmlParseUtils {
@SuppressWarnings("serial")
public static class ParseException extends XmlPullParserException {
public ParseException(String msg, XmlPullParser parser) {
- super(msg + " at line " + parser.getLineNumber()
- + ", column " + parser.getColumnNumber());
+ super(msg + " at " + parser.getPositionDescription());
}
}