diff options
Diffstat (limited to 'java/src')
7 files changed, 213 insertions, 38 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index 0a2b010b6..fbb13c25f 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -26,6 +26,7 @@ import android.util.Log; import android.util.Xml; import com.android.inputmethod.keyboard.internal.KeySpecParser; +import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec; import com.android.inputmethod.keyboard.internal.KeyStyles; import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; @@ -104,7 +105,7 @@ public class Key { /** Text to output when pressed. This can be multiple characters, like ".com" */ public final CharSequence mOutputText; /** More keys */ - public final String[] mMoreKeys; + public final MoreKeySpec[] mMoreKeys; /** More keys column number and flags */ private final int mMoreKeysColumnAndFlags; private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff; @@ -140,15 +141,12 @@ public class Key { private boolean mEnabled = true; /** - * This constructor is being used only for key in more keys keyboard. + * This constructor is being used only for keys in more keys keyboard. */ - public Key(Resources res, Keyboard.Params params, String moreKeySpec, - int x, int y, int width, int height, int labelFlags) { - this(params, KeySpecParser.getLabel(moreKeySpec), null, - KeySpecParser.getIconId(moreKeySpec), - KeySpecParser.getCode(res, moreKeySpec), - KeySpecParser.getOutputText(moreKeySpec), - x, y, width, height, labelFlags); + public Key(Keyboard.Params params, MoreKeySpec moreKeySpec, int x, int y, int width, int height, + int labelFlags) { + this(params, moreKeySpec.mLabel, null, moreKeySpec.mIconId, moreKeySpec.mCode, + moreKeySpec.mOutputText, x, y, width, height, labelFlags); } /** @@ -278,13 +276,15 @@ public class Key { moreKeys = KeySpecParser.insertAddtionalMoreKeys(moreKeys, additionalMoreKeys); if (moreKeys != null) { actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; + mMoreKeys = new MoreKeySpec[moreKeys.length]; for (int i = 0; i < moreKeys.length; i++) { - moreKeys[i] = adjustCaseOfStringForKeyboardId( - moreKeys[i], preserveCase, params.mId); + mMoreKeys[i] = new MoreKeySpec(adjustCaseOfStringForKeyboardId( + moreKeys[i], preserveCase, params.mId), params.mCodesSet); } + } else { + mMoreKeys = null; } mActionFlags = actionFlags; - mMoreKeys = moreKeys; if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) { mLabel = params.mId.mCustomActionLabel; @@ -300,8 +300,9 @@ public class Key { } String outputText = adjustCaseOfStringForKeyboardId(style.getString( keyAttr, R.styleable.Keyboard_Key_keyOutputText), preserveCase, params.mId); - final int code = style.getInt( - keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED); + final int code = KeySpecParser.parseCode(style.getString( + keyAttr, R.styleable.Keyboard_Key_code), + params.mCodesSet, Keyboard.CODE_UNSPECIFIED); // Choose the first letter of the label as primary code if not specified. if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) { @@ -331,9 +332,10 @@ public class Key { mCode = adjustCaseOfCodeForKeyboardId(code, preserveCase, params.mId); } mOutputText = outputText; - mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr, - R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase, - params.mId); + mAltCode = adjustCaseOfCodeForKeyboardId(KeySpecParser.parseCode(style.getString( + keyAttr, R.styleable.Keyboard_Key_altCode), + params.mCodesSet, Keyboard.CODE_UNSPECIFIED), + preserveCase, params.mId); mHashCode = computeHashCode(this); keyAttr.recycle(); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 950b5e99b..4b9ff28fe 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -28,6 +28,7 @@ import android.util.Xml; import android.view.InflateException; import com.android.inputmethod.keyboard.internal.KeyStyles; +import com.android.inputmethod.keyboard.internal.KeyboardCodesSet; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; @@ -238,6 +239,7 @@ public class Keyboard { public final ArrayList<Key> mShiftKeys = new ArrayList<Key>(); public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<Key>(); public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet(); + public final KeyboardCodesSet mCodesSet = new KeyboardCodesSet(); public KeyboardLayoutSet.KeysCache mKeysCache; @@ -775,6 +777,7 @@ public class Keyboard { params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0); params.mIconsSet.loadIcons(keyboardAttr); + params.mCodesSet.setLocale(params.mId.mLocale); final int resourceId = keyboardAttr.getResourceId( R.styleable.Keyboard_touchPositionCorrectionData, 0); diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 98da1eb65..5ebf92cf7 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -41,7 +41,6 @@ import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; -import com.android.inputmethod.keyboard.internal.KeySpecParser; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; @@ -560,7 +559,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } final int primaryCode = parentKey.mCode; if (parentKey.hasEmbeddedMoreKey()) { - final int embeddedCode = KeySpecParser.getCode(getResources(), parentKey.mMoreKeys[0]); + final int embeddedCode = parentKey.mMoreKeys[0].mCode; tracker.onLongPressed(); invokeCodeInput(embeddedCode); invokeReleaseKey(primaryCode); diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java index 72a5d0f05..f8682d8ca 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java @@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard; import android.graphics.Paint; import android.graphics.drawable.Drawable; -import com.android.inputmethod.keyboard.internal.KeySpecParser; +import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; @@ -301,8 +301,8 @@ public class MoreKeysKeyboard extends Keyboard { ? view.mKeyDrawParams.mKeyLabelSize : view.mKeyDrawParams.mKeyLetterSize); int maxWidth = minKeyWidth; - for (String moreKeySpec : parentKey.mMoreKeys) { - final String label = KeySpecParser.getLabel(moreKeySpec); + for (final MoreKeySpec spec : parentKey.mMoreKeys) { + final String label = spec.mLabel; // If the label is single letter, minKeyWidth is enough to hold the label. if (label != null && StringUtils.codePointCount(label) > 1) { final int width = (int)view.getLabelWidth(label, paint) + padding; @@ -336,13 +336,13 @@ public class MoreKeysKeyboard extends Keyboard { // label's code point count. final int moreKeyFlags = mParentKey.hasLabelsInMoreKeys() ? 0 : Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO; - final String[] moreKeys = mParentKey.mMoreKeys; + final MoreKeySpec[] moreKeys = mParentKey.mMoreKeys; for (int n = 0; n < moreKeys.length; n++) { - final String moreKeySpec = moreKeys[n]; + final MoreKeySpec moreKeySpec = moreKeys[n]; final int row = n / params.mNumColumns; final int x = params.getX(n, row); final int y = params.getY(row); - final Key key = new Key(mResources, params, moreKeySpec, x, y, + final Key key = new Key(params, moreKeySpec, x, y, params.mDefaultKeyWidth, params.mDefaultRowHeight, moreKeyFlags); params.markAsEdgeKey(key, row); params.onAddKey(key); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java index 4abd887f0..84965bfe7 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java @@ -21,7 +21,6 @@ import android.text.TextUtils; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; import java.util.ArrayList; @@ -35,7 +34,8 @@ import java.util.Arrays; * Each "more key" specification is one of the following: * - A single letter (Letter) * - Label optionally followed by keyOutputText or code (keyLabel|keyOutputText). - * - Icon followed by keyOutputText or code (@icon/icon_name|@integer/key_code) + * - Icon followed by keyOutputText or a string representation of codes + * (@icon/icon_name|!code/key_code) * Special character, comma ',' backslash '\', and bar '|' can be escaped by '\' character. * Note that the character '@' and '\' are also parsed by XML parser and CSV parser as well. * See {@link KeyboardIconsSet} about icon_name. @@ -53,9 +53,24 @@ public class KeySpecParser { private static final String PREFIX_STRING = PREFIX_AT + "string" + SUFFIX_SLASH; private static final char LABEL_END = '|'; private static final String PREFIX_ICON = PREFIX_AT + "icon" + SUFFIX_SLASH; - private static final String PREFIX_CODE = PREFIX_AT + "integer" + SUFFIX_SLASH; + private static final String PREFIX_CODE = "!code/"; + private static final String PREFIX_HEX = "0x"; private static final String ADDITIONAL_MORE_KEY_MARKER = "%"; + public static class MoreKeySpec { + public final int mCode; + public final String mLabel; + public final String mOutputText; + public final int mIconId; + + public MoreKeySpec(final String moreKeySpec, final KeyboardCodesSet codesSet) { + mCode = getCode(moreKeySpec, codesSet); + mLabel = getLabel(moreKeySpec); + mOutputText = getOutputText(moreKeySpec); + mIconId = getIconId(moreKeySpec); + } + } + private KeySpecParser() { // Intentional empty constructor for utility class. } @@ -144,7 +159,7 @@ public class KeySpecParser { return parseEscape(moreKeySpec.substring(end + /* LABEL_END */1)); } - public static String getOutputText(String moreKeySpec) { + private static String getOutputText(String moreKeySpec) { if (hasCode(moreKeySpec)) { return null; } @@ -168,17 +183,13 @@ public class KeySpecParser { return (StringUtils.codePointCount(label) == 1) ? null : label; } - public static int getCode(Resources res, String moreKeySpec) { + private static int getCode(String moreKeySpec, KeyboardCodesSet codesSet) { if (hasCode(moreKeySpec)) { final int end = indexOfLabelEnd(moreKeySpec, 0); if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0) { throw new KeySpecParserError("Multiple " + LABEL_END + ": " + moreKeySpec); } - final int resId = getResourceId(res, - moreKeySpec.substring(end + /* LABEL_END */1 + /* PREFIX_AT */1), - R.string.english_ime_name); - final int code = res.getInteger(resId); - return code; + return parseCode(moreKeySpec.substring(end + 1), codesSet, Keyboard.CODE_UNSPECIFIED); } final String outputText = getOutputTextInternal(moreKeySpec); if (outputText != null) { @@ -197,7 +208,18 @@ public class KeySpecParser { return Keyboard.CODE_OUTPUT_TEXT; } - public static int getIconId(String moreKeySpec) { + public static int parseCode(String text, KeyboardCodesSet codesSet, int defCode) { + if (text == null) return defCode; + if (text.startsWith(PREFIX_CODE)) { + return codesSet.getCode(text.substring(PREFIX_CODE.length())); + } else if (text.startsWith(PREFIX_HEX)) { + return Integer.parseInt(text.substring(PREFIX_HEX.length()), 16); + } else { + return Integer.parseInt(text); + } + } + + private static int getIconId(String moreKeySpec) { if (hasIcon(moreKeySpec)) { final int end = moreKeySpec.indexOf(LABEL_END, PREFIX_ICON.length()); final String name = moreKeySpec.substring(PREFIX_ICON.length(), end); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java index 9e5c227eb..405b7ad05 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java @@ -102,8 +102,8 @@ public class KeyStyles { void readKeyAttributes(TypedArray keyAttr) { // TODO: Currently not all Key attributes can be declared as style. - readInt(keyAttr, R.styleable.Keyboard_Key_code); - readInt(keyAttr, R.styleable.Keyboard_Key_altCode); + readString(keyAttr, R.styleable.Keyboard_Key_code); + readString(keyAttr, R.styleable.Keyboard_Key_altCode); readString(keyAttr, R.styleable.Keyboard_Key_keyLabel); readString(keyAttr, R.styleable.Keyboard_Key_keyOutputText); readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java new file mode 100644 index 000000000..964c8cac2 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import com.android.inputmethod.keyboard.Keyboard; + +import java.util.HashMap; +import java.util.Locale; + +public class KeyboardCodesSet { + private static final HashMap<Locale, int[]> sLocaleToCodesMap = + new HashMap<Locale, int[]>(); + private static final HashMap<String, Integer> sNameToIdMap = new HashMap<String, Integer>(); + + private int[] mCodes = DEFAULT; + + public void setLocale(final Locale locale) { + final int[] codes = sLocaleToCodesMap.get(locale); + mCodes = (codes != null) ? codes : DEFAULT; + } + + public int getCode(final String name) { + final Integer id = sNameToIdMap.get(name); + if (id == null) throw new RuntimeException("Unknown key code: " + name); + return mCodes[id]; + } + + private static final String[] ID_TO_NAME = { + "key_tab", + "key_enter", + "key_space", + "key_shift", + "key_switch_alpha_symbol", + "key_output_text", + "key_delete", + "key_settings", + "key_shortcut", + "key_action_enter", + "key_action_next", + "key_action_previous", + "key_language_switch", + "key_unspecified", + "key_left_parenthesis", + "key_right_parenthesis", + "key_less_than", + "key_greater_than", + "key_left_square_bracket", + "key_right_square_bracket", + "key_left_curly_bracket", + "key_right_curly_bracket", + }; + + private static final int CODE_LEFT_PARENTHESIS = '('; + private static final int CODE_RIGHT_PARENTHESIS = ')'; + private static final int CODE_LESS_THAN_SIGN = '<'; + private static final int CODE_GREATER_THAN_SIGN = '>'; + private static final int CODE_LEFT_SQUARE_BRACKET = '['; + private static final int CODE_RIGHT_SQUARE_BRACKET = ']'; + private static final int CODE_LEFT_CURLY_BRACKET = '{'; + private static final int CODE_RIGHT_CURLY_BRACKET = '}'; + + private static final int[] DEFAULT = { + Keyboard.CODE_TAB, + Keyboard.CODE_ENTER, + Keyboard.CODE_SPACE, + Keyboard.CODE_SHIFT, + Keyboard.CODE_SWITCH_ALPHA_SYMBOL, + Keyboard.CODE_OUTPUT_TEXT, + Keyboard.CODE_DELETE, + Keyboard.CODE_SETTINGS, + Keyboard.CODE_SHORTCUT, + Keyboard.CODE_ACTION_ENTER, + Keyboard.CODE_ACTION_NEXT, + Keyboard.CODE_LANGUAGE_SWITCH, + Keyboard.CODE_UNSPECIFIED, + CODE_LEFT_PARENTHESIS, + CODE_RIGHT_PARENTHESIS, + CODE_LESS_THAN_SIGN, + CODE_GREATER_THAN_SIGN, + CODE_LEFT_SQUARE_BRACKET, + CODE_RIGHT_SQUARE_BRACKET, + CODE_LEFT_CURLY_BRACKET, + CODE_RIGHT_CURLY_BRACKET, + }; + + private static final int[] RTL = { + DEFAULT[0], + DEFAULT[1], + DEFAULT[2], + DEFAULT[3], + DEFAULT[4], + DEFAULT[5], + DEFAULT[6], + DEFAULT[7], + DEFAULT[8], + DEFAULT[9], + DEFAULT[10], + DEFAULT[11], + DEFAULT[12], + CODE_RIGHT_PARENTHESIS, + CODE_LEFT_PARENTHESIS, + CODE_GREATER_THAN_SIGN, + CODE_LESS_THAN_SIGN, + CODE_RIGHT_SQUARE_BRACKET, + CODE_LEFT_SQUARE_BRACKET, + CODE_RIGHT_CURLY_BRACKET, + CODE_LEFT_CURLY_BRACKET, + }; + + private static final String LANGUAGE_DEFAULT = null; + private static final String LANGUAGE_ARABIC = "ar"; + private static final String LANGUAGE_PERSIAN = "fa"; + private static final String LANGUAGE_HEBREW = "iw"; + + private static final Object[] LOCALE_AND_CODES = { + LANGUAGE_DEFAULT, DEFAULT, + LANGUAGE_ARABIC, RTL, + LANGUAGE_PERSIAN, RTL, + LANGUAGE_HEBREW, RTL, + }; + + static { + for (int i = 0; i < ID_TO_NAME.length; i++) { + sNameToIdMap.put(ID_TO_NAME[i], i); + } + + for (int i = 0; i < LOCALE_AND_CODES.length; i += 2) { + final String localeString = (String)LOCALE_AND_CODES[i]; + final int[] codes = (int[])LOCALE_AND_CODES[i + 1]; + final Locale locale = (localeString == LANGUAGE_DEFAULT) + ? null : new Locale(localeString); + sLocaleToCodesMap.put(locale, codes); + } + } +} |