diff options
author | 2010-11-11 15:28:14 -0800 | |
---|---|---|
committer | 2010-11-12 14:30:25 -0800 | |
commit | b0465116bd3786174ccd0034c8a165ebc723b60f (patch) | |
tree | 5fb2421d2bb212c7a358f55ee79b4684ccab5751 /java/src/com/android/inputmethod/latin/BaseKeyboardParser.java | |
parent | 8b00bc4f3281c229ee830f34a78c0ec287902c3f (diff) | |
download | latinime-b0465116bd3786174ccd0034c8a165ebc723b60f.tar.gz latinime-b0465116bd3786174ccd0034c8a165ebc723b60f.tar.xz latinime-b0465116bd3786174ccd0034c8a165ebc723b60f.zip |
Keyboard XML supports switch-case-default tags to select rows and keys
Change-Id: I0d92e513757e765d9de98561205754af5a143650
Diffstat (limited to 'java/src/com/android/inputmethod/latin/BaseKeyboardParser.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BaseKeyboardParser.java | 197 |
1 files changed, 173 insertions, 24 deletions
diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java b/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java index 628e764b5..496f65174 100644 --- a/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java +++ b/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import com.android.inputmethod.latin.BaseKeyboard.Key; import com.android.inputmethod.latin.BaseKeyboard.Row; +import com.android.inputmethod.latin.KeyboardSwitcher.KeyboardId; import org.xmlpull.v1.XmlPullParserException; @@ -52,7 +53,7 @@ import java.util.List; * ... * >/Keyboard< * </pre> - * The xml file which is included in other file must have >merge< as root element, such as: + * The XML file which is included in other file must have >merge< as root element, such as: * <pre> * >!-- xml/other_keys.xml --< * >merge< @@ -70,6 +71,38 @@ import java.util.List; * ... * >/merge< * </pre> + * You can also use switch-case-default tags to select Rows and Keys. + * <pre> + * >switch< + * >case case_attribute*< + * >!-- Any valid tags at switch position --< + * >/case< + * ... + * >default< + * >!-- Any valid tags at switch position --< + * >/default< + * >/switch< + * </pre> + * + * TODO: These are some random ideas to improve this parser. + * - can specify keyWidth attribute by multiplication of default keyWidth + * for example: keyWidth="200%b" ("b" stands for "base") + * - can declare style and specify styles within tags. + * for example: + * >switch< + * >case colorScheme="white"< + * >declare-style name="shift-key" parentStyle="modifier-key"< + * >item name="keyIcon"<@drawable/sym_keyboard_shift">/item< + * >/declare-style< + * >/case< + * >case colorScheme="black"< + * >declare-style name="shift-key" parentStyle="modifier-key"< + * >item name="keyIcon"<@drawable/sym_bkeyboard_shift">/item< + * >/declare-style< + * >/case< + * >/switch< + * ... + * >Key include-style="shift-key" ... /< */ public class BaseKeyboardParser { private static final String TAG = "BaseKeyboardParser"; @@ -83,6 +116,17 @@ public class BaseKeyboardParser { private static final String TAG_SPACER = "Spacer"; private static final String TAG_INCLUDE = "include"; private static final String TAG_MERGE = "merge"; + private static final String TAG_SWITCH = "switch"; + private static final String TAG_CASE = "case"; + private static final String TAG_DEFAULT = "default"; + + // String representation of KeyboardSwitcher.MODE_xxx. + private static final String MODE_TEXT = "text"; + private static final String MODE_URL = "url"; + private static final String MODE_EMAIL = "email"; + private static final String MODE_IM = "im"; + private static final String MODE_WEB = "web"; + private static final String MODE_PHONE = "phone"; private final BaseKeyboard mKeyboard; private final Resources mResources; @@ -143,7 +187,7 @@ public class BaseKeyboardParser { a.recycle(); } - private void parseKeyboardContent(XmlResourceParser parser, final List<Key> keys) + private void parseKeyboardContent(XmlResourceParser parser, List<Key> keys) throws XmlPullParserException, IOException { if (DEBUG_PARSER) debugEnterMethod("parseKeyboardContent", keys == null); int event; @@ -153,14 +197,13 @@ public class BaseKeyboardParser { if (DEBUG_TAG) debugStartTag("parseKeyboardContent", tag, keys == null); if (TAG_ROW.equals(tag)) { Row row = mKeyboard.createRowFromXml(mResources, parser); - if (keys != null && maybeStartRow(row)) { - parseRowContent(parser, row, keys); - } else { - // Skip entire <Row></Row> - parseRowContent(parser, row, null); - } + if (keys != null) + startRow(row); + parseRowContent(parser, row, keys); } else if (TAG_INCLUDE.equals(tag)) { parseIncludeKeyboardContent(parser, keys); + } else if (TAG_SWITCH.equals(tag)) { + parseSwitchKeyboardContent(parser, keys); } else { throw new IllegalStartTag(parser, TAG_ROW); } @@ -170,6 +213,8 @@ public class BaseKeyboardParser { if (TAG_KEYBOARD.equals(tag)) { endKeyboard(mKeyboard.getVerticalGap()); break; + } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)) { + break; } else if (TAG_MERGE.equals(tag)) { break; } else { @@ -194,6 +239,8 @@ public class BaseKeyboardParser { parseSpacer(parser, keys); } else if (TAG_INCLUDE.equals(tag)) { parseIncludeRowContent(parser, row, keys); + } else if (TAG_SWITCH.equals(tag)) { + parseSwitchRowContent(parser, row, keys); } else { throw new IllegalStartTag(parser, TAG_KEY); } @@ -204,6 +251,8 @@ public class BaseKeyboardParser { if (keys != null) endRow(); break; + } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)) { + break; } else if (TAG_MERGE.equals(tag)) { break; } else { @@ -237,7 +286,7 @@ public class BaseKeyboardParser { } else { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.BaseKeyboard); - int gap = getDimensionOrFraction(a, R.styleable.BaseKeyboard_horizontalGap, + final int gap = getDimensionOrFraction(a, R.styleable.BaseKeyboard_horizontalGap, mKeyboard.getKeyboardWidth(), 0); a.recycle(); checkEndTag(TAG_SPACER, parser); @@ -247,17 +296,20 @@ public class BaseKeyboardParser { private void parseIncludeKeyboardContent(XmlResourceParser parser, List<Key> keys) throws XmlPullParserException, IOException { + if (DEBUG_PARSER) debugEnterMethod("parseIncludeKeyboardContent", keys == null); parseIncludeInternal(parser, null, keys); + if (DEBUG_PARSER) debugLeaveMethod("parseIncludeKeyboardContent", keys == null); } private void parseIncludeRowContent(XmlResourceParser parser, Row row, List<Key> keys) throws XmlPullParserException, IOException { + if (DEBUG_PARSER) debugEnterMethod("parseIncludeRowContent", keys == null); parseIncludeInternal(parser, row, keys); + if (DEBUG_PARSER) debugLeaveMethod("parseIncludeRowContent", keys == null); } private void parseIncludeInternal(XmlResourceParser parser, Row row, List<Key> keys) throws XmlPullParserException, IOException { - if (DEBUG_PARSER) debugEnterMethod("parseInclude", keys == null); if (keys == null) { checkEndTag(TAG_INCLUDE, parser); } else { @@ -272,7 +324,6 @@ public class BaseKeyboardParser { throw new ParseException("No keyboardLayout attribute in <include/>", parser); parseMerge(mResources.getLayout(keyboardLayout), row, keys); } - if (DEBUG_PARSER) debugLeaveMethod("parseInclude", keys == null); } private void parseMerge(XmlResourceParser parser, Row row, List<Key> keys) @@ -281,7 +332,7 @@ public class BaseKeyboardParser { int event; while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) { if (event == XmlResourceParser.START_TAG) { - String tag = parser.getName(); + final String tag = parser.getName(); if (DEBUG_TAG) debugStartTag("parseMerge", tag, keys == null); if (TAG_MERGE.equals(tag)) { if (row == null) { @@ -299,6 +350,113 @@ public class BaseKeyboardParser { if (DEBUG_PARSER) debugLeaveMethod("parseMerge", keys == null); } + private void parseSwitchKeyboardContent(XmlResourceParser parser, List<Key> keys) + throws XmlPullParserException, IOException { + if (DEBUG_PARSER) debugEnterMethod("parseSwitchKeyboardContent", keys == null); + parseSwitchInternal(parser, null, keys); + if (DEBUG_PARSER) debugLeaveMethod("parseSwitchKeyboardContent", keys == null); + } + + private void parseSwitchRowContent(XmlResourceParser parser, Row row, List<Key> keys) + throws XmlPullParserException, IOException { + if (DEBUG_PARSER) debugEnterMethod("parseSwitchRowContent", keys == null); + parseSwitchInternal(parser, row, keys); + if (DEBUG_PARSER) debugLeaveMethod("parseSwitchRowContent", keys == null); + } + + private void parseSwitchInternal(XmlResourceParser parser, Row row, List<Key> keys) + throws XmlPullParserException, IOException { + boolean selected = false; + int event; + if (DEBUG_TAG) Log.d(TAG, "parseSwitchInternal: id=" + mKeyboard.mId); + while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) { + if (event == XmlResourceParser.START_TAG) { + final String tag = parser.getName(); + if (DEBUG_TAG) debugStartTag("parseSwitchInternal", tag, keys == null); + if (TAG_CASE.equals(tag)) { + selected |= parseCase(parser, row, selected ? null : keys); + } else if (TAG_DEFAULT.equals(tag)) { + selected |= parseDefault(parser, row, selected ? null : keys); + } else { + throw new IllegalStartTag(parser, TAG_KEY); + } + } else if (event == XmlResourceParser.END_TAG) { + final String tag = parser.getName(); + if (DEBUG_TAG) debugEndTag("parseRowContent", tag, keys == null); + if (TAG_SWITCH.equals(tag)) { + break; + } else { + throw new IllegalEndTag(parser, TAG_KEY); + } + } + } + } + + private boolean parseCase(XmlResourceParser parser, Row row, List<Key> keys) + throws XmlPullParserException, IOException { + if (DEBUG_PARSER) debugEnterMethod("parseCase", keys == null); + final boolean selected = parseCaseCondition(parser); + if (row == null) { + // Processing Rows. + parseKeyboardContent(parser, selected ? keys : null); + } else { + // Processing Keys. + parseRowContent(parser, row, selected ? keys : null); + } + if (DEBUG_PARSER) debugLeaveMethod("parseCase", keys == null || !selected); + return selected; + } + + private boolean parseCaseCondition(XmlResourceParser parser) { + final BaseKeyboard keyboard = mKeyboard; + final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.BaseKeyboard_Case); + final String mode = a.getString(R.styleable.BaseKeyboard_Case_mode); + final String settingsKey = a.getString(R.styleable.BaseKeyboard_Case_settingsKey); + final String voiceKey = a.getString(R.styleable.BaseKeyboard_Case_voiceKey); + a.recycle(); + + final KeyboardId id = keyboard.mId; + if (id == null) + return true; + final boolean modeMatched = (mode == null + || id.mMode == parseModeString(mode)); + final boolean settingsKeyMatched = (settingsKey == null + || id.mHasSettingsKey == Boolean.parseBoolean(settingsKey)); + final boolean voiceKeyMatched = (voiceKey == null + || id.mHasVoiceKey == Boolean.parseBoolean(voiceKey)); + final boolean selected = modeMatched && settingsKeyMatched && voiceKeyMatched; + if (DEBUG_TAG) { + Log.d(TAG, "parseCaseCondition: " + Boolean.toString(selected).toUpperCase() + + (mode != null ? " mode=" + mode : "") + + (settingsKey != null ? " settingsKey="+settingsKey : "") + + (voiceKey != null ? " voiceKey=" + voiceKey : "")); + } + return selected; + } + + private static int parseModeString(String mode) { + if (mode.equals(MODE_TEXT)) return KeyboardSwitcher.MODE_TEXT; + if (mode.equals(MODE_URL)) return KeyboardSwitcher.MODE_URL; + if (mode.equals(MODE_EMAIL)) return KeyboardSwitcher.MODE_EMAIL; + if (mode.equals(MODE_IM)) return KeyboardSwitcher.MODE_IM; + if (mode.equals(MODE_WEB)) return KeyboardSwitcher.MODE_WEB; + if (mode.equals(MODE_PHONE)) return KeyboardSwitcher.MODE_PHONE; + throw new RuntimeException("uknown mode attribute in Keyboard XML: " + mode); + } + + private boolean parseDefault(XmlResourceParser parser, Row row, List<Key> keys) + throws XmlPullParserException, IOException { + if (DEBUG_PARSER) debugEnterMethod("parseDefault", keys == null); + if (row == null) { + parseKeyboardContent(parser, keys); + } else { + parseRowContent(parser, row, keys); + } + if (DEBUG_PARSER) debugLeaveMethod("parseDefault", keys == null); + return true; + } + private static void checkEndTag(String tag, XmlResourceParser parser) throws XmlPullParserException, IOException { if (parser.next() == XmlResourceParser.END_TAG && tag.equals(parser.getName())) @@ -306,18 +464,9 @@ public class BaseKeyboardParser { throw new NonEmptyTag(tag, parser); } - // return true if the row is valid for this keyboard mode - private boolean maybeStartRow(Row row) { - if (DEBUG_TAG) - Log.d(TAG, String.format("startRow: mode=0x%08x keyboardMode=0x%08x", - row.mode, mKeyboard.getKeyboardMode())); - if (row.mode == 0 || row.mode == mKeyboard.getKeyboardMode()) { - mCurrentX = 0; - mCurrentRow = row; - return true; - } else { - return false; - } + private void startRow(Row row) { + mCurrentX = 0; + mCurrentRow = row; } private void endRow() { |