diff options
author | 2014-08-28 15:14:36 +0900 | |
---|---|---|
committer | 2014-09-25 18:27:23 +0900 | |
commit | aaefd5666112c4a6fff58783c25cf9a75b468edd (patch) | |
tree | 69f8d60a187dac846a855aa0b94a67a97c1ce156 /java/src | |
parent | dbb2182e3928cb8d204290f83a01718d5ff9b162 (diff) | |
download | latinime-aaefd5666112c4a6fff58783c25cf9a75b468edd.tar.gz latinime-aaefd5666112c4a6fff58783c25cf9a75b468edd.tar.xz latinime-aaefd5666112c4a6fff58783c25cf9a75b468edd.zip |
Add !string/<resource_name> reference
This CL introduces new text reference notation !string/<resource_name>
to refer a string resource on the fly.
This notation is mainly used to represent action key labels may refer
a string in a system locale in run-time.
This notation is needed to implement Hinglish and Serbian-Latin
keyboards that need to refer its own action key labels.
Bug: 17169632
Bug: 9687668
Change-Id: I042f6bd04714e0e448cd92031730eb9fb422e6d3
Diffstat (limited to 'java/src')
3 files changed, 126 insertions, 90 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java index cd6abeed3..f9297ac27 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java @@ -25,49 +25,42 @@ import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.utils.RunInLocale; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; -import java.util.HashMap; import java.util.Locale; +// TODO: Make this an immutable class. public final class KeyboardTextsSet { public static final String PREFIX_TEXT = "!text/"; + private static final String PREFIX_RESOURCE = "!string/"; public static final String SWITCH_TO_ALPHA_KEY_LABEL = "keylabel_to_alpha"; private static final char BACKSLASH = Constants.CODE_BACKSLASH; - private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; + private static final int MAX_REFERENCE_INDIRECTION = 10; + private Resources mResources; + private Locale mResourceLocale; + private String mResourcePackageName; private String[] mTextsTable; - // Resource name to text map. - private HashMap<String, String> mResourceNameToTextsMap = new HashMap<>(); public void setLocale(final Locale locale, final Context context) { - mTextsTable = KeyboardTextsTable.getTextsTable(locale); final Resources res = context.getResources(); - final int referenceId = context.getApplicationInfo().labelRes; - final String resourcePackageName = res.getResourcePackageName(referenceId); - final RunInLocale<Void> job = new RunInLocale<Void>() { - @Override - protected Void job(final Resources resource) { - loadStringResourcesInternal(res, RESOURCE_NAMES, resourcePackageName); - return null; - } - }; // Null means the current system locale. - job.runInLocale(res, - SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale); + final String resourcePackageName = res.getResourcePackageName( + context.getApplicationInfo().labelRes); + setLocale(locale, res, resourcePackageName); } @UsedForTesting - void loadStringResourcesInternal(final Resources res, final String[] resourceNames, + public void setLocale(final Locale locale, final Resources res, final String resourcePackageName) { - for (final String resName : resourceNames) { - final int resId = res.getIdentifier(resName, "string", resourcePackageName); - mResourceNameToTextsMap.put(resName, res.getString(resId)); - } + mResources = res; + // Null means the current system locale. + mResourceLocale = SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale; + mResourcePackageName = resourcePackageName; + mTextsTable = KeyboardTextsTable.getTextsTable(locale); } public String getText(final String name) { - final String text = mResourceNameToTextsMap.get(name); - return (text != null) ? text : KeyboardTextsTable.getText(name, mTextsTable); + return KeyboardTextsTable.getText(name, mTextsTable); } private static int searchTextNameEnd(final String text, final int start) { @@ -93,13 +86,14 @@ public final class KeyboardTextsSet { StringBuilder sb; do { level++; - if (level >= MAX_STRING_REFERENCE_INDIRECTION) { - throw new RuntimeException("Too many " + PREFIX_TEXT + "name indirection: " + text); + if (level >= MAX_REFERENCE_INDIRECTION) { + throw new RuntimeException("Too many " + PREFIX_TEXT + " or " + PREFIX_RESOURCE + + " reference indirection: " + text); } - final int prefixLen = PREFIX_TEXT.length(); + final int prefixLength = PREFIX_TEXT.length(); final int size = text.length(); - if (size < prefixLen) { + if (size < prefixLength) { break; } @@ -110,10 +104,12 @@ public final class KeyboardTextsSet { if (sb == null) { sb = new StringBuilder(text.substring(0, pos)); } - final int end = searchTextNameEnd(text, pos + prefixLen); - final String name = text.substring(pos + prefixLen, end); - sb.append(getText(name)); - pos = end - 1; + pos = expandReference(text, pos, PREFIX_TEXT, sb); + } else if (text.startsWith(PREFIX_RESOURCE, pos)) { + if (sb == null) { + sb = new StringBuilder(text.substring(0, pos)); + } + pos = expandReference(text, pos, PREFIX_RESOURCE, sb); } else if (c == BACKSLASH) { if (sb != null) { // Append both escape character and escaped character. @@ -132,18 +128,24 @@ public final class KeyboardTextsSet { return TextUtils.isEmpty(text) ? null : text; } - // These texts' name should be aligned with the @string/<name> in - // values*/strings-action-keys.xml. - static final String[] RESOURCE_NAMES = { - // Labels for action. - "label_go_key", - "label_send_key", - "label_next_key", - "label_done_key", - "label_search_key", - "label_previous_key", - // Other labels. - "label_pause_key", - "label_wait_key", - }; + private int expandReference(final String text, final int pos, final String prefix, + final StringBuilder sb) { + final int prefixLength = prefix.length(); + final int end = searchTextNameEnd(text, pos + prefixLength); + final String name = text.substring(pos + prefixLength, end); + if (prefix.equals(PREFIX_TEXT)) { + sb.append(getText(name)); + } else { // PREFIX_RESOURCE + final String resourcePackageName = mResourcePackageName; + final RunInLocale<String> getTextJob = new RunInLocale<String>() { + @Override + protected String job(final Resources res) { + final int resId = res.getIdentifier(name, "string", resourcePackageName); + return res.getString(resId); + } + }; + sb.append(getTextJob.runInLocale(mResources, mResourceLocale)); + } + return end - 1; + } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java index 3c33320ea..192011384 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java @@ -209,48 +209,56 @@ public final class KeyboardTextsTable { /* 123: 1 */ "morekeys_less_than", /* 124: 1 */ "morekeys_greater_than", /* 125: 1 */ "morekeys_exclamation", - /* 126: 0 */ "morekeys_currency_generic", - /* 127: 0 */ "morekeys_symbols_1", - /* 128: 0 */ "morekeys_symbols_2", - /* 129: 0 */ "morekeys_symbols_3", - /* 130: 0 */ "morekeys_symbols_4", - /* 131: 0 */ "morekeys_symbols_5", - /* 132: 0 */ "morekeys_symbols_6", - /* 133: 0 */ "morekeys_symbols_7", - /* 134: 0 */ "morekeys_symbols_8", - /* 135: 0 */ "morekeys_symbols_9", - /* 136: 0 */ "morekeys_symbols_0", - /* 137: 0 */ "morekeys_am_pm", - /* 138: 0 */ "keyspec_settings", - /* 139: 0 */ "keyspec_shortcut", - /* 140: 0 */ "keyspec_action_next", - /* 141: 0 */ "keyspec_action_previous", - /* 142: 0 */ "keylabel_to_more_symbol", - /* 143: 0 */ "keylabel_tablet_to_more_symbol", - /* 144: 0 */ "keylabel_to_phone_numeric", - /* 145: 0 */ "keylabel_to_phone_symbols", - /* 146: 0 */ "keylabel_time_am", - /* 147: 0 */ "keylabel_time_pm", - /* 148: 0 */ "keyspec_popular_domain", - /* 149: 0 */ "morekeys_popular_domain", - /* 150: 0 */ "keyspecs_left_parenthesis_more_keys", - /* 151: 0 */ "keyspecs_right_parenthesis_more_keys", - /* 152: 0 */ "single_laqm_raqm", - /* 153: 0 */ "single_raqm_laqm", - /* 154: 0 */ "double_laqm_raqm", - /* 155: 0 */ "double_raqm_laqm", - /* 156: 0 */ "single_lqm_rqm", - /* 157: 0 */ "single_9qm_lqm", - /* 158: 0 */ "single_9qm_rqm", - /* 159: 0 */ "single_rqm_9qm", - /* 160: 0 */ "double_lqm_rqm", - /* 161: 0 */ "double_9qm_lqm", - /* 162: 0 */ "double_9qm_rqm", - /* 163: 0 */ "double_rqm_9qm", - /* 164: 0 */ "morekeys_single_quote", - /* 165: 0 */ "morekeys_double_quote", - /* 166: 0 */ "morekeys_tablet_double_quote", - /* 167: 0 */ "keyspec_emoji_action_key", + /* 126: 1 */ "label_go_key", + /* 127: 1 */ "label_send_key", + /* 128: 1 */ "label_next_key", + /* 129: 1 */ "label_done_key", + /* 130: 1 */ "label_search_key", + /* 131: 1 */ "label_previous_key", + /* 132: 1 */ "label_pause_key", + /* 133: 1 */ "label_wait_key", + /* 134: 0 */ "morekeys_currency_generic", + /* 135: 0 */ "morekeys_symbols_1", + /* 136: 0 */ "morekeys_symbols_2", + /* 137: 0 */ "morekeys_symbols_3", + /* 138: 0 */ "morekeys_symbols_4", + /* 139: 0 */ "morekeys_symbols_5", + /* 140: 0 */ "morekeys_symbols_6", + /* 141: 0 */ "morekeys_symbols_7", + /* 142: 0 */ "morekeys_symbols_8", + /* 143: 0 */ "morekeys_symbols_9", + /* 144: 0 */ "morekeys_symbols_0", + /* 145: 0 */ "morekeys_am_pm", + /* 146: 0 */ "keyspec_settings", + /* 147: 0 */ "keyspec_shortcut", + /* 148: 0 */ "keyspec_action_next", + /* 149: 0 */ "keyspec_action_previous", + /* 150: 0 */ "keylabel_to_more_symbol", + /* 151: 0 */ "keylabel_tablet_to_more_symbol", + /* 152: 0 */ "keylabel_to_phone_numeric", + /* 153: 0 */ "keylabel_to_phone_symbols", + /* 154: 0 */ "keylabel_time_am", + /* 155: 0 */ "keylabel_time_pm", + /* 156: 0 */ "keyspec_popular_domain", + /* 157: 0 */ "morekeys_popular_domain", + /* 158: 0 */ "keyspecs_left_parenthesis_more_keys", + /* 159: 0 */ "keyspecs_right_parenthesis_more_keys", + /* 160: 0 */ "single_laqm_raqm", + /* 161: 0 */ "single_raqm_laqm", + /* 162: 0 */ "double_laqm_raqm", + /* 163: 0 */ "double_raqm_laqm", + /* 164: 0 */ "single_lqm_rqm", + /* 165: 0 */ "single_9qm_lqm", + /* 166: 0 */ "single_9qm_rqm", + /* 167: 0 */ "single_rqm_9qm", + /* 168: 0 */ "double_lqm_rqm", + /* 169: 0 */ "double_9qm_lqm", + /* 170: 0 */ "double_9qm_rqm", + /* 171: 0 */ "double_rqm_9qm", + /* 172: 0 */ "morekeys_single_quote", + /* 173: 0 */ "morekeys_double_quote", + /* 174: 0 */ "morekeys_tablet_double_quote", + /* 175: 0 */ "keyspec_emoji_action_key", }; private static final String EMPTY = ""; @@ -379,6 +387,14 @@ public final class KeyboardTextsTable { /* morekeys_greater_than */ "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_right_double_angle_quote", // U+00A1: "¡" INVERTED EXCLAMATION MARK /* morekeys_exclamation */ "\u00A1", + /* label_go_key */ "!string/label_go_key", + /* label_send_key */ "!string/label_send_key", + /* label_next_key */ "!string/label_next_key", + /* label_done_key */ "!string/label_done_key", + /* label_search_key */ "!string/label_search_key", + /* label_previous_key */ "!string/label_previous_key", + /* label_pause_key */ "!string/label_pause_key", + /* label_wait_key */ "!string/label_wait_key", /* morekeys_currency_generic */ "$,\u00A2,\u20AC,\u00A3,\u00A5,\u20B1", // U+00B9: "¹" SUPERSCRIPT ONE // U+00BD: "½" VULGAR FRACTION ONE HALF @@ -1885,6 +1901,24 @@ public final class KeyboardTextsTable { /* ~ morekeys_s */ // U+20B9: "₹" INDIAN RUPEE SIGN /* keyspec_currency */ "\u20B9", + /* morekeys_y ~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, + /* ~ morekeys_exclamation */ + /* label_go_key */ "Go", + /* label_send_key */ "Send", + /* label_next_key */ "Next", + /* label_done_key */ "Done", + /* label_search_key */ "Search", + /* label_previous_key */ "Prev", + /* label_pause_key */ "Pause", + /* label_wait_key */ "Wait", }; /* Locale hr: Croatian */ @@ -3952,7 +3986,7 @@ public final class KeyboardTextsTable { private static final Object[] LOCALES_AND_TEXTS = { // "locale", TEXT_ARRAY, /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */ - "DEFAULT", TEXTS_DEFAULT, /* 168/168 DEFAULT */ + "DEFAULT", TEXTS_DEFAULT, /* 176/176 DEFAULT */ "af" , TEXTS_af, /* 7/ 13 Afrikaans */ "ar" , TEXTS_ar, /* 55/110 Arabic */ "az_AZ" , TEXTS_az_AZ, /* 11/ 18 Azerbaijani (Azerbaijan) */ @@ -3974,7 +4008,7 @@ public final class KeyboardTextsTable { "fr" , TEXTS_fr, /* 13/ 62 French */ "gl_ES" , TEXTS_gl_ES, /* 7/ 8 Gallegan (Spain) */ "hi" , TEXTS_hi, /* 23/ 53 Hindi */ - "hi_ZZ" , TEXTS_hi_ZZ, /* 1/ 12 Hindi (ZZ) */ + "hi_ZZ" , TEXTS_hi_ZZ, /* 9/134 Hindi (ZZ) */ "hr" , TEXTS_hr, /* 9/ 20 Croatian */ "hu" , TEXTS_hu, /* 9/ 20 Hungarian */ "hy_AM" , TEXTS_hy_AM, /* 9/126 Armenian (Armenia) */ diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java index 96a6510fc..5a7f7662c 100644 --- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java @@ -167,7 +167,7 @@ public final class SubtypeLocaleUtils { return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId; } - private static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) { + public static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) { if (NO_LANGUAGE.equals(localeString)) { return sResources.getConfiguration().locale; } |