diff options
37 files changed, 416 insertions, 372 deletions
diff --git a/java/res/drawable-hdpi/ic_launcher_keyboard.png b/java/res/drawable-hdpi/ic_launcher_keyboard.png Binary files differindex e5d086c5a..7ae00ed3f 100644 --- a/java/res/drawable-hdpi/ic_launcher_keyboard.png +++ b/java/res/drawable-hdpi/ic_launcher_keyboard.png diff --git a/java/res/drawable-mdpi/ic_launcher_keyboard.png b/java/res/drawable-mdpi/ic_launcher_keyboard.png Binary files differindex d909eff35..cc73f3be1 100644 --- a/java/res/drawable-mdpi/ic_launcher_keyboard.png +++ b/java/res/drawable-mdpi/ic_launcher_keyboard.png diff --git a/java/res/drawable-xhdpi/ic_launcher_keyboard.png b/java/res/drawable-xhdpi/ic_launcher_keyboard.png Binary files differindex acdf0d827..f2ac50dfe 100644 --- a/java/res/drawable-xhdpi/ic_launcher_keyboard.png +++ b/java/res/drawable-xhdpi/ic_launcher_keyboard.png diff --git a/java/res/drawable-xxhdpi/ic_launcher_keyboard.png b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png Binary files differindex 23403581b..df386e827 100644 --- a/java/res/drawable-xxhdpi/ic_launcher_keyboard.png +++ b/java/res/drawable-xxhdpi/ic_launcher_keyboard.png diff --git a/java/res/xml-sw600dp/key_space_symbols.xml b/java/res/xml-sw600dp/key_space_symbols.xml index 07aa7d179..d6f7cab09 100644 --- a/java/res/xml-sw600dp/key_space_symbols.xml +++ b/java/res/xml-sw600dp/key_space_symbols.xml @@ -22,5 +22,6 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > <include + latin:backgroundType="normal" latin:keyboardLayout="@xml/key_space_5kw" /> </merge> diff --git a/java/res/xml-sw600dp/keys_comma_period.xml b/java/res/xml-sw600dp/keys_comma_period.xml index 7604e033d..5e8bbabb6 100644 --- a/java/res/xml-sw600dp/keys_comma_period.xml +++ b/java/res/xml-sw600dp/keys_comma_period.xml @@ -39,30 +39,13 @@ latin:keyStyle="hasShiftedLetterHintStyle" /> </case> <case - latin:languageCode="ar" + latin:languageCode="ar|fa" > <Key - latin:keyLabel="!text/keylabel_for_apostrophe" - latin:keyHintLabel="!text/keyhintlabel_for_apostrophe" - latin:moreKeys="!text/more_keys_for_apostrophe" - latin:backgroundType="functional" - latin:keyStyle="hasShiftedLetterHintStyle" /> - <Key - latin:keyLabel="." - latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics" - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_arabic_diacritics" - latin:backgroundType="functional" - latin:keyStyle="hasShiftedLetterHintStyle" /> - </case> - <case - latin:languageCode="fa" - > - <Key - latin:keyLabel="!text/keylabel_for_apostrophe" - latin:keyHintLabel="!text/keyhintlabel_for_apostrophe" + latin:keyLabel="!text/keylabel_for_tablet_comma" + latin:keyHintLabel="!text/keyhintlabel_for_tablet_comma" latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_apostrophe" + latin:moreKeys="!text/more_keys_for_tablet_comma" latin:backgroundType="functional" latin:keyStyle="hasShiftedLetterHintStyle" /> <Key @@ -90,14 +73,12 @@ <default> <Key latin:keyLabel="!text/keylabel_for_tablet_comma" - latin:keyHintLabel="!text/keyhintlabel_for_tablet_comma" - latin:backgroundType="functional" - latin:moreKeys="!text/more_keys_for_tablet_comma" /> + latin:moreKeys="!text/more_keys_for_tablet_comma" + latin:backgroundType="functional" /> <Key latin:keyLabel="." - latin:keyHintLabel="!text/keyhintlabel_for_period" - latin:backgroundType="functional" - latin:moreKeys="!text/more_keys_for_period" /> + latin:moreKeys="!text/more_keys_for_period" + latin:backgroundType="functional" /> </default> </switch> </merge> diff --git a/java/res/xml-sw600dp/keys_exclamation_question.xml b/java/res/xml-sw600dp/keys_exclamation_question.xml index cd38282ee..fd849222d 100644 --- a/java/res/xml-sw600dp/keys_exclamation_question.xml +++ b/java/res/xml-sw600dp/keys_exclamation_question.xml @@ -22,7 +22,9 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > <Key - latin:keyLabel="!" /> + latin:keyLabel="!" + latin:moreKeys="!text/more_keys_for_exclamation" /> <Key - latin:keyLabel="\?" /> + latin:keyLabel="\?" + latin:moreKeys="!text/more_keys_for_question" /> </merge> diff --git a/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml b/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml index 774ff8d05..46a1c85dc 100644 --- a/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml +++ b/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml @@ -40,7 +40,7 @@ latin:keyHintLabel="\?" latin:additionalMoreKeys="\?" latin:keyStyle="hasShiftedLetterHintStyle" - latin:moreKeys="!text/more_keys_for_symbols_question" /> + latin:moreKeys="!text/more_keys_for_question" /> </case> <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" --> <default> @@ -58,7 +58,7 @@ latin:moreKeys="!fixedColumnOrder!3,›,≥,»" /> <Key latin:keyLabel="\?" - latin:moreKeys="!text/more_keys_for_symbols_question" /> + latin:moreKeys="!text/more_keys_for_question" /> </default> </switch> </merge> diff --git a/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml b/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml index 254d3fdba..ae6bab79c 100644 --- a/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml +++ b/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml @@ -31,7 +31,7 @@ latin:keyHintLabel="!" latin:additionalMoreKeys="!" latin:keyStyle="hasShiftedLetterHintStyle" - latin:moreKeys="!text/more_keys_for_symbols_exclamation,!text/more_keys_for_symbols_1" /> + latin:moreKeys="!text/more_keys_for_exclamation,!text/more_keys_for_symbols_1" /> <Key latin:keyLabel="2" latin:keyHintLabel="\@" diff --git a/java/res/xml-sw600dp/rows_symbols.xml b/java/res/xml-sw600dp/rows_symbols.xml index cf94b06ed..7a33f4923 100644 --- a/java/res/xml-sw600dp/rows_symbols.xml +++ b/java/res/xml-sw600dp/rows_symbols.xml @@ -62,6 +62,7 @@ </Row> <Row latin:keyWidth="9.0%p" + latin:backgroundType="functional" > <Key latin:keyStyle="toAlphaKeyStyle" diff --git a/java/res/xml-sw600dp/rows_symbols_shift.xml b/java/res/xml-sw600dp/rows_symbols_shift.xml index 92299f65d..79d1aa142 100644 --- a/java/res/xml-sw600dp/rows_symbols_shift.xml +++ b/java/res/xml-sw600dp/rows_symbols_shift.xml @@ -64,6 +64,7 @@ </Row> <Row latin:keyWidth="9.0%p" + latin:backgroundType="functional" > <Key latin:keyStyle="toAlphaKeyStyle" diff --git a/java/res/xml/key_period.xml b/java/res/xml/key_period.xml new file mode 100644 index 000000000..7fc886d19 --- /dev/null +++ b/java/res/xml/key_period.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <switch> + <case + latin:languageCode="ar|fa" + > + <Key + latin:keyLabel="." + latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics" + latin:keyLabelFlags="hasPopupHint|hasShiftedLetterHint" + latin:moreKeys="!text/more_keys_for_arabic_diacritics" + latin:backgroundType="functional" /> + </case> + <case + latin:languageCode="ne" + latin:keyboardLayoutSet="nepali_traditional" + > + <include + latin:keyboardLayout="@xml/key_nepali_traditional_period" /> + </case> + <case + latin:languageCode="hy" + > + <!-- U+0589: "։" ARMENIAN FULL STOP --> + <Key + latin:keyLabel="։" + latin:keyLabelFlags="hasPopupHint" + latin:moreKeys="!text/more_keys_for_punctuation" + latin:backgroundType="functional" /> + </case> + <default> + <Key + latin:keyLabel="." + latin:keyLabelFlags="hasPopupHint" + latin:moreKeys="!text/more_keys_for_punctuation" + latin:backgroundType="functional" /> + </default> + </switch> +</merge> diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml index a3b6507ce..d538eb8c3 100644 --- a/java/res/xml/key_styles_common.xml +++ b/java/res/xml/key_styles_common.xml @@ -183,12 +183,6 @@ latin:code="!code/key_shift" latin:parentStyle="baseForToSymbolKeyStyle" /> <key-style - latin:styleName="punctuationKeyStyle" - latin:keyLabel="." - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_punctuation" - latin:backgroundType="functional" /> - <key-style latin:styleName="comKeyStyle" latin:keyLabel="!text/keylabel_for_popular_domain" latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase" diff --git a/java/res/xml/keys_comma_period.xml b/java/res/xml/keys_comma_period.xml deleted file mode 100644 index 1b51e45ed..000000000 --- a/java/res/xml/keys_comma_period.xml +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 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. -*/ ---> - -<merge - xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" -> - <switch> - <case - latin:languageCode="ar" - > - <Key - latin:keyLabel="!text/keylabel_for_apostrophe" - latin:keyHintLabel="!text/keyhintlabel_for_apostrophe" - latin:moreKeys="!text/more_keys_for_apostrophe" - latin:backgroundType="functional" - latin:keyStyle="hasShiftedLetterHintStyle" /> - <Key - latin:keyLabel="." - latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics" - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_arabic_diacritics" - latin:backgroundType="functional" - latin:keyStyle="hasShiftedLetterHintStyle" /> - </case> - <case - latin:languageCode="fa" - > - <Key - latin:keyLabel="!text/keylabel_for_apostrophe" - latin:keyHintLabel="!text/keyhintlabel_for_apostrophe" - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_apostrophe" - latin:backgroundType="functional" - latin:keyStyle="hasShiftedLetterHintStyle" /> - <Key - latin:keyLabel="." - latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics" - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_arabic_diacritics" - latin:backgroundType="functional" - latin:keyStyle="hasShiftedLetterHintStyle" /> - </case> - <case - latin:languageCode="hy" - > - <!-- U+055D: "՝" ARMENIAN COMMA --> - <Key - latin:keyLabel="՝" - latin:backgroundType="functional" /> - <!-- U+0589: "։" ARMENIAN FULL STOP --> - <Key - latin:keyLabel="։" - latin:keyLabelFlags="hasPopupHint" - latin:backgroundType="functional" - latin:moreKeys="!text/more_keys_for_punctuation" /> - </case> - <default> - <Key - latin:keyLabel="!text/keylabel_for_tablet_comma" - latin:keyHintLabel="!text/keyhintlabel_for_tablet_comma" - latin:backgroundType="functional" - latin:moreKeys="!text/more_keys_for_tablet_comma" /> - <Key - latin:keyLabel="." - latin:keyHintLabel="!text/keyhintlabel_for_period" - latin:backgroundType="functional" - latin:moreKeys="!text/more_keys_for_period" /> - </default> - </switch> -</merge> diff --git a/java/res/xml/keys_comma_period_symbols.xml b/java/res/xml/keys_comma_period_symbols.xml new file mode 100644 index 000000000..6465fedd1 --- /dev/null +++ b/java/res/xml/keys_comma_period_symbols.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <Key + latin:keyLabel="," + latin:backgroundType="functional" /> + <!-- U+2026: "…" HORIZONTAL ELLIPSIS --> + <Key + latin:keyLabel="." + latin:moreKeys="…" + latin:backgroundType="functional" /> +</merge> diff --git a/java/res/xml/keys_pcqwerty4_right3.xml b/java/res/xml/keys_pcqwerty4_right3.xml index e6084cb45..a5d5a429c 100644 --- a/java/res/xml/keys_pcqwerty4_right3.xml +++ b/java/res/xml/keys_pcqwerty4_right3.xml @@ -34,7 +34,7 @@ <Key latin:keyLabel="/" latin:additionalMoreKeys="\?" - latin:moreKeys="!text/more_keys_for_symbols_question" /> + latin:moreKeys="!text/more_keys_for_question" /> </case> <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" --> <default> @@ -52,7 +52,7 @@ latin:moreKeys="!fixedColumnOrder!3,›,≥,»" /> <Key latin:keyLabel="\?" - latin:moreKeys="!text/more_keys_for_symbols_question" /> + latin:moreKeys="!text/more_keys_for_question" /> </default> </switch> </merge> diff --git a/java/res/xml/row_qwerty4.xml b/java/res/xml/row_qwerty4.xml index 578bc1234..509092d96 100644 --- a/java/res/xml/row_qwerty4.xml +++ b/java/res/xml/row_qwerty4.xml @@ -32,36 +32,8 @@ <include latin:keyXPos="25%p" latin:keyboardLayout="@xml/key_space_5kw" /> - <switch> - <case - latin:languageCode="ar|fa" - > - <Key - latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics" - latin:keyLabelFlags="hasPopupHint|hasShiftedLetterHint" - latin:moreKeys="!text/more_keys_for_arabic_diacritics" - latin:keyStyle="punctuationKeyStyle" /> - </case> - <case - latin:languageCode="ne" - latin:keyboardLayoutSet="nepali_traditional" - > - <include - latin:keyboardLayout="@xml/key_nepali_traditional_period" /> - </case> - <case - latin:languageCode="hy" - > - <!-- U+0589: "։" ARMENIAN FULL STOP --> - <Key - latin:keyLabel="։" - latin:keyStyle="punctuationKeyStyle" /> - </case> - <default> - <Key - latin:keyStyle="punctuationKeyStyle" /> - </default> - </switch> + <include + latin:keyboardLayout="@xml/key_period" /> <Key latin:keyStyle="enterKeyStyle" latin:keyWidth="fillRight" /> diff --git a/java/res/xml/row_symbols4.xml b/java/res/xml/row_symbols4.xml index 73d93c89c..09d2a1971 100644 --- a/java/res/xml/row_symbols4.xml +++ b/java/res/xml/row_symbols4.xml @@ -19,15 +19,12 @@ --> <merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > - <Key - latin:backgroundType="functional" latin:keyLabel="_" /> <Key - latin:backgroundType="functional" latin:keyLabel="/" /> - - <include latin:keyboardLayout="@xml/key_space_symbols" /> - <include latin:keyboardLayout="@xml/keys_comma_period" /> - + <include + latin:keyboardLayout="@xml/key_space_symbols" /> + <include + latin:keyboardLayout="@xml/keys_comma_period_symbols" /> </merge> diff --git a/java/res/xml/row_symbols_shift4.xml b/java/res/xml/row_symbols_shift4.xml index 0909374f4..f75575bc6 100644 --- a/java/res/xml/row_symbols_shift4.xml +++ b/java/res/xml/row_symbols_shift4.xml @@ -22,5 +22,5 @@ <include latin:keyboardLayout="@xml/keys_less_greater" /> <include latin:keyboardLayout="@xml/key_space_symbols" /> - <include latin:keyboardLayout="@xml/keys_comma_period" /> + <include latin:keyboardLayout="@xml/keys_comma_period_symbols" /> </merge> diff --git a/java/res/xml/rowkeys_pcqwerty1.xml b/java/res/xml/rowkeys_pcqwerty1.xml index de548d0ba..1ac264afa 100644 --- a/java/res/xml/rowkeys_pcqwerty1.xml +++ b/java/res/xml/rowkeys_pcqwerty1.xml @@ -26,7 +26,7 @@ latin:additionalMoreKeys="~" /> <Key latin:keyLabel="1" - latin:additionalMoreKeys="!,!text/more_keys_for_symbols_exclamation" + latin:additionalMoreKeys="!,!text/more_keys_for_exclamation" latin:moreKeys="!text/more_keys_for_symbols_1" /> <Key latin:keyLabel="2" diff --git a/java/res/xml/rowkeys_pcqwerty1_shift.xml b/java/res/xml/rowkeys_pcqwerty1_shift.xml index bc39f944e..718acfd24 100644 --- a/java/res/xml/rowkeys_pcqwerty1_shift.xml +++ b/java/res/xml/rowkeys_pcqwerty1_shift.xml @@ -25,7 +25,7 @@ latin:keyLabel="~" /> <Key latin:keyLabel="!" - latin:additionalMoreKeys="!text/more_keys_for_symbols_exclamation" /> + latin:additionalMoreKeys="!text/more_keys_for_exclamation" /> <Key latin:keyLabel="\@" /> <Key diff --git a/java/res/xml/rowkeys_symbols3.xml b/java/res/xml/rowkeys_symbols3.xml index 074078cb6..e525dc480 100644 --- a/java/res/xml/rowkeys_symbols3.xml +++ b/java/res/xml/rowkeys_symbols3.xml @@ -55,8 +55,8 @@ latin:moreKeys="!text/more_keys_for_symbols_semicolon" /> <Key latin:keyLabel="!" - latin:moreKeys="!text/more_keys_for_symbols_exclamation" /> + latin:moreKeys="!text/more_keys_for_exclamation" /> <Key latin:keyLabel="!text/keylabel_for_symbols_question" - latin:moreKeys="!text/more_keys_for_symbols_question" /> + latin:moreKeys="!text/more_keys_for_question" /> </merge> diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java index 1ea4d3ac7..36a12addd 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java @@ -208,8 +208,8 @@ public final class KeyboardTextsSet { /* 103 */ "keylabel_for_symbols_question", /* 104 */ "keylabel_for_symbols_semicolon", /* 105 */ "keylabel_for_symbols_percent", - /* 106 */ "more_keys_for_symbols_exclamation", - /* 107 */ "more_keys_for_symbols_question", + /* 106 */ "more_keys_for_exclamation", + /* 107 */ "more_keys_for_question", /* 108 */ "more_keys_for_symbols_semicolon", /* 109 */ "more_keys_for_symbols_percent", /* 110 */ "keylabel_for_tablet_comma", @@ -217,47 +217,44 @@ public final class KeyboardTextsSet { /* 112 */ "more_keys_for_tablet_comma", /* 113 */ "keyhintlabel_for_period", /* 114 */ "more_keys_for_period", - /* 115 */ "keylabel_for_apostrophe", - /* 116 */ "keyhintlabel_for_apostrophe", - /* 117 */ "more_keys_for_apostrophe", - /* 118 */ "more_keys_for_q", - /* 119 */ "more_keys_for_x", - /* 120 */ "keylabel_for_q", - /* 121 */ "keylabel_for_w", - /* 122 */ "keylabel_for_y", - /* 123 */ "keylabel_for_x", - /* 124 */ "keylabel_for_spanish_row2_10", - /* 125 */ "more_keys_for_am_pm", - /* 126 */ "settings_as_more_key", - /* 127 */ "shortcut_as_more_key", - /* 128 */ "action_next_as_more_key", - /* 129 */ "action_previous_as_more_key", - /* 130 */ "label_to_more_symbol_key", - /* 131 */ "label_to_more_symbol_for_tablet_key", - /* 132 */ "label_tab_key", - /* 133 */ "label_to_phone_numeric_key", - /* 134 */ "label_to_phone_symbols_key", - /* 135 */ "label_time_am", - /* 136 */ "label_time_pm", - /* 137 */ "keylabel_for_popular_domain", - /* 138 */ "more_keys_for_popular_domain", - /* 139 */ "more_keys_for_smiley", - /* 140 */ "single_laqm_raqm", - /* 141 */ "single_laqm_raqm_rtl", - /* 142 */ "single_raqm_laqm", - /* 143 */ "double_laqm_raqm", - /* 144 */ "double_laqm_raqm_rtl", - /* 145 */ "double_raqm_laqm", - /* 146 */ "single_lqm_rqm", - /* 147 */ "single_9qm_lqm", - /* 148 */ "single_9qm_rqm", - /* 149 */ "double_lqm_rqm", - /* 150 */ "double_9qm_lqm", - /* 151 */ "double_9qm_rqm", - /* 152 */ "more_keys_for_single_quote", - /* 153 */ "more_keys_for_double_quote", - /* 154 */ "more_keys_for_tablet_double_quote", - /* 155 */ "emoji_key_as_more_key", + /* 115 */ "more_keys_for_q", + /* 116 */ "more_keys_for_x", + /* 117 */ "keylabel_for_q", + /* 118 */ "keylabel_for_w", + /* 119 */ "keylabel_for_y", + /* 120 */ "keylabel_for_x", + /* 121 */ "keylabel_for_spanish_row2_10", + /* 122 */ "more_keys_for_am_pm", + /* 123 */ "settings_as_more_key", + /* 124 */ "shortcut_as_more_key", + /* 125 */ "action_next_as_more_key", + /* 126 */ "action_previous_as_more_key", + /* 127 */ "label_to_more_symbol_key", + /* 128 */ "label_to_more_symbol_for_tablet_key", + /* 129 */ "label_tab_key", + /* 130 */ "label_to_phone_numeric_key", + /* 131 */ "label_to_phone_symbols_key", + /* 132 */ "label_time_am", + /* 133 */ "label_time_pm", + /* 134 */ "keylabel_for_popular_domain", + /* 135 */ "more_keys_for_popular_domain", + /* 136 */ "more_keys_for_smiley", + /* 137 */ "single_laqm_raqm", + /* 138 */ "single_laqm_raqm_rtl", + /* 139 */ "single_raqm_laqm", + /* 140 */ "double_laqm_raqm", + /* 141 */ "double_laqm_raqm_rtl", + /* 142 */ "double_raqm_laqm", + /* 143 */ "single_lqm_rqm", + /* 144 */ "single_9qm_lqm", + /* 145 */ "single_9qm_rqm", + /* 146 */ "double_lqm_rqm", + /* 147 */ "double_9qm_lqm", + /* 148 */ "double_9qm_rqm", + /* 149 */ "more_keys_for_single_quote", + /* 150 */ "more_keys_for_double_quote", + /* 151 */ "more_keys_for_tablet_double_quote", + /* 152 */ "emoji_key_as_more_key", }; private static final String EMPTY = ""; @@ -372,41 +369,38 @@ public final class KeyboardTextsSet { /* ~113 */ // U+2026: "…" HORIZONTAL ELLIPSIS /* 114 */ "\u2026", - /* 115 */ "\'", - /* 116 */ "\"", - /* 117 */ "\"", - /* 118 */ EMPTY, - /* 119 */ EMPTY, - /* 120 */ "q", - /* 121 */ "w", - /* 122 */ "y", - /* 123 */ "x", - /* 124 */ EMPTY, - /* 125 */ "!fixedColumnOrder!2,!hasLabels!,!text/label_time_am,!text/label_time_pm", - /* 126 */ "!icon/settings_key|!code/key_settings", - /* 127 */ "!icon/shortcut_key|!code/key_shortcut", - /* 128 */ "!hasLabels!,!text/label_next_key|!code/key_action_next", - /* 129 */ "!hasLabels!,!text/label_previous_key|!code/key_action_previous", + /* 115 */ EMPTY, + /* 116 */ EMPTY, + /* 117 */ "q", + /* 118 */ "w", + /* 119 */ "y", + /* 120 */ "x", + /* 121 */ EMPTY, + /* 122 */ "!fixedColumnOrder!2,!hasLabels!,!text/label_time_am,!text/label_time_pm", + /* 123 */ "!icon/settings_key|!code/key_settings", + /* 124 */ "!icon/shortcut_key|!code/key_shortcut", + /* 125 */ "!hasLabels!,!text/label_next_key|!code/key_action_next", + /* 126 */ "!hasLabels!,!text/label_previous_key|!code/key_action_previous", // Label for "switch to more symbol" modifier key. Must be short to fit on key! - /* 130 */ "= \\ <", + /* 127 */ "= \\ <", // Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! - /* 131 */ "~ [ <", + /* 128 */ "~ [ <", // Label for "Tab" key. Must be short to fit on key! - /* 132 */ "Tab", + /* 129 */ "Tab", // Label for "switch to phone numeric" key. Must be short to fit on key! - /* 133 */ "123", + /* 130 */ "123", // Label for "switch to phone symbols" key. Must be short to fit on key! // U+FF0A: "*" FULLWIDTH ASTERISK // U+FF03: "#" FULLWIDTH NUMBER SIGN - /* 134 */ "\uFF0A\uFF03", + /* 131 */ "\uFF0A\uFF03", // Key label for "ante meridiem" - /* 135 */ "AM", + /* 132 */ "AM", // Key label for "post meridiem" - /* 136 */ "PM", - /* 137 */ ".com", + /* 133 */ "PM", + /* 134 */ ".com", // popular web domains for the locale - most popular, displayed on the keyboard - /* 138 */ "!hasLabels!,.net,.org,.gov,.edu", - /* 139 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ", + /* 135 */ "!hasLabels!,.net,.org,.gov,.edu", + /* 136 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ", // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK @@ -428,25 +422,25 @@ public final class KeyboardTextsSet { // The following each quotation mark pair consist of // <opening quotation mark>, <closing quotation mark> // and is named after (single|double)_<opening quotation mark>_<closing quotation mark>. - /* 140 */ "\u2039,\u203A", - /* 141 */ "\u2039|\u203A,\u203A|\u2039", - /* 142 */ "\u203A,\u2039", - /* 143 */ "\u00AB,\u00BB", - /* 144 */ "\u00AB|\u00BB,\u00BB|\u00AB", - /* 145 */ "\u00BB,\u00AB", + /* 137 */ "\u2039,\u203A", + /* 138 */ "\u2039|\u203A,\u203A|\u2039", + /* 139 */ "\u203A,\u2039", + /* 140 */ "\u00AB,\u00BB", + /* 141 */ "\u00AB|\u00BB,\u00BB|\u00AB", + /* 142 */ "\u00BB,\u00AB", // The following each quotation mark triplet consists of // <another quotation mark>, <opening quotation mark>, <closing quotation mark> // and is named after (single|double)_<opening quotation mark>_<closing quotation mark>. - /* 146 */ "\u201A,\u2018,\u2019", - /* 147 */ "\u2019,\u201A,\u2018", - /* 148 */ "\u2018,\u201A,\u2019", - /* 149 */ "\u201E,\u201C,\u201D", - /* 150 */ "\u201D,\u201E,\u201C", - /* 151 */ "\u201C,\u201E,\u201D", - /* 152 */ "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes", - /* 153 */ "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes", - /* 154 */ "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes", - /* 155 */ "!icon/emoji_key|!code/key_emoji", + /* 143 */ "\u201A,\u2018,\u2019", + /* 144 */ "\u2019,\u201A,\u2018", + /* 145 */ "\u2018,\u201A,\u2019", + /* 146 */ "\u201E,\u201C,\u201D", + /* 147 */ "\u201D,\u201E,\u201C", + /* 148 */ "\u201C,\u201E,\u201D", + /* 149 */ "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes", + /* 150 */ "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes", + /* 151 */ "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes", + /* 152 */ "!icon/emoji_key|!code/key_emoji", }; /* Language af: Afrikaans */ @@ -523,9 +517,6 @@ public final class KeyboardTextsSet { /* 56~ */ null, null, null, /* ~58 */ - // U+061F: "؟" ARABIC QUESTION MARK - // U+060C: "،" ARABIC COMMA - // U+061B: "؛" ARABIC SEMICOLON /* 59 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(|),)|(", // U+2605: "★" BLACK STAR // U+066D: "٭" ARABIC FIVE POINTED STAR @@ -614,19 +605,17 @@ public final class KeyboardTextsSet { // U+066A: "٪" ARABIC PERCENT SIGN /* 105 */ "\u066A", /* 106 */ null, - /* 107 */ "?", + // U+00BF: "¿" INVERTED QUESTION MARK + /* 107 */ "?,\u00BF", /* 108 */ ";", // U+2030: "‰" PER MILLE SIGN /* 109 */ "\\%,\u2030", - /* 110~ */ - null, null, null, null, null, - /* ~114 */ + // U+061F: "؟" ARABIC QUESTION MARK // U+060C: "،" ARABIC COMMA // U+061B: "؛" ARABIC SEMICOLON - // U+061F: "؟" ARABIC QUESTION MARK - /* 115 */ "\u060C", - /* 116 */ "\u061F", - /* 117 */ "\u061F,\u061B,!,:,-,/,\',\"", + /* 110 */ "\u060C", + /* 111 */ "\u061F", + /* 112 */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\",\'", }; /* Language az: Azerbaijani */ @@ -804,10 +793,10 @@ public final class KeyboardTextsSet { /* ~113 */ /* 114 */ "?,\u00B7", /* 115~ */ - null, null, null, null, null, null, null, null, null, - /* ~123 */ + null, null, null, null, null, null, + /* ~120 */ // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA - /* 124 */ "\u00E7", + /* 121 */ "\u00E7", }; /* Language cs: Czech */ @@ -1206,20 +1195,20 @@ public final class KeyboardTextsSet { 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, - /* ~117 */ - /* 118 */ "q", - /* 119 */ "x", + null, null, null, null, null, + /* ~114 */ + /* 115 */ "q", + /* 116 */ "x", // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX - /* 120 */ "\u015D", + /* 117 */ "\u015D", // U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX - /* 121 */ "\u011D", + /* 118 */ "\u011D", // U+016D: "ŭ" LATIN SMALL LETTER U WITH BREVE - /* 122 */ "\u016D", + /* 119 */ "\u016D", // U+0109: "ĉ" LATIN SMALL LETTER C WITH CIRCUMFLEX - /* 123 */ "\u0109", + /* 120 */ "\u0109", // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX - /* 124 */ "\u0135", + /* 121 */ "\u0135", }; /* Language es: Spanish */ @@ -1282,26 +1271,16 @@ public final class KeyboardTextsSet { /* ~58 */ // U+00A1: "¡" INVERTED EXCLAMATION MARK // U+00BF: "¿" INVERTED QUESTION MARK - /* 59 */ "!fixedColumnOrder!4,;,!,\\,,?,:,\u00A1,@,\u00BF", + /* 59 */ "!fixedColumnOrder!9,\u00A1,;,/,(,),#,!,\\,,?,\u00BF,&,\\%,+,\",-,:,',@", /* 60~ */ 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, - /* ~111 */ - // U+00A1: "¡" INVERTED EXCLAMATION MARK - /* 112 */ "!,\u00A1", - /* 113 */ null, - // U+00BF: "¿" INVERTED QUESTION MARK - /* 114 */ "?,\u00BF", - /* 115 */ "\"", - /* 116 */ "\'", - /* 117 */ "\'", - /* 118~ */ - null, null, null, null, null, null, - /* ~123 */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, + /* ~120 */ // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE - /* 124 */ "\u00F1", + /* 121 */ "\u00F1", }; /* Language et: Estonian */ @@ -1523,7 +1502,8 @@ public final class KeyboardTextsSet { // U+066A: "٪" ARABIC PERCENT SIGN /* 105 */ "\u066A", /* 106 */ null, - /* 107 */ "?", + // U+00BF: "¿" INVERTED QUESTION MARK + /* 107 */ "?,\u00BF", /* 108 */ ";", // U+2030: "‰" PER MILLE SIGN /* 109 */ "\\%,\u2030", @@ -1533,13 +1513,10 @@ public final class KeyboardTextsSet { // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK /* 110 */ "\u060C", - /* 111 */ "!", - /* 112 */ "!,\\,", + /* 111 */ "\u061F", + /* 112 */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\u00AB|\u00BB,\u00BB|\u00AB", /* 113 */ "\u061F", /* 114 */ "\u061F,?", - /* 115 */ "\u060C", - /* 116 */ "\u061F", - /* 117 */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\u00AB|\u00BB,\u00BB|\u00AB", }; /* Language fi: Finnish */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h index 12d3579fd..b7bd08531 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h @@ -29,7 +29,7 @@ namespace latinime { class Ver4ShortcutListPolicy : public DictionaryShortcutsStructurePolicy { public: - Ver4ShortcutListPolicy(const ShortcutDictContent *const shortcutDictContent, + Ver4ShortcutListPolicy(ShortcutDictContent *const shortcutDictContent, const TerminalPositionLookupTable *const terminalPositionLookupTable) : mShortcutDictContent(shortcutDictContent), mTerminalPositionLookupTable(terminalPositionLookupTable) {} @@ -44,16 +44,11 @@ class Ver4ShortcutListPolicy : public DictionaryShortcutsStructurePolicy { void getNextShortcut(const int maxCodePointCount, int *const outCodePoint, int *const outCodePointCount, bool *const outIsWhitelist, bool *const outHasNext, int *const pos) const { - int shortcutFlags = 0; - if (outCodePoint && outCodePointCount) { - mShortcutDictContent->getShortcutEntryAndAdvancePosition(maxCodePointCount, - outCodePoint, outCodePointCount, &shortcutFlags, pos); - } - if (outHasNext) { - *outHasNext = ShortcutListReadingUtils::hasNext(shortcutFlags); - } + int probability = 0; + mShortcutDictContent->getShortcutEntryAndAdvancePosition(maxCodePointCount, + outCodePoint, outCodePointCount, &probability, outHasNext, pos); if (outIsWhitelist) { - *outIsWhitelist = ShortcutListReadingUtils::isWhitelist(shortcutFlags); + *outIsWhitelist = ShortcutListReadingUtils::isWhitelist(probability); } } @@ -61,10 +56,52 @@ class Ver4ShortcutListPolicy : public DictionaryShortcutsStructurePolicy { // Do nothing because we don't need to skip shortcut lists in ver4 dictionaries. } + bool addNewShortcut(const int terminalId, const int *const codePoints, const int codePointCount, + const int probability) { + const int shortcutListPos = mShortcutDictContent->getShortcutListHeadPos(terminalId); + if (shortcutListPos == NOT_A_DICT_POS) { + // Create shortcut list. + if (!mShortcutDictContent->createNewShortcutList(terminalId)) { + AKLOGE("Cannot create new shortcut list. terminal id: %d", terminalId); + return false; + } + const int writingPos = mShortcutDictContent->getShortcutListHeadPos(terminalId); + return mShortcutDictContent->writeShortcutEntry(codePoints, codePointCount, probability, + false /* hasNext */, writingPos); + } + const int entryPos = mShortcutDictContent->findShortcutEntryAndGetPos(shortcutListPos, + codePoints, codePointCount); + if (entryPos == NOT_A_DICT_POS) { + // Add new entry to the shortcut list. + // Create new shortcut list. + if (!mShortcutDictContent->createNewShortcutList(terminalId)) { + AKLOGE("Cannot create new shortcut list. terminal id: %d", terminalId); + return false; + } + int writingPos = mShortcutDictContent->getShortcutListHeadPos(terminalId); + if (!mShortcutDictContent->writeShortcutEntryAndAdvancePosition(codePoints, + codePointCount, probability, true /* hasNext */, &writingPos)) { + AKLOGE("Cannot write shortcut entry. terminal id: %d, pos: %d", terminalId, + writingPos); + return false; + } + return mShortcutDictContent->copyShortcutList(shortcutListPos, writingPos); + } + // Overwrite existing entry. + int writingPos = entryPos; + if (!mShortcutDictContent->writeShortcutEntryAndAdvancePosition(codePoints, + codePointCount, probability, true /* hasNext */, &writingPos)) { + AKLOGE("Cannot overwrite shortcut entry. terminal id: %d, pos: %d", terminalId, + writingPos); + return false; + } + return true; + } + private: DISALLOW_IMPLICIT_CONSTRUCTORS(Ver4ShortcutListPolicy); - const ShortcutDictContent *const mShortcutDictContent; + ShortcutDictContent *const mShortcutDictContent; const TerminalPositionLookupTable *const mTerminalPositionLookupTable; }; } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp index 14eff673c..eca69ec23 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp @@ -21,12 +21,16 @@ namespace latinime { void ShortcutDictContent::getShortcutEntryAndAdvancePosition(const int maxCodePointCount, - int *const outCodePoint, int *const outCodePointCount, int *const outShortcutFlags, - int *const shortcutEntryPos) const { + int *const outCodePoint, int *const outCodePointCount, int *const outProbability, + bool *const outhasNext, int *const shortcutEntryPos) const { const BufferWithExtendableBuffer *const shortcutListBuffer = getContentBuffer(); - if (outShortcutFlags) { - *outShortcutFlags = shortcutListBuffer->readUintAndAdvancePosition( - Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos); + const int shortcutFlags = shortcutListBuffer->readUintAndAdvancePosition( + Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos); + if (outProbability) { + *outProbability = shortcutFlags & Ver4DictConstants::SHORTCUT_PROBABILITY_MASK; + } + if (outhasNext) { + *outhasNext = shortcutFlags & Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK; } if (outCodePoint && outCodePointCount) { shortcutListBuffer->readCodePointsAndAdvancePosition( @@ -59,50 +63,113 @@ bool ShortcutDictContent::runGC( continue; } const int shortcutListPos = getContentBuffer()->getTailPosition(); - // Copy shortcut list with GC from original content. - if (!copyShortcutList(originalShortcutListPos, originalShortcutDictContent, + // Copy shortcut list from original content. + if (!copyShortcutListFromDictContent(originalShortcutListPos, originalShortcutDictContent, shortcutListPos)) { + AKLOGE("Cannot copy shortcut list during GC. original pos: %d, pos: %d", + originalShortcutListPos, shortcutListPos); return false; } // Set shortcut list position to the lookup table. if (!getUpdatableAddressLookupTable()->set(it->second, shortcutListPos)) { + AKLOGE("Cannot set shortcut list position. terminal id: %d, pos: %d", + it->second, shortcutListPos); return false; } } return true; } -bool ShortcutDictContent::copyShortcutList(const int shortcutListPos, +bool ShortcutDictContent::createNewShortcutList(const int terminalId) { + const int shortcutListListPos = getContentBuffer()->getTailPosition(); + return getUpdatableAddressLookupTable()->set(terminalId, shortcutListListPos); +} + +bool ShortcutDictContent::copyShortcutList(const int shortcutListPos, const int toPos) { + return copyShortcutListFromDictContent(shortcutListPos, this, toPos); +} + +bool ShortcutDictContent::copyShortcutListFromDictContent(const int shortcutListPos, const ShortcutDictContent *const sourceShortcutDictContent, const int toPos) { bool hasNext = true; int readingPos = shortcutListPos; int writingPos = toPos; int codePoints[MAX_WORD_LENGTH]; while (hasNext) { - int shortcutFlags = 0; + int probability = 0; int codePointCount = 0; sourceShortcutDictContent->getShortcutEntryAndAdvancePosition(MAX_WORD_LENGTH, - codePoints, &codePointCount, &shortcutFlags, &readingPos); - if (!writeShortcutEntryAndAdvancePosition(codePoints, codePointCount, shortcutFlags, - &writingPos)) { + codePoints, &codePointCount, &probability, &hasNext, &readingPos); + if (!writeShortcutEntryAndAdvancePosition(codePoints, codePointCount, probability, + hasNext, &writingPos)) { + AKLOGE("Cannot write shortcut entry to copy. pos: %d", writingPos); return false; } } return true; } +bool ShortcutDictContent::setProbability(const int probability, const int shortcutEntryPos) { + BufferWithExtendableBuffer *const shortcutListBuffer = getWritableContentBuffer(); + const int shortcutFlags = shortcutListBuffer->readUint( + Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos); + const bool hasNext = shortcutFlags & Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK; + const int shortcutFlagsToWrite = createAndGetShortcutFlags(probability, hasNext); + return shortcutListBuffer->writeUint(shortcutFlagsToWrite, + Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos); +} + bool ShortcutDictContent::writeShortcutEntryAndAdvancePosition(const int *const codePoint, - const int codePointCount, const int shortcutFlags, int *const shortcutEntryPos) { + const int codePointCount, const int probability, const bool hasNext, + int *const shortcutEntryPos) { BufferWithExtendableBuffer *const shortcutListBuffer = getWritableContentBuffer(); + const int shortcutFlags = createAndGetShortcutFlags(probability, hasNext); if (!shortcutListBuffer->writeUintAndAdvancePosition(shortcutFlags, Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos)) { + AKLOGE("Cannot write shortcut flags. flags; %x, pos: %d", shortcutFlags, *shortcutEntryPos); return false; } if (!shortcutListBuffer->writeCodePointsAndAdvancePosition(codePoint, codePointCount, true /* writesTerminator */, shortcutEntryPos)) { + AKLOGE("Cannot write shortcut target code points. pos: %d", *shortcutEntryPos); return false; } return true; } +// Find a shortcut entry that has specified target and return its position. +int ShortcutDictContent::findShortcutEntryAndGetPos(const int shortcutListPos, + const int *const targetCodePointsToFind, const int codePointCount) const { + bool hasNext = true; + int readingPos = shortcutListPos; + int targetCodePoints[MAX_WORD_LENGTH]; + while (hasNext) { + const int entryPos = readingPos; + int probability = 0; + int targetCodePointCount = 0; + getShortcutEntryAndAdvancePosition(MAX_WORD_LENGTH, targetCodePoints, &targetCodePointCount, + &probability, &hasNext, &readingPos); + if (targetCodePointCount != codePointCount) { + continue; + } + bool matched = true; + for (int i = 0; i < codePointCount; ++i) { + if (targetCodePointsToFind[i] != targetCodePoints[i]) { + matched = false; + break; + } + } + if (matched) { + return entryPos; + } + } + return NOT_A_DICT_POS; +} + +int ShortcutDictContent::createAndGetShortcutFlags(const int probability, + const bool hasNext) const { + return (probability & Ver4DictConstants::SHORTCUT_PROBABILITY_MASK) + | (hasNext ? Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK : 0); +} + } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h index 902016a1f..a4f817e28 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.h @@ -39,8 +39,8 @@ class ShortcutDictContent : public SparseTableDictContent { Ver4DictConstants::SHORTCUT_ADDRESS_TABLE_DATA_SIZE) {} void getShortcutEntryAndAdvancePosition(const int maxCodePointCount, - int *const outCodePoint, int *const outCodePointCount, int *const outShortcutFlags, - int *const shortcutEntryPos) const; + int *const outCodePoint, int *const outCodePointCount, int *const outProbability, + bool *const outhasNext, int *const shortcutEntryPos) const; // Returns head position of shortcut list for a PtNode specified by terminalId. int getShortcutListHeadPos(const int terminalId) const; @@ -50,14 +50,33 @@ class ShortcutDictContent : public SparseTableDictContent { bool runGC(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, const ShortcutDictContent *const originalShortcutDictContent); + bool createNewShortcutList(const int terminalId); + + bool copyShortcutList(const int shortcutListPos, const int toPos); + + bool setProbability(const int probability, const int shortcutEntryPos); + + bool writeShortcutEntry(const int *const codePoint, const int codePointCount, + const int probability, const bool hasNext, const int shortcutEntryPos) { + int writingPos = shortcutEntryPos; + return writeShortcutEntryAndAdvancePosition(codePoint, codePointCount, probability, + hasNext, &writingPos); + } + + bool writeShortcutEntryAndAdvancePosition(const int *const codePoint, + const int codePointCount, const int probability, const bool hasNext, + int *const shortcutEntryPos); + + int findShortcutEntryAndGetPos(const int shortcutListPos, + const int *const targetCodePointsToFind, const int codePointCount) const; + private: DISALLOW_COPY_AND_ASSIGN(ShortcutDictContent); - bool copyShortcutList(const int shortcutListPos, + bool copyShortcutListFromDictContent(const int shortcutListPos, const ShortcutDictContent *const sourceShortcutDictContent, const int toPos); - bool writeShortcutEntryAndAdvancePosition(const int *const codePoint, - const int codePointCount, const int shortcutFlags, int *const shortcutEntryPos); + int createAndGetShortcutFlags(const int probability, const bool hasNext) const; }; } // namespace latinime #endif /* LATINIME_SHORTCUT_DICT_CONTENT_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h index 40f6469fa..7e283f437 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h @@ -74,7 +74,7 @@ class Ver4DictBuffers { return &mExpandableTrieBuffer; } - AK_FORCE_INLINE TerminalPositionLookupTable *getUpdatableTerminalPositionLookupTable() { + AK_FORCE_INLINE TerminalPositionLookupTable *getMutableTerminalPositionLookupTable() { return &mTerminalPositionLookupTable; } @@ -82,7 +82,7 @@ class Ver4DictBuffers { return &mTerminalPositionLookupTable; } - AK_FORCE_INLINE ProbabilityDictContent *getUpdatableProbabilityDictContent() { + AK_FORCE_INLINE ProbabilityDictContent *getMutableProbabilityDictContent() { return &mProbabilityDictContent; } @@ -90,7 +90,7 @@ class Ver4DictBuffers { return &mProbabilityDictContent; } - AK_FORCE_INLINE BigramDictContent *getUpdatableBigramDictContent() { + AK_FORCE_INLINE BigramDictContent *getMutableBigramDictContent() { return &mBigramDictContent; } @@ -98,7 +98,7 @@ class Ver4DictBuffers { return &mBigramDictContent; } - AK_FORCE_INLINE ShortcutDictContent *getUpdatableShortcutDictContent() { + AK_FORCE_INLINE ShortcutDictContent *getMutableShortcutDictContent() { return &mShortcutDictContent; } diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp index 457f29667..d359caa5b 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp @@ -64,5 +64,7 @@ const int Ver4DictConstants::BIGRAM_HAS_NEXT_MASK = 0x80; const int Ver4DictConstants::BIGRAM_LARGE_PROBABILITY_FIELD_SIZE = 1; const int Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE = 1; +const int Ver4DictConstants::SHORTCUT_PROBABILITY_MASK = 0x0F; +const int Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK = 0x80; } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h index 536b713f7..5764bed95 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h @@ -62,6 +62,8 @@ class Ver4DictConstants { static const int BIGRAM_LARGE_PROBABILITY_FIELD_SIZE; static const int SHORTCUT_FLAGS_FIELD_SIZE; + static const int SHORTCUT_PROBABILITY_MASK; + static const int SHORTCUT_HAS_NEXT_MASK; private: DISALLOW_IMPLICIT_CONSTRUCTORS(Ver4DictConstants); diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp index 00ce06107..f6ea3b731 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp @@ -53,7 +53,7 @@ bool Ver4PatriciaTrieNodeWriter::markPtNodeAsDeleted( } if (toBeUpdatedPtNodeParams->isTerminal()) { // The PtNode is a terminal. Delete entry from the terminal position lookup table. - return mBuffers->getUpdatableTerminalPositionLookupTable()->setTerminalPtNodePosition( + return mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition( toBeUpdatedPtNodeParams->getTerminalId(), NOT_A_DICT_POS /* ptNodePos */); } else { return true; @@ -117,7 +117,7 @@ bool Ver4PatriciaTrieNodeWriter::updatePtNodeProbability( toBeUpdatedPtNodeParams->getTerminalId()); const ProbabilityEntry probabilityEntry = createUpdatedEntryFrom(&originalProbabilityEntry, newProbability, timestamp); - return mBuffers->getUpdatableProbabilityDictContent()->setProbabilityEntry( + return mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry( toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry); } @@ -152,7 +152,7 @@ bool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition( ProbabilityEntry newProbabilityEntry; const ProbabilityEntry probabilityEntryToWrite = createUpdatedEntryFrom( &newProbabilityEntry, ptNodeParams->getProbability(), timestamp); - return mBuffers->getUpdatableProbabilityDictContent()->setProbabilityEntry(terminalId, + return mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(terminalId, &probabilityEntryToWrite); } @@ -248,7 +248,7 @@ bool Ver4PatriciaTrieNodeWriter::writePtNodeAndGetTerminalIdAndAdvancePosition( const int isTerminal = terminalId != Ver4DictConstants::NOT_A_TERMINAL_ID; if (isTerminal) { // Update the lookup table. - if (!mBuffers->getUpdatableTerminalPositionLookupTable()->setTerminalPtNodePosition( + if (!mBuffers->getMutableTerminalPositionLookupTable()->setTerminalPtNodePosition( terminalId, nodePos)) { return false; } diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h index 8cbd4a657..78f3a553d 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h @@ -40,10 +40,10 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy { Ver4PatriciaTriePolicy(const Ver4DictBuffers::Ver4DictBuffersPtr &buffers) : mBuffers(buffers), mHeaderPolicy(mBuffers.get()->getHeaderPolicy()), mDictBuffer(mBuffers.get()->getWritableTrieBuffer()), - mBigramPolicy(mBuffers.get()->getUpdatableBigramDictContent(), + mBigramPolicy(mBuffers.get()->getMutableBigramDictContent(), mBuffers.get()->getTerminalPositionLookupTable(), mHeaderPolicy, mHeaderPolicy->isDecayingDict()), - mShortcutPolicy(mBuffers.get()->getShortcutDictContent(), + mShortcutPolicy(mBuffers.get()->getMutableShortcutDictContent(), mBuffers.get()->getTerminalPositionLookupTable()), mNodeReader(mDictBuffer, mBuffers.get()->getProbabilityDictContent()), mNodeWriter(mDictBuffer, mBuffers.get(), &mNodeReader, &mBigramPolicy, diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp index 1f38be54c..2a80784f8 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp @@ -80,9 +80,9 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, int *const outUnigramCount, int *const outBigramCount, const bool needsToDecay) { Ver4PatriciaTrieNodeReader ptNodeReader(mBuffers->getTrieBuffer(), mBuffers->getProbabilityDictContent()); - Ver4BigramListPolicy bigramPolicy(mBuffers->getUpdatableBigramDictContent(), + Ver4BigramListPolicy bigramPolicy(mBuffers->getMutableBigramDictContent(), mBuffers->getTerminalPositionLookupTable(), headerPolicy, needsToDecay); - Ver4ShortcutListPolicy shortcutPolicy(mBuffers->getShortcutDictContent(), + Ver4ShortcutListPolicy shortcutPolicy(mBuffers->getMutableShortcutDictContent(), mBuffers->getTerminalPositionLookupTable()); Ver4PatriciaTrieNodeWriter ptNodeWriter(mBuffers->getWritableTrieBuffer(), mBuffers, &ptNodeReader, &bigramPolicy, &shortcutPolicy, @@ -133,32 +133,32 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos, // Create policy instances for the GCed dictionary. Ver4PatriciaTrieNodeReader newPtNodeReader(buffersToWrite->getTrieBuffer(), buffersToWrite->getProbabilityDictContent()); - Ver4BigramListPolicy newBigramPolicy(buffersToWrite->getUpdatableBigramDictContent(), + Ver4BigramListPolicy newBigramPolicy(buffersToWrite->getMutableBigramDictContent(), buffersToWrite->getTerminalPositionLookupTable(), headerPolicy, false /* needsToDecay */); - Ver4ShortcutListPolicy newShortcutPolicy(buffersToWrite->getShortcutDictContent(), + Ver4ShortcutListPolicy newShortcutPolicy(buffersToWrite->getMutableShortcutDictContent(), buffersToWrite->getTerminalPositionLookupTable()); Ver4PatriciaTrieNodeWriter newPtNodeWriter(buffersToWrite->getWritableTrieBuffer(), buffersToWrite, &newPtNodeReader, &newBigramPolicy, &newShortcutPolicy, false /* needsToDecayWhenUpdating */); // Re-assign terminal IDs for valid terminal PtNodes. TerminalPositionLookupTable::TerminalIdMap terminalIdMap; - if(!buffersToWrite->getUpdatableTerminalPositionLookupTable()->runGCTerminalIds( + if(!buffersToWrite->getMutableTerminalPositionLookupTable()->runGCTerminalIds( &terminalIdMap)) { return false; } // Run GC for probability dict content. - if (!buffersToWrite->getUpdatableProbabilityDictContent()->runGC(&terminalIdMap, + if (!buffersToWrite->getMutableProbabilityDictContent()->runGC(&terminalIdMap, mBuffers->getProbabilityDictContent())) { return false; } // Run GC for bigram dict content. - if(!buffersToWrite->getUpdatableBigramDictContent()->runGC(&terminalIdMap, + if(!buffersToWrite->getMutableBigramDictContent()->runGC(&terminalIdMap, mBuffers->getBigramDictContent(), outBigramCount)) { return false; } // Run GC for shortcut dict content. - if(!buffersToWrite->getUpdatableShortcutDictContent()->runGC(&terminalIdMap, + if(!buffersToWrite->getMutableShortcutDictContent()->runGC(&terminalIdMap, mBuffers->getShortcutDictContent())) { return false; } diff --git a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml index 8b86b1ba2..010459fd2 100644 --- a/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-ar/donottranslate-more-keys.xml @@ -69,20 +69,18 @@ <string name="keylabel_for_symbols_semicolon">؛</string> <!-- U+066A: "٪" ARABIC PERCENT SIGN --> <string name="keylabel_for_symbols_percent">٪</string> - <string name="more_keys_for_symbols_question">\?</string> + <!-- U+00BF: "¿" INVERTED QUESTION MARK --> + <string name="more_keys_for_question">\?,¿</string> <string name="more_keys_for_symbols_semicolon">;</string> <!-- U+2030: "‰" PER MILLE SIGN --> <string name="more_keys_for_symbols_percent">\\%,‰</string> - <!-- U+060C: "،" ARABIC COMMA - U+061B: "؛" ARABIC SEMICOLON - U+061F: "؟" ARABIC QUESTION MARK --> - <string name="keylabel_for_apostrophe">،</string> - <string name="keyhintlabel_for_apostrophe">؟</string> <!-- U+061F: "؟" ARABIC QUESTION MARK U+060C: "،" ARABIC COMMA U+061B: "؛" ARABIC SEMICOLON --> + <string name="keylabel_for_tablet_comma">"،"</string> + <string name="keyhintlabel_for_tablet_comma">"؟"</string> + <string name="more_keys_for_tablet_comma">"!fixedColumnOrder!4,:,!,؟,؛,-,/,\",\'"</string> <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,\",\',#,-,:,!,،,؟,\@,&,\\%,+,؛,/,(|),)|("</string> - <string name="more_keys_for_apostrophe">"؟,؛,!,:,-,/,\',\""</string> <!-- U+266A: "♪" EIGHTH NOTE --> <string name="more_keys_for_bullet">♪</string> <!-- U+2605: "★" BLACK STAR diff --git a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml index 8e6b4ee06..deae87939 100644 --- a/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-es/donottranslate-more-keys.xml @@ -71,12 +71,5 @@ <string name="keylabel_for_spanish_row2_10">ñ</string> <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_punctuation">"!fixedColumnOrder!4,;,!,\\,,\?,:,¡,\@,¿"</string> - <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK --> - <string name="more_keys_for_tablet_comma">"!,¡"</string> - <!-- U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_period">"\?,¿"</string> - <string name="keylabel_for_apostrophe">\"</string> - <string name="keyhintlabel_for_apostrophe">\'</string> - <string name="more_keys_for_apostrophe">\'</string> + <string name="more_keys_for_punctuation">"!fixedColumnOrder!9,¡,;,/,(,),#,!,\\,,\?,¿,&,\\%,+,\",-,:,',\@"</string> </resources> diff --git a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml index ab4fbda44..9a46ae15a 100644 --- a/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-fa/donottranslate-more-keys.xml @@ -69,7 +69,8 @@ <string name="keylabel_for_symbols_semicolon">؛</string> <!-- U+066A: "٪" ARABIC PERCENT SIGN --> <string name="keylabel_for_symbols_percent">٪</string> - <string name="more_keys_for_symbols_question">\?</string> + <!-- U+00BF: "¿" INVERTED QUESTION MARK --> + <string name="more_keys_for_question">\?,¿</string> <string name="more_keys_for_symbols_semicolon">;</string> <!-- U+2030: "‰" PER MILLE SIGN --> <string name="more_keys_for_symbols_percent">\\%,‰</string> @@ -79,13 +80,10 @@ U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK --> <string name="keylabel_for_tablet_comma">"،"</string> - <string name="keyhintlabel_for_tablet_comma">"!"</string> - <string name="more_keys_for_tablet_comma">"!,\\,"</string> + <string name="keyhintlabel_for_tablet_comma">"؟"</string> + <string name="more_keys_for_tablet_comma">"!fixedColumnOrder!4,:,!,؟,؛,-,/,«|»,»|«"</string> <string name="keyhintlabel_for_period">"؟"</string> <string name="more_keys_for_period">"؟,\?"</string> - <string name="keylabel_for_apostrophe">،</string> - <string name="keyhintlabel_for_apostrophe">؟</string> - <string name="more_keys_for_apostrophe">"!fixedColumnOrder!4,:,!,؟,؛,-,/,«|»,»|«"</string> <!-- U+FDFC: "﷼" RIAL SIGN --> <string name="keylabel_for_currency">﷼</string> <!-- U+061F: "؟" ARABIC QUESTION MARK diff --git a/tools/make-keyboard-text/res/values-hy/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-hy/donottranslate-more-keys.xml index 2f34128bd..67072ec78 100644 --- a/tools/make-keyboard-text/res/values-hy/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values-hy/donottranslate-more-keys.xml @@ -29,10 +29,10 @@ <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,!,?,\\,,.,֊,՜,՝,՞,:,;,\@,ՙ,՚,՛,՟"</string> <!-- U+055E: "՞" ARMENIAN QUESTION MARK --> <!-- U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_symbols_question">՞,¿</string> + <string name="more_keys_for_question">՞,¿</string> <!-- U+055C: "՜" ARMENIAN EXCLAMATION MARK --> <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK --> - <string name="more_keys_for_symbols_exclamation">՜,¡</string> + <string name="more_keys_for_exclamation">՜,¡</string> <!-- U+058F: "֏" ARMENIAN DRAM SIGN --> <!-- TODO: Enable this when we have glyph for the following letter <string name="keylabel_for_currency">֏</string> diff --git a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml index 5f687db99..9b74416cb 100644 --- a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml @@ -166,9 +166,9 @@ <string name="keylabel_for_symbols_semicolon">;</string> <string name="keylabel_for_symbols_percent">%</string> <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK --> - <string name="more_keys_for_symbols_exclamation">¡</string> + <string name="more_keys_for_exclamation">¡</string> <!-- U+00BF: "¿" INVERTED QUESTION MARK --> - <string name="more_keys_for_symbols_question">¿</string> + <string name="more_keys_for_question">¿</string> <string name="more_keys_for_symbols_semicolon"></string> <!-- U+2030: "‰" PER MILLE SIGN --> <string name="more_keys_for_symbols_percent">‰</string> @@ -178,9 +178,6 @@ <string name="keyhintlabel_for_period"></string> <!-- U+2026: "…" HORIZONTAL ELLIPSIS --> <string name="more_keys_for_period">…</string> - <string name="keylabel_for_apostrophe">\'</string> - <string name="keyhintlabel_for_apostrophe">\"</string> - <string name="more_keys_for_apostrophe">\"</string> <string name="more_keys_for_q"></string> <string name="more_keys_for_x"></string> <string name="keylabel_for_q">q</string> |