aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.mk16
-rw-r--r--java/AndroidManifest.xml5
-rw-r--r--java/proguard.flags2
-rw-r--r--java/res/anim/more_keys_keyboard_fadein.xml (renamed from java/res/anim/mini_keyboard_fadein.xml)2
-rw-r--r--java/res/anim/more_keys_keyboard_fadeout.xml (renamed from java/res/anim/mini_keyboard_fadeout.xml)2
-rw-r--r--java/res/layout/input_view.xml2
-rw-r--r--java/res/layout/more_keys_keyboard.xml (renamed from java/res/layout/mini_keyboard.xml)6
-rw-r--r--java/res/layout/more_suggestions.xml4
-rw-r--r--java/res/values-af/strings.xml31
-rw-r--r--java/res/values-am/strings.xml27
-rw-r--r--java/res/values-ar/donottranslate-more-keys.xml71
-rw-r--r--java/res/values-ar/donottranslate.xml25
-rw-r--r--java/res/values-ar/strings.xml27
-rw-r--r--java/res/values-be/donottranslate-more-keys.xml (renamed from java/res/values-de-rZZ/donottranslate-more-keys.xml)4
-rw-r--r--java/res/values-be/strings.xml27
-rw-r--r--java/res/values-bg/strings.xml27
-rw-r--r--java/res/values-ca/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-ca/strings.xml27
-rw-r--r--java/res/values-cs/donottranslate-more-keys.xml14
-rw-r--r--java/res/values-cs/strings.xml27
-rw-r--r--java/res/values-da/donottranslate-more-keys.xml11
-rw-r--r--java/res/values-da/strings.xml26
-rw-r--r--java/res/values-de/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-de/strings.xml27
-rw-r--r--java/res/values-el/strings.xml27
-rw-r--r--java/res/values-en-rGB/strings.xml26
-rw-r--r--java/res/values-en/additional-proximitychars.xml62
-rw-r--r--java/res/values-en/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-en/whitelist.xml4
-rw-r--r--java/res/values-es-rUS/strings.xml37
-rw-r--r--java/res/values-es/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-es/strings.xml26
-rw-r--r--java/res/values-et/donottranslate-more-keys.xml42
-rw-r--r--java/res/values-et/strings.xml27
-rw-r--r--java/res/values-fa/strings.xml27
-rw-r--r--java/res/values-fi/donottranslate-more-keys.xml5
-rw-r--r--java/res/values-fi/strings.xml29
-rw-r--r--java/res/values-fr/donottranslate-more-keys.xml15
-rw-r--r--java/res/values-fr/strings.xml27
-rw-r--r--java/res/values-hi/strings.xml27
-rw-r--r--java/res/values-hr/donottranslate-more-keys.xml2
-rw-r--r--java/res/values-hr/strings.xml33
-rw-r--r--java/res/values-hu/donottranslate-more-keys.xml10
-rw-r--r--java/res/values-hu/strings.xml27
-rw-r--r--java/res/values-in/strings.xml27
-rw-r--r--java/res/values-it/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-it/strings.xml27
-rw-r--r--java/res/values-iw/donottranslate-more-keys.xml37
-rw-r--r--java/res/values-iw/donottranslate.xml25
-rw-r--r--java/res/values-iw/strings.xml27
-rw-r--r--java/res/values-ja/strings.xml27
-rw-r--r--java/res/values-ko/strings.xml27
-rw-r--r--java/res/values-ky/donottranslate-more-keys.xml (renamed from java/res/values-fr-rCA/donottranslate-more-keys.xml)7
-rw-r--r--java/res/values-land/dimens.xml5
-rw-r--r--java/res/values-lt/donottranslate-more-keys.xml21
-rw-r--r--java/res/values-lt/strings.xml27
-rw-r--r--java/res/values-lv/donottranslate-more-keys.xml24
-rw-r--r--java/res/values-lv/strings.xml27
-rw-r--r--java/res/values-ms/strings.xml27
-rw-r--r--java/res/values-nb/donottranslate-more-keys.xml7
-rw-r--r--java/res/values-nb/strings.xml26
-rw-r--r--java/res/values-nl/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-nl/strings.xml27
-rw-r--r--java/res/values-pl/donottranslate-more-keys.xml4
-rw-r--r--java/res/values-pl/strings.xml29
-rw-r--r--java/res/values-pt-rPT/strings.xml27
-rw-r--r--java/res/values-pt/donottranslate-more-keys.xml8
-rw-r--r--java/res/values-pt/strings.xml27
-rw-r--r--java/res/values-rm/donottranslate-more-keys.xml2
-rw-r--r--java/res/values-rm/strings.xml71
-rw-r--r--java/res/values-ro/donottranslate-more-keys.xml6
-rw-r--r--java/res/values-ro/strings.xml27
-rw-r--r--java/res/values-ru/donottranslate-more-keys.xml4
-rw-r--r--java/res/values-ru/strings.xml35
-rw-r--r--java/res/values-sk/donottranslate-more-keys.xml26
-rw-r--r--java/res/values-sk/strings.xml27
-rw-r--r--java/res/values-sl/donottranslate-more-keys.xml (renamed from java/res/values-fr-rCH/donottranslate-more-keys.xml)9
-rw-r--r--java/res/values-sl/strings.xml27
-rw-r--r--java/res/values-sr/strings.xml27
-rw-r--r--java/res/values-sv/donottranslate-more-keys.xml7
-rw-r--r--java/res/values-sv/strings.xml27
-rw-r--r--java/res/values-sw/strings.xml27
-rw-r--r--java/res/values-sw600dp-land/dimens.xml1
-rw-r--r--java/res/values-sw600dp/config.xml12
-rw-r--r--java/res/values-sw600dp/dimens.xml7
-rw-r--r--java/res/values-sw768dp-land/dimens.xml1
-rw-r--r--java/res/values-sw768dp/config.xml12
-rw-r--r--java/res/values-sw768dp/dimens.xml7
-rw-r--r--java/res/values-th/strings.xml27
-rw-r--r--java/res/values-tl/strings.xml27
-rw-r--r--java/res/values-tr/donottranslate-more-keys.xml6
-rw-r--r--java/res/values-tr/strings.xml27
-rw-r--r--java/res/values-uk/donottranslate-more-keys.xml23
-rw-r--r--java/res/values-uk/strings.xml27
-rw-r--r--java/res/values-vi/donottranslate-more-keys.xml28
-rw-r--r--java/res/values-vi/strings.xml27
-rw-r--r--java/res/values-zh-rCN/strings.xml27
-rw-r--r--java/res/values-zh-rTW/strings.xml29
-rw-r--r--java/res/values-zu/strings.xml27
-rw-r--r--java/res/values/additional-proximitychars.xml23
-rw-r--r--java/res/values/attrs.xml168
-rw-r--r--java/res/values/config.xml57
-rw-r--r--java/res/values/dimens.xml13
-rw-r--r--java/res/values/donottranslate-more-keys.xml88
-rw-r--r--java/res/values/donottranslate.xml6
-rw-r--r--java/res/values/keyboard-icons-black.xml7
-rw-r--r--java/res/values/keyboard-icons-ics.xml9
-rw-r--r--java/res/values/keyboard-icons-white.xml8
-rw-r--r--java/res/values/keycodes.xml11
-rw-r--r--java/res/values/strings.xml79
-rw-r--r--java/res/values/styles.xml165
-rw-r--r--java/res/values/themes-basic-highcontrast.xml8
-rw-r--r--java/res/values/themes-basic.xml8
-rw-r--r--java/res/values/themes-gingerbread.xml8
-rw-r--r--java/res/values/themes-ics.xml8
-rw-r--r--java/res/values/themes-stone-bold.xml8
-rw-r--r--java/res/values/themes-stone.xml8
-rw-r--r--java/res/xml-ar/keyboard_set.xml42
-rw-r--r--java/res/xml-be/keyboard_set.xml42
-rw-r--r--java/res/xml-bg/keyboard_set.xml42
-rw-r--r--java/res/xml-cs/keyboard_set.xml42
-rw-r--r--java/res/xml-da/keyboard_set.xml42
-rw-r--r--java/res/xml-de-rZZ/keyboard_set.xml42
-rw-r--r--java/res/xml-de/kbd_qwerty.xml27
-rw-r--r--java/res/xml-de/keyboard_set.xml42
-rw-r--r--java/res/xml-es/kbd_qwerty.xml27
-rw-r--r--java/res/xml-es/keyboard_set.xml42
-rw-r--r--java/res/xml-et/keyboard_set.xml42
-rw-r--r--java/res/xml-fi/kbd_qwerty.xml27
-rw-r--r--java/res/xml-fi/keyboard_set.xml42
-rw-r--r--java/res/xml-fr-rCA/kbd_qwerty.xml27
-rw-r--r--java/res/xml-fr-rCA/keyboard_set.xml42
-rw-r--r--java/res/xml-fr-rCH/kbd_qwerty.xml27
-rw-r--r--java/res/xml-fr-rCH/keyboard_set.xml42
-rw-r--r--java/res/xml-fr/keyboard_set.xml42
-rw-r--r--java/res/xml-hr/kbd_qwerty.xml28
-rw-r--r--java/res/xml-hr/keyboard_set.xml42
-rw-r--r--java/res/xml-hu/keyboard_set.xml42
-rw-r--r--java/res/xml-iw/kbd_qwerty.xml28
-rw-r--r--java/res/xml-iw/kbd_symbols.xml27
-rw-r--r--java/res/xml-iw/kbd_symbols_shift.xml27
-rw-r--r--java/res/xml-iw/keyboard_set.xml42
-rw-r--r--java/res/xml-ky/keyboard_set.xml42
-rw-r--r--java/res/xml-land/kbd_number.xml2
-rw-r--r--java/res/xml-land/kbd_phone.xml2
-rw-r--r--java/res/xml-land/kbd_phone_symbols.xml (renamed from java/res/xml-land/kbd_phone_shift.xml)2
-rw-r--r--java/res/xml-nb/kbd_qwerty.xml27
-rw-r--r--java/res/xml-nb/keyboard_set.xml42
-rw-r--r--java/res/xml-pl/keyboard_set.xml42
-rw-r--r--java/res/xml-pt/kbd_qwerty.xml27
-rw-r--r--java/res/xml-pt/keyboard_set.xml42
-rw-r--r--java/res/xml-ro/keyboard_set.xml42
-rw-r--r--java/res/xml-ru/kbd_qwerty.xml27
-rw-r--r--java/res/xml-ru/keyboard_set.xml42
-rw-r--r--java/res/xml-sk/keyboard_set.xml42
-rw-r--r--java/res/xml-sl/keyboard_set.xml42
-rw-r--r--java/res/xml-sr/kbd_qwerty.xml27
-rw-r--r--java/res/xml-sr/keyboard_set.xml42
-rw-r--r--java/res/xml-sv/kbd_qwerty.xml27
-rw-r--r--java/res/xml-sv/keyboard_set.xml42
-rw-r--r--java/res/xml-sw600dp-land/kbd_more_keys_keyboard_template.xml (renamed from java/res/xml-sw600dp-land/kbd_mini_keyboard_template.xml)2
-rw-r--r--java/res/xml-sw600dp-land/kbd_number.xml (renamed from java/res/xml-ar/kbd_symbols.xml)5
-rw-r--r--java/res/xml-sw600dp-land/kbd_phone.xml (renamed from java/res/xml-ar/kbd_qwerty.xml)6
-rw-r--r--java/res/xml-sw600dp-land/kbd_phone_symbols.xml29
-rw-r--r--java/res/xml-sw600dp/kbd_more_keys_keyboard_template.xml (renamed from java/res/xml-sw600dp/kbd_mini_keyboard_template.xml)2
-rw-r--r--java/res/xml-sw600dp/kbd_number.xml186
-rw-r--r--java/res/xml-sw600dp/kbd_phone.xml100
-rw-r--r--java/res/xml-sw600dp/kbd_phone_symbols.xml28
-rw-r--r--java/res/xml-sw600dp/key_f2.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_f2.xml)0
-rw-r--r--java/res/xml-sw600dp/key_smiley.xml (renamed from java/res/xml-sw600dp/kbd_row3_smiley.xml)16
-rw-r--r--java/res/xml-sw600dp/key_styles_common.xml (renamed from java/res/xml-sw600dp/kbd_key_styles.xml)85
-rw-r--r--java/res/xml-sw600dp/keys_apostrophe_dash.xml (renamed from java/res/xml-sw768dp/kbd_row4_apostrophe_dash.xml)12
-rw-r--r--java/res/xml-sw600dp/row_qwerty1.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_row1.xml)9
-rw-r--r--java/res/xml-sw600dp/row_qwerty2.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_row2.xml)2
-rw-r--r--java/res/xml-sw600dp/row_qwerty3.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_row3.xml)6
-rw-r--r--java/res/xml-sw600dp/row_qwerty4.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_row4.xml)10
-rw-r--r--java/res/xml-sw600dp/rows_arabic.xml (renamed from java/res/xml-sw600dp/kbd_rows_arabic.xml)39
-rw-r--r--java/res/xml-sw600dp/rows_azerty.xml (renamed from java/res/xml-sw600dp/kbd_rows_azerty.xml)46
-rw-r--r--java/res/xml-sw600dp/rows_bulgarian.xml117
-rw-r--r--java/res/xml-sw600dp/rows_hebrew.xml (renamed from java/res/xml-sw600dp/kbd_rows_hebrew.xml)46
-rw-r--r--java/res/xml-sw600dp/rows_number_normal.xml138
-rw-r--r--java/res/xml-sw600dp/rows_number_password.xml81
-rw-r--r--java/res/xml-sw600dp/rows_phone.xml (renamed from java/res/xml-sw600dp/kbd_phone_shift.xml)51
-rw-r--r--java/res/xml-sw600dp/rows_qwerty.xml (renamed from java/res/xml-sw600dp/kbd_rows_qwerty.xml)10
-rw-r--r--java/res/xml-sw600dp/rows_qwertz.xml (renamed from java/res/xml-sw600dp/kbd_rows_qwertz.xml)43
-rw-r--r--java/res/xml-sw600dp/rows_scandinavian.xml (renamed from java/res/xml-sw600dp/kbd_rows_scandinavian.xml)25
-rw-r--r--java/res/xml-sw600dp/rows_serbian.xml (renamed from java/res/xml-sw600dp/kbd_rows_serbian.xml)12
-rw-r--r--java/res/xml-sw600dp/rows_slavic.xml (renamed from java/res/xml-sw600dp/kbd_rows_russian.xml)52
-rw-r--r--java/res/xml-sw600dp/rows_spanish.xml (renamed from java/res/xml-sw600dp/kbd_rows_spanish.xml)10
-rw-r--r--java/res/xml-sw600dp/rows_symbols.xml (renamed from java/res/xml-sw600dp/kbd_rows_symbols.xml)42
-rw-r--r--java/res/xml-sw600dp/rows_symbols_shift.xml (renamed from java/res/xml-sw600dp/kbd_rows_symbols_shift.xml)20
-rw-r--r--java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml (renamed from java/res/xml-sw768dp-land/kbd_mini_keyboard_template.xml)2
-rw-r--r--java/res/xml-sw768dp-land/kbd_number.xml28
-rw-r--r--java/res/xml-sw768dp-land/kbd_phone.xml (renamed from java/res/xml-ar/kbd_symbols_shift.xml)5
-rw-r--r--java/res/xml-sw768dp-land/kbd_phone_symbols.xml29
-rw-r--r--java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml (renamed from java/res/xml-sw768dp/kbd_mini_keyboard_template.xml)2
-rw-r--r--java/res/xml-sw768dp/kbd_number.xml203
-rw-r--r--java/res/xml-sw768dp/kbd_phone.xml119
-rw-r--r--java/res/xml-sw768dp/kbd_phone_symbols.xml (renamed from java/res/xml-da/kbd_qwerty.xml)5
-rw-r--r--java/res/xml-sw768dp/kbd_row3_comma_period.xml46
-rw-r--r--java/res/xml-sw768dp/key_styles_common.xml (renamed from java/res/xml-sw768dp/kbd_key_styles.xml)97
-rw-r--r--java/res/xml-sw768dp/keys_apostrophe_dash.xml (renamed from java/res/xml-sw600dp/kbd_row4_apostrophe_dash.xml)12
-rw-r--r--java/res/xml-sw768dp/row_qwerty1.xml (renamed from java/res/xml-sw768dp/kbd_qwerty_row1.xml)11
-rw-r--r--java/res/xml-sw768dp/row_qwerty2.xml (renamed from java/res/xml-sw768dp/kbd_qwerty_row2.xml)4
-rw-r--r--java/res/xml-sw768dp/row_qwerty3.xml (renamed from java/res/xml-sw768dp/kbd_qwerty_row3.xml)2
-rw-r--r--java/res/xml-sw768dp/row_qwerty4.xml (renamed from java/res/xml-sw768dp/kbd_qwerty_row4.xml)12
-rw-r--r--java/res/xml-sw768dp/rows_arabic.xml (renamed from java/res/xml-sw768dp/kbd_rows_arabic.xml)10
-rw-r--r--java/res/xml-sw768dp/rows_azerty.xml (renamed from java/res/xml-sw768dp/kbd_rows_azerty.xml)47
-rw-r--r--java/res/xml-sw768dp/rows_bulgarian.xml (renamed from java/res/xml-sw768dp/kbd_rows_russian.xml)85
-rw-r--r--java/res/xml-sw768dp/rows_hebrew.xml (renamed from java/res/xml-sw768dp/kbd_rows_hebrew.xml)12
-rw-r--r--java/res/xml-sw768dp/rows_number_normal.xml159
-rw-r--r--java/res/xml-sw768dp/rows_number_password.xml79
-rw-r--r--java/res/xml-sw768dp/rows_phone.xml (renamed from java/res/xml-sw768dp/kbd_phone_shift.xml)31
-rw-r--r--java/res/xml-sw768dp/rows_qwerty.xml (renamed from java/res/xml-sw768dp/kbd_rows_qwerty.xml)10
-rw-r--r--java/res/xml-sw768dp/rows_qwertz.xml (renamed from java/res/xml-sw768dp/kbd_rows_qwertz.xml)41
-rw-r--r--java/res/xml-sw768dp/rows_scandinavian.xml (renamed from java/res/xml-sw768dp/kbd_rows_scandinavian.xml)23
-rw-r--r--java/res/xml-sw768dp/rows_serbian.xml (renamed from java/res/xml-sw768dp/kbd_rows_serbian.xml)12
-rw-r--r--java/res/xml-sw768dp/rows_slavic.xml131
-rw-r--r--java/res/xml-sw768dp/rows_spanish.xml (renamed from java/res/xml-sw768dp/kbd_rows_spanish.xml)12
-rw-r--r--java/res/xml-sw768dp/rows_symbols.xml (renamed from java/res/xml-sw768dp/kbd_rows_symbols.xml)44
-rw-r--r--java/res/xml-sw768dp/rows_symbols_shift.xml (renamed from java/res/xml-sw768dp/kbd_rows_symbols_shift.xml)22
-rw-r--r--java/res/xml-tr/kbd_qwerty.xml27
-rw-r--r--java/res/xml-tr/keyboard_set.xml42
-rw-r--r--java/res/xml-uk/keyboard_set.xml42
-rw-r--r--java/res/xml-vi/keyboard_set.xml42
-rw-r--r--java/res/xml/kbd_arabic.xml (renamed from java/res/xml-de-rZZ/kbd_qwerty.xml)3
-rw-r--r--java/res/xml/kbd_azerty.xml (renamed from java/res/xml-pl/kbd_qwerty.xml)3
-rw-r--r--java/res/xml/kbd_bulgarian.xml (renamed from java/res/xml-fr/kbd_qwerty.xml)7
-rw-r--r--java/res/xml/kbd_hebrew.xml (renamed from java/res/xml-hu/kbd_qwerty.xml)3
-rw-r--r--java/res/xml/kbd_more_keys_keyboard_template.xml (renamed from java/res/xml/kbd_mini_keyboard_template.xml)2
-rw-r--r--java/res/xml/kbd_number.xml2
-rw-r--r--java/res/xml/kbd_phone.xml2
-rw-r--r--java/res/xml/kbd_phone_symbols.xml (renamed from java/res/xml/kbd_phone_shift.xml)2
-rw-r--r--java/res/xml/kbd_qwerty.xml3
-rw-r--r--java/res/xml/kbd_qwertz.xml (renamed from java/res/xml-cs/kbd_qwerty.xml)3
-rw-r--r--java/res/xml/kbd_rows_number.xml132
-rw-r--r--java/res/xml/kbd_scandinavian.xml26
-rw-r--r--java/res/xml/kbd_serbian.xml26
-rw-r--r--java/res/xml/kbd_slavic.xml26
-rw-r--r--java/res/xml/kbd_spanish.xml26
-rw-r--r--java/res/xml/kbd_symbols.xml2
-rw-r--r--java/res/xml/kbd_symbols_shift.xml2
-rw-r--r--java/res/xml/key_f1.xml (renamed from java/res/xml/kbd_qwerty_f1.xml)0
-rw-r--r--java/res/xml/key_settings_or_tab.xml (renamed from java/res/xml/kbd_settings_or_tab.xml)3
-rw-r--r--java/res/xml/key_styles_common.xml (renamed from java/res/xml/kbd_key_styles.xml)126
-rw-r--r--java/res/xml/key_styles_currency.xml (renamed from java/res/xml/kbd_currency_key_styles.xml)10
-rw-r--r--java/res/xml/key_styles_currency_dollar.xml (renamed from java/res/xml/kbd_currency_dollar_key_styles.xml)0
-rw-r--r--java/res/xml/key_styles_currency_euro.xml (renamed from java/res/xml/kbd_currency_euro_key_styles.xml)0
-rw-r--r--java/res/xml/key_styles_enter_phone.xml124
-rw-r--r--java/res/xml/key_styles_enter_tablet.xml111
-rw-r--r--java/res/xml/key_styles_number.xml (renamed from java/res/xml/kbd_numkey_styles.xml)46
-rw-r--r--java/res/xml/key_symbols_f1.xml (renamed from java/res/xml/kbd_symbols_f1.xml)0
-rw-r--r--java/res/xml/keyboard_set.xml42
-rw-r--r--java/res/xml/keys_comma_period.xml (renamed from java/res/xml-sw600dp/kbd_row3_comma_period.xml)10
-rw-r--r--java/res/xml/keys_curly_brackets.xml30
-rw-r--r--java/res/xml/keys_less_greater.xml32
-rw-r--r--java/res/xml/keys_parentheses.xml32
-rw-r--r--java/res/xml/keys_square_brackets.xml30
-rw-r--r--java/res/xml/method.xml73
-rw-r--r--java/res/xml/prefs_for_debug.xml6
-rw-r--r--java/res/xml/row_qwerty1.xml (renamed from java/res/xml/kbd_qwerty_row1.xml)13
-rw-r--r--java/res/xml/row_qwerty2.xml (renamed from java/res/xml/kbd_qwerty_row2.xml)0
-rw-r--r--java/res/xml/row_qwerty3.xml (renamed from java/res/xml/kbd_qwerty_row3.xml)0
-rw-r--r--java/res/xml/row_qwerty4.xml (renamed from java/res/xml/kbd_qwerty_row4.xml)10
-rw-r--r--java/res/xml/row_symbols4.xml (renamed from java/res/xml/kbd_symbols_row4.xml)10
-rw-r--r--java/res/xml/row_symbols_shift4.xml (renamed from java/res/xml/kbd_symbols_shift_row4.xml)10
-rw-r--r--java/res/xml/rows_arabic.xml (renamed from java/res/xml/kbd_rows_arabic.xml)28
-rw-r--r--java/res/xml/rows_azerty.xml (renamed from java/res/xml/kbd_rows_azerty.xml)27
-rw-r--r--java/res/xml/rows_bulgarian.xml129
-rw-r--r--java/res/xml/rows_hebrew.xml (renamed from java/res/xml/kbd_rows_hebrew.xml)4
-rw-r--r--java/res/xml/rows_number.xml41
-rw-r--r--java/res/xml/rows_number_normal.xml81
-rw-r--r--java/res/xml/rows_number_password.xml62
-rw-r--r--java/res/xml/rows_phone.xml (renamed from java/res/xml/kbd_rows_phone.xml)8
-rw-r--r--java/res/xml/rows_phone_symbols.xml (renamed from java/res/xml/kbd_rows_phone_shift.xml)19
-rw-r--r--java/res/xml/rows_qwerty.xml (renamed from java/res/xml/kbd_rows_qwerty.xml)10
-rw-r--r--java/res/xml/rows_qwertz.xml (renamed from java/res/xml/kbd_rows_qwertz.xml)19
-rw-r--r--java/res/xml/rows_scandinavian.xml (renamed from java/res/xml/kbd_rows_scandinavian.xml)24
-rw-r--r--java/res/xml/rows_serbian.xml (renamed from java/res/xml/kbd_rows_serbian.xml)24
-rw-r--r--java/res/xml/rows_slavic.xml (renamed from java/res/xml/kbd_rows_russian.xml)44
-rw-r--r--java/res/xml/rows_spanish.xml (renamed from java/res/xml/kbd_rows_spanish.xml)8
-rw-r--r--java/res/xml/rows_symbols.xml (renamed from java/res/xml/kbd_rows_symbols.xml)33
-rw-r--r--java/res/xml/rows_symbols_shift.xml (renamed from java/res/xml/kbd_rows_symbols_shift.xml)28
-rw-r--r--java/res/xml/spell_checker_settings.xml6
-rw-r--r--java/res/xml/spellchecker.xml15
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java25
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java96
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java18
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java104
-rw-r--r--java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java1
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java143
-rw-r--r--java/src/com/android/inputmethod/compat/ArraysCompatUtils.java15
-rw-r--r--java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java81
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java3
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java14
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java43
-rw-r--r--java/src/com/android/inputmethod/deprecated/VoiceProxy.java50
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java6
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/FieldContext.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java501
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java126
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java1255
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java254
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java362
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java735
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java278
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboard.java339
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java589
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java23
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java (renamed from java/src/com/android/inputmethod/keyboard/MiniKeyboard.java)95
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java (renamed from java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java)45
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java440
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java175
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java (renamed from java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java)58
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java394
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java217
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java893
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java132
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java190
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java588
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java18
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/MoreKeySpecParser.java230
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java51
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java4
-rw-r--r--java/src/com/android/inputmethod/latin/AutoCorrection.java15
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java30
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java6
-rw-r--r--java/src/com/android/inputmethod/latin/ComposingStateManager.java7
-rw-r--r--java/src/com/android/inputmethod/latin/DebugSettings.java3
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryCollection.java22
-rw-r--r--java/src/com/android/inputmethod/latin/EditingUtils.java17
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java8
-rw-r--r--java/src/com/android/inputmethod/latin/InputAttributes.java105
-rw-r--r--java/src/com/android/inputmethod/latin/LastComposedWord.java74
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java1386
-rw-r--r--java/src/com/android/inputmethod/latin/LatinImeLogger.java20
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java335
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java371
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java9
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java95
-rw-r--r--java/src/com/android/inputmethod/latin/TextEntryState.java237
-rw-r--r--java/src/com/android/inputmethod/latin/UserBigramDictionary.java10
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java70
-rw-r--r--java/src/com/android/inputmethod/latin/UserUnigramDictionary.java12
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java290
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java190
-rw-r--r--java/src/com/android/inputmethod/latin/XmlParseUtils.java77
-rw-r--r--java/src/com/android/inputmethod/latin/define/JniLibName.java21
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java254
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java198
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java (renamed from java/src/com/android/inputmethod/latin/MoreSuggestions.java)45
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java (renamed from java/src/com/android/inputmethod/latin/MoreSuggestionsView.java)16
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java (renamed from java/src/com/android/inputmethod/latin/SuggestionsView.java)239
356 files changed, 11982 insertions, 9279 deletions
diff --git a/java/Android.mk b/java/Android.mk
index e9fa52ef3..fd71d82e0 100644
--- a/java/Android.mk
+++ b/java/Android.mk
@@ -1,3 +1,17 @@
+# Copyright (C) 2011 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.
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -9,7 +23,9 @@ LOCAL_PACKAGE_NAME := LatinIME
LOCAL_CERTIFICATE := shared
+# We want to package libjni_latinime.so into the apk.
LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime
+# We want to install libjni_latinime.so to the system partition if LatinIME gets installed.
LOCAL_REQUIRED_MODULES := libjni_latinime
LOCAL_STATIC_JAVA_LIBRARIES := android-common
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index b0525326c..e663c90f2 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -5,16 +5,15 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
- <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
- <application android:label="@string/english_ime_name"
+ <application android:label="@string/aosp_android_keyboard_ime_name"
android:icon="@drawable/ic_ime_settings"
android:backupAgent="BackupAgent"
android:killAfterRestore="false">
<service android:name="LatinIME"
- android:label="@string/english_ime_name"
+ android:label="@string/aosp_android_keyboard_ime_name"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
diff --git a/java/proguard.flags b/java/proguard.flags
index 33af890ec..5ce0c273c 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -35,6 +35,6 @@
*;
}
--keep class com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder$MiniKeyboardParams {
+-keep class com.android.inputmethod.keyboard.MoreKeysKeyboard$Builder$MoreKeysKeyboardParams {
<init>(...);
}
diff --git a/java/res/anim/mini_keyboard_fadein.xml b/java/res/anim/more_keys_keyboard_fadein.xml
index f80e8b8de..c781f36ad 100644
--- a/java/res/anim/mini_keyboard_fadein.xml
+++ b/java/res/anim/more_keys_keyboard_fadein.xml
@@ -25,5 +25,5 @@
<alpha
android:fromAlpha="0.5"
android:toAlpha="1.0"
- android:duration="@integer/config_mini_keyboard_fadein_anim_time" />
+ android:duration="@integer/config_more_keys_keyboard_fadein_anim_time" />
</set>
diff --git a/java/res/anim/mini_keyboard_fadeout.xml b/java/res/anim/more_keys_keyboard_fadeout.xml
index 535b100ae..32fae6bd8 100644
--- a/java/res/anim/mini_keyboard_fadeout.xml
+++ b/java/res/anim/more_keys_keyboard_fadeout.xml
@@ -25,5 +25,5 @@
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
- android:duration="@integer/config_mini_keyboard_fadeout_anim_time" />
+ android:duration="@integer/config_more_keys_keyboard_fadeout_anim_time" />
</set>
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index 2e0cddc28..b9451f8ae 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -43,7 +43,7 @@
android:layout_width="@dimen/suggestions_strip_padding"
android:layout_height="@dimen/suggestions_strip_height"
style="?attr/suggestionsStripBackgroundStyle" />
- <com.android.inputmethod.latin.SuggestionsView
+ <com.android.inputmethod.latin.suggestions.SuggestionsView
android:id="@+id/suggestions_view"
android:layout_weight="1.0"
android:layout_width="0dp"
diff --git a/java/res/layout/mini_keyboard.xml b/java/res/layout/more_keys_keyboard.xml
index 6964ec5d6..89161c6b4 100644
--- a/java/res/layout/mini_keyboard.xml
+++ b/java/res/layout/more_keys_keyboard.xml
@@ -22,11 +22,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
- style="?attr/miniKeyboardPanelStyle"
+ style="?attr/moreKeysKeyboardPanelStyle"
>
- <com.android.inputmethod.keyboard.MiniKeyboardView
+ <com.android.inputmethod.keyboard.MoreKeysKeyboardView
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/mini_keyboard_view"
+ android:id="@+id/more_keys_keyboard_view"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/java/res/layout/more_suggestions.xml b/java/res/layout/more_suggestions.xml
index 6aa82e197..34f54f974 100644
--- a/java/res/layout/more_suggestions.xml
+++ b/java/res/layout/more_suggestions.xml
@@ -22,9 +22,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
- style="?attr/miniKeyboardPanelStyle"
+ style="?attr/moreKeysKeyboardPanelStyle"
>
- <com.android.inputmethod.latin.MoreSuggestionsView
+ <com.android.inputmethod.latin.suggestions.MoreSuggestionsView
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
android:id="@+id/more_suggestions_view"
android:layout_alignParentBottom="true"
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 36c9d4bc4..0ca0e9005 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android-sleutelbord"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-sleutelbord (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android-sleutelbordinstellings"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Invoeropsies"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android-korrigering"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Speltoetser se instellings"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Gebruik nabyheidsdata"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Gebruik \'n sleutelbordagtige nabyheidsalgoritme vir die speltoetser"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Soek kontakname op"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Speltoetser gebruik inskrywings uit jou kontaklys"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibreer met sleuteldruk"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Klank met sleuteldruk"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Opspring met sleuteldruk"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Gestoor"</string>
<string name="label_go_key" msgid="1635148082137219148">"Gaan"</string>
<string name="label_next_key" msgid="362972844525672568">"Volgende"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Klaar"</string>
<string name="label_send_key" msgid="2815056534433717444">"Stuur"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Steminvoering"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Glimlag-gesiggie"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Tydperk"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Links-hakie"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Regs-hakie"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dubbelpunt"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Kommapunt"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Uitroepteken"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Vraagteken"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dubbel-aanhalingsteken"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Enkel-aanhalingsteken"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Vierkantswortel"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Handelsmerk"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Per adres"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Ster"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Pond"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellips"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Onderste dubbel-aanhalingsteken"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Steminvoering"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Steminvoering vir jou taal word nie tans ondersteun nie, maar werk wel in Engels."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Steminvoer gebruik Google se spraakherkenning. "<a href="http://m.google.com/privacy">"Die Mobiel-privaatheidsbeleid"</a>" is van toepassing."</string>
@@ -144,10 +128,9 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Aktiveer gebruikerterugvoer"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Help hierdie invoermetode-redigeerder te verbeter deur gebruikstatistiek en omvalverslae outomaties na Google te stuur."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Sleutelbordtema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Duitse QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engels (VK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engels (VS)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruikbaarheidstudie-modus"</string>
- <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Vibrasie-tydsduur met sleuteldruk"</string>
- <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Volume met sleuteldruk"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Sleuteldruk se vibrasie-tydsduurinstellings"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Sleuteldruk se klankvolume-instellings"</string>
</resources>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index d5280bc64..ea64daeff 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"የAndroid ቁልፍሰሌዳ"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"የAndroid ቁልፍ ሰሌዳ (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"የAndroid ቁልፍሰሌዳ ቅንብሮች"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"ግቤት አማራጮች"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"የAndroid ማስተካከያ"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"የፊደል አራሚ ቅንብሮች"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"የቀረቤታ ውሂብ ተጠቀም"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"ለፊደል አራሚ የሰሌዳ ቁልፍ አይነት የቀረበ ስልተ ቀመር ተጠቀም"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"የእውቅያ ስሞችን ተመልከት"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"ፊደል አራሚ ከእውቅያ ዝርዝርህ የገቡትን ይጠቀማል"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"በቁልፍመጫንጊዜ አንዝር"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"በቁልፍ መጫን ላይ የሚወጣ ድምፅ"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"ቁልፍ ጫን ላይ ብቅ ባይ"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ተቀምጧል"</string>
<string name="label_go_key" msgid="1635148082137219148">"ሂድ"</string>
<string name="label_next_key" msgid="362972844525672568">"በመቀጠል"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"ተከናውኗል"</string>
<string name="label_send_key" msgid="2815056534433717444">" ይላኩ"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"የድምፅ ግቤ ት"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"የፈገግታ ፊት"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"ተመለስ"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"ነጠላ ሰረዝ"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"ክፍለ ጊዜ"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"የግራ ቅንፍ"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"የቀኝ ቅንፍ"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"ሁለት ነጥብ"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"ድርብ ሰረዝ"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"ቃል አጋኖ"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"ጥያቄ ምልክት"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"ድርብ ጥቅስ"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"ነጠላ ትምህርተ ጥቅስ"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"ነጥብ"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"ስክዌር ሩት"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"ዴልታ"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"የንግድምልክት"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"መጠንቀቅ"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"ኮከብ"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"ፓውንድ"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"ዝቅ ያለ ድርብ ትምህርተ ጥቅስ"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"የድምፅ ግቤ ት"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"የድምፅ ግቤት በአሁኑ ጊዜ ለእርስዎን ቋንቋ አይደግፍም፣ ግን በእንግሊዘኛ ይሰራል።"</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"የድምፅ ግቤት የGoogleን ንግግር ለይቶ ማወቂያ ይጠቀማል።"<a href="http://m.google.com/privacy">"የተንቀሳቃሽ ስልክ ግላዊ ፖሊሲ"</a>" ይተገበራል።"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"የተጠቃሚ ግብረ ምላሽ አንቃ"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"ወደ Google የተሰናከለ ሪፖርቶች እና አጠቃቀም ስታስቲክስ በራስ ሰር በመላክ ይህን ግቤት ሜተድ አርትኢ እገዛ ያሻሽላል።"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"የቁልፍ ሰሌዳ ገጽታ"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"የጀመርን QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"እንግሊዘኛ (የታላቋ ብሪታንያ)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"እንግሊዘኛ (ዩ.ኤስ)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"የተገልጋይነት ጥናት ሁነታ"</string>
diff --git a/java/res/values-ar/donottranslate-more-keys.xml b/java/res/values-ar/donottranslate-more-keys.xml
index cde686084..df093b3c9 100644
--- a/java/res/values-ar/donottranslate-more-keys.xml
+++ b/java/res/values-ar/donottranslate-more-keys.xml
@@ -38,7 +38,7 @@
<!-- In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. -->
<!-- TODO: Will introduce "grouping marks" to the more characters specification. -->
<string name="more_keys_for_punctuation">"\u060c,\u061b,\u061f,!,:,-,/,\',\",\u0640\u0640\u0640|\u0640,\u064e,\u0650,\u064b,\u064d,\u0670,\u0656,\u0655,\u0654,\u0653,\u0652,\u0651,\u064c,\u064f"</string>
- <integer name="mini_keyboard_column_for_punctuation">9</integer>
+ <integer name="more_keys_keyboard_column_for_punctuation">9</integer>
<string name="keyhintlabel_for_punctuation">\u064b</string>
<string name="keylabel_for_symbols_1">"١"</string>
<string name="keylabel_for_symbols_2">"٢"</string>
@@ -50,18 +50,18 @@
<string name="keylabel_for_symbols_8">"٨"</string>
<string name="keylabel_for_symbols_9">"٩"</string>
<string name="keylabel_for_symbols_0">"٠"</string>
- <string name="more_keys_for_symbols_1">1</string>
- <string name="more_keys_for_symbols_2">2</string>
- <string name="more_keys_for_symbols_3">3</string>
- <string name="more_keys_for_symbols_4">4</string>
- <string name="more_keys_for_symbols_5">5</string>
- <string name="more_keys_for_symbols_6">6</string>
- <string name="more_keys_for_symbols_7">7</string>
- <string name="more_keys_for_symbols_8">8</string>
- <string name="more_keys_for_symbols_9">9</string>
+ <string name="additional_more_keys_for_symbols_1">1</string>
+ <string name="additional_more_keys_for_symbols_2">2</string>
+ <string name="additional_more_keys_for_symbols_3">3</string>
+ <string name="additional_more_keys_for_symbols_4">4</string>
+ <string name="additional_more_keys_for_symbols_5">5</string>
+ <string name="additional_more_keys_for_symbols_6">6</string>
+ <string name="additional_more_keys_for_symbols_7">7</string>
+ <string name="additional_more_keys_for_symbols_8">8</string>
+ <string name="additional_more_keys_for_symbols_9">9</string>
<!-- \u066b: ARABIC DECIMAL SEPARATOR
\u066c: ARABIC THOUSANDS SEPARATOR -->
- <string name="more_keys_for_symbols_0">0,\u066b,\u066c</string>
+ <string name="additional_more_keys_for_symbols_0">0,\u066b,\u066c</string>
<string name="keylabel_for_comma">\u060c</string>
<string name="keylabel_for_f1">\u060c</string>
<string name="keylabel_for_symbols_question">\u061f</string>
@@ -70,10 +70,8 @@
<string name="keylabel_for_symbols_percent">\u066a</string>
<string name="more_keys_for_comma">,</string>
<string name="more_keys_for_f1">,</string>
- <!-- @icon/3 is iconSettingsKey -->
- <string name="more_keys_for_f1_settings">\\,,\@icon/3|\@integer/key_settings</string>
- <!-- @icon/7 is iconTabKey -->
- <string name="more_keys_for_f1_navigate">\\,,\@icon/7|\@integer/key_tab</string>
+ <string name="more_keys_for_f1_settings">\\,,\@icon/settingsKey|\@integer/key_settings</string>
+ <string name="more_keys_for_f1_navigate">\\,,\@icon/tabKey|\@integer/key_tab</string>
<string name="more_keys_for_symbols_question">\?</string>
<string name="more_keys_for_symbols_semicolon">;</string>
<string name="more_keys_for_symbols_percent">%,‰</string>
@@ -104,8 +102,43 @@
<string name="more_keys_for_bullet">♪</string>
<!-- \u066d: ARABIC FIVE POINTED STAR -->
<string name="more_keys_for_star">★,\u066d</string>
- <!-- \ufd3e: ORNATE LEFT PARENTHESIS -->
- <string name="more_keys_for_left_parenthesis">[,{,&lt;,\ufd3e</string>
- <!-- \ufd3f: ORNATE RIGHT PARENTHESIS -->
- <string name="more_keys_for_right_parenthesis">],},&gt;,\ufd3f</string>
+ <!-- The all letters need to be mirrored are found at
+ http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+ <integer name="keycode_for_left_parenthesis">0x0029</integer>
+ <integer name="keycode_for_right_parenthesis">0x0028</integer>
+ <!-- \ufd3e: ORNATE LEFT PARENTHESIS
+ \ufd3f: ORNATE RIGHT PARENTHESIS -->
+ <string name="more_keys_for_left_parenthesis">[|],{|},&lt;|&gt;,\ufd3e|\ufd3f</string>
+ <string name="more_keys_for_right_parenthesis">]|[,}|{,&gt;|&lt;,\ufd3f|\ufd3e</string>
+ <integer name="keycode_for_less_than">0x003e</integer>
+ <integer name="keycode_for_greater_than">0x003c</integer>
+ <!-- \u2264: LESS-THAN OR EQUAL TO
+ \u2265: GREATER-THAN EQUAL TO
+ \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ The following characters don't need BIDI mirroring.
+ \u2018: LEFT SINGLE QUOTATION MARK
+ \u2019: RIGHT SINGLE QUOTATION MARK
+ \u201a: SINGLE LOW-9 QUOTATION MARK
+ \u201b: SINGLE HIGH-REVERSED-9 QUOTATION MARK
+ \u201c: LEFT DOUBLE QUOTATION MARK
+ \u201d: RIGHT DOUBLE QUOTATION MARK
+ \u201e: DOUBLE LOW-9 QUOTATION MARK
+ \u201f: DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+ <string name="more_keys_for_less_than">\u2264|\u2265,\u00ab|\u00bb,\u2039|\u203a</string>
+ <string name="more_keys_for_greater_than">\u2265|\u2264,\u00bb|\u00ab,\u203a|\u2039</string>
+ <integer name="keycode_for_left_square_bracket">0x005d</integer>
+ <integer name="keycode_for_right_square_bracket">0x005b</integer>
+ <integer name="keycode_for_left_curly_bracket">0x007d</integer>
+ <integer name="keycode_for_right_curly_bracket">0x007b</integer>
+ <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+ <!-- <string name="more_keys_for_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb</string> -->
+ <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+ <string name="more_keys_for_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab</string>
+ <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+ <!-- <string name="more_keys_for_tablet_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb,\u2018,\u2019,\u201a,\u201b</string> -->
+ <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
+ <string name="more_keys_for_tablet_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab,\u2019,\u201a,\u2018,\u201b</string>
</resources>
diff --git a/java/res/values-ar/donottranslate.xml b/java/res/values-ar/donottranslate.xml
new file mode 100644
index 000000000..a9aad4e3c
--- /dev/null
+++ b/java/res/values-ar/donottranslate.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- The all letters need to be mirrored are found at
+ http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+ <!-- Symbols that are suggested between words -->
+ <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
+</resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index dca73659a..c4aa441d8 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"لوحة مفاتيح Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"لوحة مفاتيح Android ‏(AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"إعدادات لوحة مفاتيح Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"خيارات الإرسال"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"تصحيح Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"إعدادات التدقيق الإملائي"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"استخدام بيانات التقريب"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"استخدام خوارزمية تقريب شبيهة بلوحة المفاتيح لإجراء التدقيق الإملائي"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"بحث في أسماء جهات الاتصال"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"يستخدم المدقق الإملائي إدخالات من قائمة جهات الاتصال"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"اهتزاز عند ضغط مفتاح"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"صوت عند الضغط على مفتاح"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"انبثاق عند ضغط مفتاح"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : تم الحفظ"</string>
<string name="label_go_key" msgid="1635148082137219148">"تنفيذ"</string>
<string name="label_next_key" msgid="362972844525672568">"التالي"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"تم"</string>
<string name="label_send_key" msgid="2815056534433717444">"إرسال"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"أ ب ج"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"إدخال صوتي"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"وجه مبتسم"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"رجوع"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"فاصلة"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"نقطة"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"قوس أيسر"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"قوس أيمن"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"نقطتان"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"فاصلة منقوطة"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"علامة التعجب"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"علامة استفهام"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"علامة الاقتباس المزدوجة"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"علامة الاقتباس المفردة"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"نقطة"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"جذر تربيعي"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"باي"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"دلتا"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"علامة تجارية"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"رعاية"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"نجمة"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"جنيه"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"علامة حذف"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"علامة الاقتباس المزدوجة السفلية"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"الإدخال الصوتي"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"الإدخال الصوتي غير معتمد حاليًا للغتك، ولكنه يعمل باللغة الإنجليزية."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"يستخدم الإدخال الصوتي خاصية التعرف على الكلام من Google. تنطبق "<a href="http://m.google.com/privacy">"سياسة خصوصية الجوال"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"تمكين ملاحظات المستخدم"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"المساعدة في تحسين محرر طريقة الإرسال هذا من خلال إرسال إحصاءات الاستخدام وتقارير الأعطال تلقائيًا إلى Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"مظهر لوحة المفاتيح"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"الألمانية (QWERTY)"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"الإنجليزية (المملكة المتحدة)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"الإنجليزية (الولايات المتحدة)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"وضع سهولة الاستخدام"</string>
diff --git a/java/res/values-de-rZZ/donottranslate-more-keys.xml b/java/res/values-be/donottranslate-more-keys.xml
index e7ec5e152..28264c4ac 100644
--- a/java/res/values-de-rZZ/donottranslate-more-keys.xml
+++ b/java/res/values-be/donottranslate-more-keys.xml
@@ -18,6 +18,6 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_y">6</string>
- <string name="more_keys_for_z"></string>
+ <string name="keylabel_for_slavic_shcha">ў</string>
+ <string name="keylabel_for_slavic_i">i</string>
</resources>
diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml
index 1ed944caf..c0094741c 100644
--- a/java/res/values-be/strings.xml
+++ b/java/res/values-be/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Клавіятура Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Клавіятура Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Налады клавіятуры Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Параметры ўводу"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Папраўкі Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Налады праверкі арфаграфіі"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Выкарыстоўвайць дадзеныя аб блізкасці"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Для праверкі арфаграфіі выкарыстоўваць алгарытм блізкасці, падобны на клавіятуру"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Шукаць імёны кантактаў"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Модуль праверкі правапісу выкарыстоўвае запісы са спісу кантактаў"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Вібрацыя пры націску клавіш"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Гук пры націску"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Па націску на клавішы ўсплывае акно"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Захаваныя"</string>
<string name="label_go_key" msgid="1635148082137219148">"Пачаць"</string>
<string name="label_next_key" msgid="362972844525672568">"Далей"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Гатова"</string>
<string name="label_send_key" msgid="2815056534433717444">"Адправіць"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Галасавы ўвод"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Смайлік"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Увод"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Коска"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Кропка"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Адчыняючая дужка"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Дужка, якая зачыняе"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Двукроп\'е"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Кропка з коскай"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Клічнік"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Пытальнік"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Двукоссі"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Паўдвукоссі"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Кропка"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Квадратны корань"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Пі"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Дэльта"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Гандлёвая марка"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Працэнт"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Пазначыць"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Фунт"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Шматкроп\'е"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Нізкія падвойныя двукоссі"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Галасавы ўвод"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Галасавы ўвод пакуль не падтрымліваецца для вашай мовы, але працуе на англійскай мове."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Галасавы набор выкарыстоўвае распазнанне гаворкі Google. Ужываецца "<a href="http://m.google.com/privacy">"палiтыка прыватнасцi для мабiльных прылад"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Уключыць зваротную сувязь з карыстальнікамі"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Дапамажыце палепшыць гэты рэдактар ​​метаду ўводу, аўтаматычна адпраўляючы статыстыку выкарыстання і справаздачы аб збоях Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тэма клавіятуры"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Нямецкая QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Англійская (ЗК)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Англійская (ЗША)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Рэжым даследвання выкарыстальнасці"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 30fe132d8..900a7fd88 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Клавиатура на Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Клавиатура на Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Настройки на клавиатурата на Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Опции за въвеждане"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Корекция на Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Настройки за проверка на правописа"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Използване на близост"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Проверка на правописа: Използвайте алгоритъм за близост"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Търсене на имена"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"За проверка на правописа се ползват записи от списъка с контакти"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Да вибрира при натискане на клавиш"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натискане на клавиш"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Изскачащ прозорец при натискане на клавиш"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Запазено"</string>
<string name="label_go_key" msgid="1635148082137219148">"Старт"</string>
<string name="label_next_key" msgid="362972844525672568">"Напред"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
<string name="label_send_key" msgid="2815056534433717444">"Изпращане"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"АБВ"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Гласово въвеждане"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Усмивка"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Запетая"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Точка"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Лява кръгла скоба"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Дясна кръгла скоба"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Двоеточие"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Точка и запетая"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Удивителен знак"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Въпросителен знак"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Двойни кавички"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Единични кавички"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Корен квадратен"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Пи"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Делта"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Запазена марка"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"По адрес"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Звездичка"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Диез"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Многоточие"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Долни двойни кавички"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Гласово въвеждане"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"За вашия език понастоящем не се поддържа гласово въвеждане, но можете да го използвате на английски."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Гласовото въвеждане използва функцията на Google за разпознаване на говор. В сила е "<a href="http://m.google.com/privacy">"Декларацията за поверителност за мобилни устройства"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Активиране на отзивите от потребителите"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Помогнете за подобряването на този редактор за въвеждане чрез автоматично изпращане до Google на статистически данни за употребата и сигнали за сривове."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема на клавиатурата"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"немски, „QWERTY“"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"английски (Великобритания)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"английски (САЩ)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за изучаване на използваемостта"</string>
diff --git a/java/res/values-ca/donottranslate-more-keys.xml b/java/res/values-ca/donottranslate-more-keys.xml
index bd9fb7ccd..512a86110 100644
--- a/java/res/values-ca/donottranslate-more-keys.xml
+++ b/java/res/values-ca/donottranslate-more-keys.xml
@@ -19,10 +19,10 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">à,á,ä,â,ã,å,ą,æ,ā,ª</string>
- <string name="more_keys_for_e">3,è,é,ë,ê,ę,ė,ē</string>
- <string name="more_keys_for_i">8,í,ï,ì,î,į,ī</string>
- <string name="more_keys_for_o">9,ò,ó,ö,ô,õ,ø,œ,ō,º</string>
- <string name="more_keys_for_u">7,ú,ü,ù,û,ū</string>
+ <string name="more_keys_for_e">è,é,ë,ê,ę,ė,ē</string>
+ <string name="more_keys_for_i">í,ï,ì,î,į,ī</string>
+ <string name="more_keys_for_o">ò,ó,ö,ô,õ,ø,œ,ō,º</string>
+ <string name="more_keys_for_u">ú,ü,ù,û,ū</string>
<string name="more_keys_for_n">ñ,ń</string>
<string name="more_keys_for_c">ç,ć,č</string>
<string name="more_keys_for_l">ŀ,ł</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index a58d8faa9..0fae132a6 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Teclat Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Teclat d\'Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Configuració del teclat d\'Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opcions d\'entrada"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Correcció d\'Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Configuració de la correcció ortogràfica"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Utilitza les dades de proximitat"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Utilitza un algorisme de proximitat similar al teclat per comprovar l\'ortografia"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cerca noms de contactes"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"El corrector ortogràfic utilitza entrades de la llista de cont."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibra en prémer tecles"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"So en prémer una tecla"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Finestra emergent en prémer un botó"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: desada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Vés"</string>
<string name="label_next_key" msgid="362972844525672568">"Següent"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Fet"</string>
<string name="label_send_key" msgid="2815056534433717444">"Envia"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Entrada de veu"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Cara somrient"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Retorn"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Coma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punt"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Parèntesi esquerre"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Parèntesi dret"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Coma"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Punt i coma"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Signe d\'admiració"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Signe d\'interrogació"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Cometes dobles"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Cometes simples"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punt"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Arrel quadrada"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marca comercial"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Percentatge"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Destaca"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Coixinet"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Punts suspensius"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Cometes angulars"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Entrada de veu"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualment, l\'entrada de veu no és compatible amb el vostre idioma, però funciona en anglès."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"L\'entrada de veu utilitza el reconeixement de veu de Google. S\'hi aplica la "<a href="http://m.google.com/privacy">"Política de privadesa de Google per a mòbils"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Activa els comentaris de l\'usuari"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Ajuda a millorar aquest editor de mètodes d\'entrada enviant automàticament estadístiques d\'ús i informes de bloqueigs a Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclat"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY alemany"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglès (Regne Unit)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglès (EUA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'estudi d\'usabilitat"</string>
diff --git a/java/res/values-cs/donottranslate-more-keys.xml b/java/res/values-cs/donottranslate-more-keys.xml
index 70b3f3ee7..3701adb1b 100644
--- a/java/res/values-cs/donottranslate-more-keys.xml
+++ b/java/res/values-cs/donottranslate-more-keys.xml
@@ -19,16 +19,16 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">á,à,â,ä,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,é,ě,è,ê,ë,ę,ė,ē</string>
- <string name="more_keys_for_i">8,í,î,ï,ì,į,ī</string>
- <string name="more_keys_for_o">9,ó,ö,ô,ò,õ,œ,ø,ō</string>
- <string name="more_keys_for_u">7,ú,ů,û,ü,ù,ū</string>
+ <string name="more_keys_for_e">é,ě,è,ê,ë,ę,ė,ē</string>
+ <string name="more_keys_for_i">í,î,ï,ì,į,ī</string>
+ <string name="more_keys_for_o">ó,ö,ô,ò,õ,œ,ø,ō</string>
+ <string name="more_keys_for_u">ú,ů,û,ü,ù,ū</string>
<string name="more_keys_for_s">š,ß,ś</string>
<string name="more_keys_for_n">ň,ñ,ń</string>
<string name="more_keys_for_c">č,ç,ć</string>
<string name="more_keys_for_y">ý,ÿ</string>
<string name="more_keys_for_d">ď</string>
- <string name="more_keys_for_r">4,ř</string>
- <string name="more_keys_for_t">5,ť</string>
- <string name="more_keys_for_z">6,ž,ź,ż</string>
+ <string name="more_keys_for_r">ř</string>
+ <string name="more_keys_for_t">ť</string>
+ <string name="more_keys_for_z">ž,ź,ż</string>
</resources>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index d57ccaa28..7c4c31ac4 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Klávesnice Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Klávesnice Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Nastavení klávesnice Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti zadávání textu a dat"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Opravy Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Nastavení kontroly pravopisu"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Použít údaje o blízkosti"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Při kontrole pravopisu uvažovat blízkost písmen na klávesnici"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Vyhledat kontakty"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Kontrola pravopisu používá záznamy z vašeho seznamu kontaktů."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Při stisku klávesy vibrovat"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk při stisku klávesy"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Zobrazit znaky při stisku klávesy"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Uloženo"</string>
<string name="label_go_key" msgid="1635148082137219148">"Přejít"</string>
<string name="label_next_key" msgid="362972844525672568">"Další"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Hotovo"</string>
<string name="label_send_key" msgid="2815056534433717444">"Odeslat"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Hlasový vstup"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smajlík"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Čárka"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Tečka"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Levá závorka"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Pravá závorka"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dvojtečka"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Středník"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Vykřičník"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Otazník"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Uvozovky"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Apostrof"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Tečka"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Odmocnina"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pí"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Ochranná známka"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Procento"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Hvězdička"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Libra"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Tři tečky"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Uvozovky dole"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pro váš jazyk aktuálně není hlasový vstup podporován, ale funguje v angličtině."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Hlasový vstup používá rozpoznávání hlasu Google a vztahují se na něj "<a href="http://m.google.com/privacy">"Zásady ochrany osobních údajů pro mobilní služby"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Aktivovat zasílání statistik užívání a zpráv o selhání"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Automatickým zasíláním statistik o užívání editoru zadávání dat a zpráv o jeho selhání do Googlu můžete přispět k vylepšení tohoto nástroje."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Motiv klávesnice"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"němčina (QWERTY)"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angličtina (Spojené království)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angličtina (USA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim studie použitelnosti"</string>
diff --git a/java/res/values-da/donottranslate-more-keys.xml b/java/res/values-da/donottranslate-more-keys.xml
index 12c1ebfe1..b1c8d2072 100644
--- a/java/res/values-da/donottranslate-more-keys.xml
+++ b/java/res/values-da/donottranslate-more-keys.xml
@@ -19,15 +19,16 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">á,ä,à,â,ã,ā</string>
- <string name="more_keys_for_e">3,é,ë</string>
- <string name="more_keys_for_i">8,í,ï</string>
- <string name="more_keys_for_o">9,ó,ô,ò,õ,œ,ō</string>
- <string name="more_keys_for_u">7,ú,ü,û,ù,ū</string>
+ <string name="more_keys_for_e">é,ë</string>
+ <string name="more_keys_for_i">í,ï</string>
+ <string name="more_keys_for_o">ó,ô,ò,õ,œ,ō</string>
+ <string name="more_keys_for_u">ú,ü,û,ù,ū</string>
<string name="more_keys_for_s">ß,ś,š</string>
<string name="more_keys_for_n">ñ,ń</string>
- <string name="more_keys_for_y">6,ý,ÿ</string>
+ <string name="more_keys_for_y">ý,ÿ</string>
<string name="more_keys_for_d">ð</string>
<string name="more_keys_for_l">ł</string>
+ <string name="keylabel_for_scandinavia_row1_11">å</string>
<string name="keylabel_for_scandinavia_row2_10">æ</string>
<string name="keylabel_for_scandinavia_row2_11">ø</string>
<string name="more_keys_for_scandinavia_row2_10">ä</string>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index b91acaa90..bc871e7b7 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android-tastatur"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-tastatur (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android-tastatur-indstillinger"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Indstillinger for input"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android-rettelse"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Indstillinger for stavekontrol"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Brug nærhedsdata"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Brug en tastaturlignende nærhedsalgoritme til stavekontrol"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Slå kontaktnavne op"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Stavekontrollen bruger poster fra listen over kontaktpersoner"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibration ved tastetryk"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetryk"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop op ved tastetryk"</string>
@@ -64,6 +65,7 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string>
<string name="label_go_key" msgid="1635148082137219148">"Gå"</string>
<string name="label_next_key" msgid="362972844525672568">"Næste"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Forr."</string>
<string name="label_done_key" msgid="2441578748772529288">"Udfør"</string>
<string name="label_send_key" msgid="2815056534433717444">"Send"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +90,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Stemmeinput"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Tilbage"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punktum"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Venstre parentes"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Højre parentes"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Kolon"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikolon"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Udråbstegn"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Spørgsmålstegn"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dobbelt anførselstegn"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Enkelt anførselstegn"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punktum"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Kvadratrod"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Varemærke"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"De bedste hilsner"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Stjerne"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Pund"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipse"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Lave dobbelte anførelsestegn"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Stemmeinput"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer på engelsk."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Stemmeinput anvender Googles stemmegenkendelse. "<a href="http://m.google.com/privacy">"Fortrolighedspolitikken for mobilenheder"</a>" gælder."</string>
@@ -144,7 +127,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Aktiver brugerfeedback"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Vær med til at forbedre denne inputmetode ved at sende anvendelsesstatistikker og rapporter om nedbrud til Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Tysk QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engelsk (Storbritannien)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engelsk (USA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tilstand for brugsstudie"</string>
diff --git a/java/res/values-de/donottranslate-more-keys.xml b/java/res/values-de/donottranslate-more-keys.xml
index 80aa32ae2..48462c59d 100644
--- a/java/res/values-de/donottranslate-more-keys.xml
+++ b/java/res/values-de/donottranslate-more-keys.xml
@@ -19,11 +19,9 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">ä,â,à,á,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,ė</string>
- <string name="more_keys_for_o">9,ö,ô,ò,ó,õ,œ,ø,ō</string>
- <string name="more_keys_for_u">7,ü,û,ù,ú,ū</string>
+ <string name="more_keys_for_e">ė</string>
+ <string name="more_keys_for_o">ö,ô,ò,ó,õ,œ,ø,ō</string>
+ <string name="more_keys_for_u">ü,û,ù,ú,ū</string>
<string name="more_keys_for_s">ß,ś,š</string>
<string name="more_keys_for_n">ñ,ń</string>
- <string name="more_keys_for_y"></string>
- <string name="more_keys_for_z">6</string>
</resources>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index d329f3271..da5823a76 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android-Tastatur"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-Tastatur (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android-Tastatureinstellungen"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Eingabeoptionen"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Rechtschreibprüfung für Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Einstellungen für Rechtschreibprüfung"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Näherungsdaten verwenden"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Tastaturähnl. Abstandsalgorith. für Rechtschreibprüfung verwenden"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontaktnamen prüfen"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Rechtschreibprüfung verwendet Einträge aus Ihrer Kontaktliste."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Bei Tastendruck vibrieren"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Ton bei Tastendruck"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bei Tastendruck"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: gespeichert"</string>
<string name="label_go_key" msgid="1635148082137219148">"Los"</string>
<string name="label_next_key" msgid="362972844525672568">"Weiter"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Fertig"</string>
<string name="label_send_key" msgid="2815056534433717444">"Senden"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Spracheingabe"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Eingabe"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punkt"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Öffnende Klammer"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Schließende Klammer"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Doppelpunkt"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikolon"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Ausrufezeichen"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Fragezeichen"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Anführungszeichen"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Einfaches Anführungszeichen"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Aufzählungspunkt"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Quadratwurzel"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Trademark"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"c/o"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Sternchen"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Raute"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Auslassungszeichen"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Anführungszeichen unten"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Spracheingabe"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spracheingaben werden zurzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Die Spracheingabe verwendet die Spracherkennung von Google. Es gelten die "<a href="http://m.google.com/privacy">"Google Mobile-Datenschutzbestimmungen"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Nutzer-Feedback aktivieren"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Tragen Sie zur Verbesserung dieses Eingabemethodeneditors bei, indem Sie automatisch Nutzungsstatistiken und Absturzberichte an Google senden."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastaturdesign"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Deutsche QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Englisch (Großbritannien)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Englisch (USA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus der Studie zur Benutzerfreundlichkeit"</string>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 6fe191ee7..d126edb56 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Πληκτρολόγιο Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Πληκτρολόγιο Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Ρυθμίσεις πληκτρολογίου Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Επιλογές εισόδου"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Διόρθωση Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Ρυθμίσεις ορθογραφικού ελέγχου"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Χρ. δεδ. εγγύτ."</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Χρησ. αλγόρ. εγγύτ. τύπου πληκτρ., για ορθ. έλεγχο"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Αναζήτηση ονομάτων επαφών"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Ο ορθογρ. έλεγχος χρησιμοπ. καταχωρίσεις από τη λίστα επαφών σας"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Δόνηση κατά το πάτημα πλήκτρων"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Ήχος κατά το πάτημα πλήκτρων"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Εμφάνιση με το πάτημα πλήκτρου"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Αποθηκεύτηκε"</string>
<string name="label_go_key" msgid="1635148082137219148">"Μετ."</string>
<string name="label_next_key" msgid="362972844525672568">"Επόμενο"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Τέλος"</string>
<string name="label_send_key" msgid="2815056534433717444">"Αποστολή"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ΑΒΓ"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Μικρόφωνο"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Πλήκτρο Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Κόμμα"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Τελεία"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Αριστερή παρένθεση"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Δεξιά παρένθεση"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Άνω και κάτω τελεία"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Ερωτηματικό"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Θαυμαστικό"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Ερωτηματικό"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Διπλά εισαγωγικά"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Μονό εισαγωγικό"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Κουκκίδα"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Τετραγωνική ρίζα"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"πι"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Δέλτα"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Εμπορικό σήμα"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Υπεύθυνος"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Αστερίσκος"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Δίεση"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Αποσιωπητικά"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Χαμηλό διπλό εισαγωγικό"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Φωνητική είσοδος"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Η φωνητική είσοδος δεν υποστηρίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουργεί στα Αγγλικά."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Οι φωνητικές εντολές χρησιμοποιούν την τεχνολογία αναγνώρισης φωνής της Google. Ισχύει "<a href="http://m.google.com/privacy">"η Πολιτική Απορρήτου για κινητά"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Ενεργοποίηση σχολίων χρηστών"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Βοηθήστε μας να βελτιώσουμε αυτό το πρόγραμμα επεξεργασίας μεθόδου εισόδου στέλνοντας αυτόματα στατιστικά στοιχεία και αναφορές σφαλμάτων στην Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Θέμα πληκτρολογίου"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Γερμανικά QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Αγγλικά (Η.Β.)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Αγγλικά (Η.Π.Α)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Λειτουργία μελέτης χρηστικότητας"</string>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index a7d50860c..bce6a51a5 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android keyboard"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android keyboard (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android keyboard settings"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Input options"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android correction"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Spellchecking settings"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Use proximity data"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Use a keyboard-like proximity algorithm for spellchecking"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Look up contact names"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Spell checker uses entries from your contact list"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on key-press"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Sound on key-press"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up on key press"</string>
@@ -64,6 +65,7 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Saved"</string>
<string name="label_go_key" msgid="1635148082137219148">"Go"</string>
<string name="label_next_key" msgid="362972844525672568">"Next"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Prev"</string>
<string name="label_done_key" msgid="2441578748772529288">"Done"</string>
<string name="label_send_key" msgid="2815056534433717444">"Send"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +90,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Voice input"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley face"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Comma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Full stop"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Left parenthesis"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Right parenthesis"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Colon"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semi-colon"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Exclamation mark"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Question mark"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Double quote"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Single quote"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Dot"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Square root"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Trademark"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Care of"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Star"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Pound"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Low double quote"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Voice input"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Voice input is not currently supported for your language, but does work in English."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Voice input uses Google\'s speech recognition. "<a href="http://m.google.com/privacy">"The Mobile Privacy Policy"</a>" applies."</string>
@@ -144,7 +127,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Enable user feedback"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Help improve this input method editor by sending usage statistics and crash reports automatically to Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"German QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Usability study mode"</string>
diff --git a/java/res/values-en/additional-proximitychars.xml b/java/res/values-en/additional-proximitychars.xml
new file mode 100644
index 000000000..0e1276796
--- /dev/null
+++ b/java/res/values-en/additional-proximitychars.xml
@@ -0,0 +1,62 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <string-array name="additional_proximitychars">
+ <!-- Empty entry terminates the proximity chars array. -->
+
+ <!-- Additional proximity chars for a -->
+ <item>a</item>
+ <item>e</item>
+ <item>i</item>
+ <item>o</item>
+ <item>u</item>
+ <item></item>
+ <!-- Additional proximity chars for e -->
+ <item>e</item>
+ <item>a</item>
+ <item>i</item>
+ <item>o</item>
+ <item>u</item>
+ <item></item>
+ <!-- Additional proximity chars for i -->
+ <item>i</item>
+ <item>a</item>
+ <item>e</item>
+ <item>o</item>
+ <item>u</item>
+ <item></item>
+ <!-- Additional proximity chars for o -->
+ <item>o</item>
+ <item>a</item>
+ <item>e</item>
+ <item>i</item>
+ <item>u</item>
+ <item></item>
+ <!-- Additional proximity chars for u -->
+ <item>u</item>
+ <item>a</item>
+ <item>e</item>
+ <item>i</item>
+ <item>o</item>
+ <item></item>
+ </string-array>
+
+</resources> \ No newline at end of file
diff --git a/java/res/values-en/donottranslate-more-keys.xml b/java/res/values-en/donottranslate-more-keys.xml
index bc26c6aa0..9073d3b4f 100644
--- a/java/res/values-en/donottranslate-more-keys.xml
+++ b/java/res/values-en/donottranslate-more-keys.xml
@@ -19,11 +19,11 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">à,á,â,ä,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,è,é,ê,ë,ē</string>
- <string name="more_keys_for_i">8,î,ï,í,ī,ì</string>
- <string name="more_keys_for_o">9,ô,ö,ò,ó,œ,ø,ō,õ</string>
+ <string name="more_keys_for_e">è,é,ê,ë,ē</string>
+ <string name="more_keys_for_i">î,ï,í,ī,ì</string>
+ <string name="more_keys_for_o">ô,ö,ò,ó,œ,ø,ō,õ</string>
<string name="more_keys_for_s">ß</string>
- <string name="more_keys_for_u">7,û,ü,ù,ú,ū</string>
+ <string name="more_keys_for_u">û,ü,ù,ú,ū</string>
<string name="more_keys_for_n">ñ</string>
<string name="more_keys_for_c">ç</string>
</resources>
diff --git a/java/res/values-en/whitelist.xml b/java/res/values-en/whitelist.xml
index f929cec23..fd79999bf 100644
--- a/java/res/values-en/whitelist.xml
+++ b/java/res/values-en/whitelist.xml
@@ -422,6 +422,10 @@
<item>needn\'t</item>
<item>255</item>
+ <item>nit</item>
+ <item>not</item>
+
+ <item>255</item>
<item>oclock</item>
<item>o\'clock</item>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 95e309ff7..29df462fb 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Teclado de Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Teclado de Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Configuración de teclado de Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opciones de entrada"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Corrector de Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Configuración del corrector ortográfico"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Utilizar datos de prox."</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Utilizar algoritmo de prox. de teclado para corrector ortográfico"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Buscar nombres contactos"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"El corrector ortográfico usa entradas de tu lista de contactos."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar al pulsar teclas"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Sonar al pulsar las teclas"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Aviso emergente al pulsar tecla"</string>
@@ -35,12 +36,12 @@
<string name="misc_category" msgid="6894192814868233453">"Otras opciones"</string>
<string name="advanced_settings" msgid="362895144495591463">"Configuración avanzada"</string>
<string name="advanced_settings_summary" msgid="5193513161106637254">"Opciones para usuarios expertos"</string>
- <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Demora en rechazo de ventana emergente de clave"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Retraso en rechazo de alerta de tecla"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sin demora"</string>
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminada"</string>
<string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nombres de contacto"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nombres de los contactos para sugerencias y correcciones"</string>
- <string name="enable_span_insert" msgid="7204653105667167620">"Habilitar correcciones"</string>
+ <string name="enable_span_insert" msgid="7204653105667167620">"Activar correcciones"</string>
<string name="enable_span_insert_summary" msgid="2947317657871394467">"Establecer sugerencias para realizar correcciones"</string>
<string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
<string name="configure_dictionaries_title" msgid="4238652338556902049">"Diccionarios complementarios"</string>
@@ -52,7 +53,7 @@
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar siempre"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de configuración"</string>
<string name="auto_correction" msgid="4979925752001319458">"Corrección automática"</string>
- <string name="auto_correction_summary" msgid="5625751551134658006">"La barra espaciadora y puntuación insertan automáticamente las palabras corregidas"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"La barra espaciadora y las teclas de puntuación insertan automáticamente la palabra corregida"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactivado"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Siguiente"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Hecho"</string>
<string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Carita sonriente"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Volver"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Coma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punto"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Paréntesis de apertura"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Paréntesis de cierre"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dos puntos"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Punto y coma"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Signo de admiración"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Signo de interrogación"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Comillas dobles"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Comillas simples"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Raíz cuadrada"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marca registrada"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"En atención de"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Destacar"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Numeral"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Elipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Comillas bajas"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Entrada por voz"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La entrada por voz no está admitida en tu idioma, pero sí funciona en inglés."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La entrada de voz usa el reconocimiento de voz de Google. "<a href="http://m.google.com/privacy">"Se aplica la política de privacidad para"</a>" celulares."</string>
@@ -128,7 +112,7 @@
<string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugerencia:"</b>" La próxima vez intenta decir la puntuación como \"punto\", \"coma\" o \"signo de pregunta\"."</string>
<string name="cancel" msgid="6830980399865683324">"Cancelar"</string>
<string name="ok" msgid="7898366843681727667">"Aceptar"</string>
- <string name="voice_input" msgid="3583258583521397548">"Clave de entrada de voz"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Tecla de entrada por voz"</string>
<string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"En el teclado principal"</string>
<string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"En el teclado de símbolos"</string>
<string name="voice_input_modes_off" msgid="3745699748218082014">"Desactivado"</string>
@@ -141,10 +125,9 @@
<string name="select_language" msgid="3693815588777926848">"Idiomas de entrada"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tocar de nuevo para guardar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Diccionario disponible"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Habilitar los comentarios del usuario"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Activar los comentarios del usuario"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Ayuda a mejorar este editor de método de introducción de texto al enviar las estadísticas de uso y los informes de error a Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclado"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY alemán"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglés (Reino Unido)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglés (EE.UU.)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudio de usabilidad"</string>
diff --git a/java/res/values-es/donottranslate-more-keys.xml b/java/res/values-es/donottranslate-more-keys.xml
index d5a8ed19d..429273647 100644
--- a/java/res/values-es/donottranslate-more-keys.xml
+++ b/java/res/values-es/donottranslate-more-keys.xml
@@ -19,10 +19,10 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">á,à,ä,â,ã,å,ą,æ,ā,ª</string>
- <string name="more_keys_for_e">3,é,è,ë,ê,ę,ė,ē</string>
- <string name="more_keys_for_i">8,í,ï,ì,î,į,ī</string>
- <string name="more_keys_for_o">9,ó,ò,ö,ô,õ,ø,œ,ō,º</string>
- <string name="more_keys_for_u">7,ú,ü,ù,û,ū</string>
+ <string name="more_keys_for_e">é,è,ë,ê,ę,ė,ē</string>
+ <string name="more_keys_for_i">í,ï,ì,î,į,ī</string>
+ <string name="more_keys_for_o">ó,ò,ö,ô,õ,ø,œ,ō,º</string>
+ <string name="more_keys_for_u">ú,ü,ù,û,ū</string>
<string name="more_keys_for_n">ñ,ń</string>
<string name="more_keys_for_c">ç,ć,č</string>
<string name="more_keys_for_punctuation">"\\,,\?,!,¿,¡,:,-,\',\",),(,/,;,+,&amp;,\@"</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index fcd65e1fc..4e47069f6 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Teclado de Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Teclado Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Ajustes del teclado de Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opciones introducción texto"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Corrector de Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Ajustes del corrector ortográfico"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Usar datos de proximidad"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Usar algoritmo de proximidad de teclado para corregir la ortografía"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Buscar nombres de contactos"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"El corrector ortográfico usa entradas de tu lista de contactos."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar al pulsar tecla"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Sonido al pulsar tecla"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up al pulsar tecla"</string>
@@ -64,6 +65,7 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Sig."</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Anterior"</string>
<string name="label_done_key" msgid="2441578748772529288">"Ok"</string>
<string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +90,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Emoticono"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Tecla Intro"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Coma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punto"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Paréntesis de apertura"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Paréntesis de cierre"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dos puntos"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Punto y coma"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Signo de exclamación"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Signo de interrogación"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Comillas dobles"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Comillas simples"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punto"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Raíz cuadrada"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marca comercial"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Porcentaje"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Asterisco"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Almohadilla"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Puntos suspensivos"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Comillas dobles bajas"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Introducción de voz"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La entrada de voz utiliza el reconocimiento de voz de Google. Se aplica la "<a href="http://m.google.com/privacy">"Política de privacidad de Google para móviles"</a>"."</string>
@@ -144,7 +127,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Habilitar comentarios de usuarios"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Ayuda a mejorar este editor de método de introducción de texto enviando estadísticas de uso e informes de error a Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema de teclado"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY alemán"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"inglés (Reino Unido)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"inglés (EE.UU.)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudio de usabilidad"</string>
diff --git a/java/res/values-et/donottranslate-more-keys.xml b/java/res/values-et/donottranslate-more-keys.xml
new file mode 100644
index 000000000..bda22fcec
--- /dev/null
+++ b/java/res/values-et/donottranslate-more-keys.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="more_keys_for_a">ä,ā,à,á,â,ã,å,æ,ą</string>
+ <string name="more_keys_for_e">ē,è,ė,é,ê,ë,ę,ě</string>
+ <string name="more_keys_for_i">ī,ì,į,í,î,ï,ı</string>
+ <string name="more_keys_for_o">ö,õ,ò,ó,ô,œ,ő,ø</string>
+ <string name="more_keys_for_u">ü,ū,ų,ù,ú,û,ů,ű</string>
+ <string name="more_keys_for_s">š,ß,ś,ş</string>
+ <string name="more_keys_for_n">ņ,ñ,ń,ń</string>
+ <string name="more_keys_for_c">č,ç,ć</string>
+ <string name="more_keys_for_y">ý,ÿ</string>
+ <string name="more_keys_for_d">ď</string>
+ <string name="more_keys_for_r">ŗ,ř,ŕ</string>
+ <string name="more_keys_for_t">ţ,ť</string>
+ <string name="more_keys_for_z">ž,ż,ź</string>
+ <string name="more_keys_for_k">ķ</string>
+ <string name="more_keys_for_l">ļ,ł,ĺ,ľ</string>
+ <string name="more_keys_for_g">ģ,ğ</string>
+ <string name="keylabel_for_scandinavia_row1_11">ü</string>
+ <string name="keylabel_for_scandinavia_row2_10">ö</string>
+ <string name="keylabel_for_scandinavia_row2_11">ä</string>
+ <string name="more_keys_for_scandinavia_row2_10">õ</string>
+ <string name="more_keys_for_scandinavia_row2_11"></string>
+</resources>
diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml
index 2c69c99d3..a65bd4a95 100644
--- a/java/res/values-et/strings.xml
+++ b/java/res/values-et/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Androidi klaviatuur"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-klaviatuur (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Androidi klaviatuuriseaded"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Sisestusvalikud"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Androidi parandus"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Õigekirjakontrolli seaded"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Kasuta lähedusandmeid"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Kasuta õigekirjakontrollis klaviatuurisarnast lähedusalgoritmi"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontakti nimede kontroll."</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Õigekirjakontroll kasutab teie kontaktisikute loendi sissekandeid"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibreeri klahvivajutusel"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Heli klahvivajutusel"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Klahvivajutusel kuva hüpik"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : salvestatud"</string>
<string name="label_go_key" msgid="1635148082137219148">"Mine"</string>
<string name="label_next_key" msgid="362972844525672568">"Edasi"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Valmis"</string>
<string name="label_send_key" msgid="2815056534433717444">"Saada"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Kõnesisend"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Naerunägu"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Tagasi"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Koma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punkt"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Vasaksulg"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Paremsulg"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Koolon"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikoolon"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Hüüumärk"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Küsimärk"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Jutumärgid"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Üksikjutumärgid"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Ruutjuur"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pii"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Kaubamärk"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Vahendaja"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Tärn"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Nael"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Kolmikpunkt"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Alumised jutumärgid"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Kõnesisend"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Kõnesisendit ei toetata praegu teie keeles, kuid see töötab inglise keeles."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Kõnesisend kasutab Google\'i kõnetuvastust. Kehtivad "<a href="http://m.google.com/privacy">"Mobile\'i privaatsuseeskirjad"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Luba kasutaja tagasiside"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Saatke Google\'ile automaatselt kasutusstatistikat ja krahhiaruandeid ning aidake seda sisestusmeetodi redigeerijat parandada."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klaviatuuri teema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Saksa QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglise (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglise (USA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kasutatavuse uurimisrežiim"</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 7d8c1e941..9b757505a 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"صفحه کلید Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"صفحه کلید (Android (AOSP"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"تنظیمات صفحه کلید Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"گزینه های ورودی"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"تصحیح Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"تنظیمات غلط گیری املایی"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"استفاده از داده‌های مجاورت"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"استفاده از یک الگوریتم مجاورت مشابه صفحه کلید برای غلط گیری املایی"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"جستجوی نام مخاطبین"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"غلط‌گیر املا از ورودی‌های لیست مخاطبین شما استفاده میکند"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"لرزش با فشار کلید"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"صدا با فشار کلید"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"بازشدن با فشار کلید"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ذخیره شد"</string>
<string name="label_go_key" msgid="1635148082137219148">"برو"</string>
<string name="label_next_key" msgid="362972844525672568">"بعدی"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"انجام شد"</string>
<string name="label_send_key" msgid="2815056534433717444">"ارسال"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -92,26 +95,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"ورودی صدا"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"صورت متبسم"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"کاما"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"نقطه"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"پرانتز چپ"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"پرانتز راست"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"دو نقطه"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"نقطه ویرگول"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"علامت تعجب"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"علامت سؤال"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"علامت نقل قول"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"علامت نقل قول تکی"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"نقطه"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"ریشه دوم"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"پی"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"دلتا"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"علامت تجاری"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"توسط"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"ستاره"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"پوند"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"سه نقطه"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"علامت نقل قول پایین"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"ورودی صوتی"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ورودی صوتی در حال حاضر برای زبان شما پشتیبانی نمی شود اما برای زبان انگلیسی فعال است."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ورودی صوتی از تشخیص صدای Google استفاده می کند. "<a href="http://m.google.com/privacy">"خط مشی رازداری Mobile "</a>" اعمال می شود."</string>
@@ -148,7 +132,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"فعال کردن بازخورد کاربر"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"با ارسال خودکار آمارهای کاربرد و گزارش های خرابی به Google، به بهبود این ویرایشگر روش ورودی کمک کنید."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"طرح زمینه صفحه کلید"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY آلمانی"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"انگیسی (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"انگیسی (US)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"حالت بررسی قابلیت استفاده"</string>
diff --git a/java/res/values-fi/donottranslate-more-keys.xml b/java/res/values-fi/donottranslate-more-keys.xml
index df67c69ba..b922fe21d 100644
--- a/java/res/values-fi/donottranslate-more-keys.xml
+++ b/java/res/values-fi/donottranslate-more-keys.xml
@@ -19,10 +19,11 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">æ,à,á,â,ã,ā</string>
- <string name="more_keys_for_o">9,ø,ô,ò,ó,õ,œ,ō</string>
- <string name="more_keys_for_u">7,ü</string>
+ <string name="more_keys_for_o">ø,ô,ò,ó,õ,œ,ō</string>
+ <string name="more_keys_for_u">ü</string>
<string name="more_keys_for_s">š,ß,ś</string>
<string name="more_keys_for_z">ž,ź,ż</string>
+ <string name="keylabel_for_scandinavia_row1_11">å</string>
<string name="keylabel_for_scandinavia_row2_10">ö</string>
<string name="keylabel_for_scandinavia_row2_11">ä</string>
<string name="more_keys_for_scandinavia_row2_10">ø</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index c77cd8107..c4da3cbf7 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android-näppäimistö"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-näppäimistö (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android-näppäimistön asetukset"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Syöttövalinnat"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android-korjaus"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Oikoluvun asetukset"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Käytä lähestymistietoja"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Käytä näppäimistön kaltaista lähestymisalgoritmia oikolukuun"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Hae kontaktien nimiä"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Oikeinkirjoituksen tarkistus käyttää kontaktiluettelosi tietoja."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Käytä värinää näppäimiä painettaessa"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Toista ääni näppäimiä painettaessa"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Ponnahdusikkuna painalluksella"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Tallennettu"</string>
<string name="label_go_key" msgid="1635148082137219148">"Siirry"</string>
<string name="label_next_key" msgid="362972844525672568">"Seur."</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Valmis"</string>
<string name="label_send_key" msgid="2815056534433717444">"Lähetä"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Puheohjaus"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Hymiö"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Pilkku"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Piste"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Vasen sulkumerkki"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Oikea sulkumerkki"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Kaksoispiste"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Puolipiste"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Huutomerkki"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Kysymysmerkki"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Lainausmerkki"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Puolilainausmerkki"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Piste"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Neliöjuuri"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pii"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Tavaramerkki"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"C/O"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Tähti"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Punta"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipsi"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Rivinalinen lainausmerkki"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Äänisyöte"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Äänisyötettä ei vielä tueta kielelläsi, mutta voit käyttää sitä englanniksi."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Äänisyöte käyttää Googlen puheentunnistusta. "<a href="http://m.google.com/privacy">"Mobile-tietosuojakäytäntö"</a>" on voimassa."</string>
@@ -123,7 +107,7 @@
<string name="voice_server_error" msgid="7807129913977261644">"Palvelinvirhe"</string>
<string name="voice_speech_timeout" msgid="8461817525075498795">"Puhetta ei kuulu"</string>
<string name="voice_no_match" msgid="4285117547030179174">"Ei vastineita"</string>
- <string name="voice_not_installed" msgid="5552450909753842415">"Äänihakua ei asennettu"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Puhehakua ei asennettu"</string>
<string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Vihje:"</b>" liu\'uta sormea näppäimistöllä ja puhu"</string>
<string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Vihje:"</b>" kokeile seuraavalla kerralla puhua välimerkit, kuten \"period\" (piste), \"comma\" (pilkku) tai \"question mark\" (kysymysmerkki)."</string>
<string name="cancel" msgid="6830980399865683324">"Peruuta"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Ota käyttäjäpalaute käyttöön"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Auta parantamaan tätä syöttötavan muokkausohjelmaa lähettämällä automaattisesti käyttötietoja ja kaatumisraportteja Googlelle."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Näppäimistöteema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"saksa, QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"englanti (Iso-Britannia)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"englanti (Yhdysvallat)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Käytettävyystutkimustila"</string>
diff --git a/java/res/values-fr/donottranslate-more-keys.xml b/java/res/values-fr/donottranslate-more-keys.xml
index cd6d49bad..0f78e7cd9 100644
--- a/java/res/values-fr/donottranslate-more-keys.xml
+++ b/java/res/values-fr/donottranslate-more-keys.xml
@@ -18,14 +18,11 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">à,â,1,æ,á,ä,ã,å,ā,ª</string>
- <string name="more_keys_for_e">é,è,ê,ë,3,ę,ė,ē</string>
- <string name="more_keys_for_i">î,8,ï,ì,í,į,ī</string>
- <string name="more_keys_for_o">ô,œ,9,ö,ò,ó,õ,ø,ō,º</string>
- <string name="more_keys_for_u">ù,û,7,ü,ú,ū</string>
+ <string name="more_keys_for_a">à,â,%,æ,á,ä,ã,å,ā,ª</string>
+ <string name="more_keys_for_e">é,è,ê,ë,%,ę,ė,ē</string>
+ <string name="more_keys_for_i">î,%,ï,ì,í,į,ī</string>
+ <string name="more_keys_for_o">ô,œ,%,ö,ò,ó,õ,ø,ō,º</string>
+ <string name="more_keys_for_u">ù,û,%,ü,ú,ū</string>
<string name="more_keys_for_c">ç,ć,č</string>
- <string name="more_keys_for_y">6,ÿ</string>
- <string name="more_keys_for_q"></string>
- <string name="more_keys_for_w"></string>
- <string name="more_keys_for_z">2</string>
+ <string name="more_keys_for_y">%,ÿ</string>
</resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 7b89edd54..e9536ec35 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Clavier Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Paramètres du clavier Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Options de saisie"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Correcteur Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Paramètre du correcteur orthographique"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Utiliser données proximité"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Utiliser algorithme de proximité clavier pour correcteur ortho"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Rechercher noms contacts"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Correcteur orthographique utilise entrées de liste de contacts."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer à chaque touche"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Son à chaque touche"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Agrandir les caractères"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Suiv."</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"OK"</string>
<string name="label_send_key" msgid="2815056534433717444">"Envoi"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Saisie vocale"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Émoticône"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Entrée"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Virgule"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Point"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Parenthèse gauche"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Parenthèse droite"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Deux-points"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Point-virgule"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Point d\'exclamation"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Point d\'interrogation"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Guillemets doubles"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Apostrophe"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Point"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Racine carrée"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marque commerciale"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"à l\'attention de"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Étoile"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Dièse"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipse"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Guillemets bas doubles"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Saisie vocale"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"La saisie vocale fait appel à la reconnaissance vocale de Google. Les "<a href="http://m.google.com/privacy">"Règles de confidentialité Google Mobile"</a>" s\'appliquent."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Autoriser les commentaires des utilisateurs"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Contribuer à l\'amélioration de cet éditeur du mode de saisie grâce à l\'envoi automatique de statistiques d\'utilisation et de rapports d\'incident à Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Clavier QWERTY allemand"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglais (Royaume-Uni)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglais (États-Unis)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'étude de l\'utilisabilité"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index de95ab8d7..6b17d6751 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android कीबोर्ड"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android कीबोर्ड (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android कीबोर्ड सेटिंग"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"इनपुट विकल्‍प"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android correction"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"वर्तनी जांच सेटिंग"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"निकटस्थ डेटा उपयोग करें"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"वर्तनी जांचने के लि‍ए कीबोर्ड जैसे नि‍कटस्‍थ एल्‍गोरि‍दम का उपयोग करें"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"संपर्क नामों को खोजें"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"वर्तनी परीक्षक आपकी संपर्क सूची की प्रविष्टियों का उपयोग करता है"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"कुंजी दबाने पर कंपन करता है"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"कुंजी दबाने पर आवाज"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"कुंजी दबाने पर पॉपअप दिखाएं"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: सहेजा गया"</string>
<string name="label_go_key" msgid="1635148082137219148">"जाएं"</string>
<string name="label_next_key" msgid="362972844525672568">"अगला"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"पूर्ण"</string>
<string name="label_send_key" msgid="2815056534433717444">"भेजें"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"ध्‍वनि इनपुट"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"मुस्कुराता चेहरा"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"रिटर्न"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"अल्पविराम"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"पूर्णविराम"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"बायां कोष्ठक"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"दायां कोष्ठक"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"अपूर्ण विराम"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"अर्द्धविराम"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"विस्मयादिबोधक चिह्न"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"प्रश्नचिह्न"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"दोहरा उद्धरण"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"एकल उद्धरण"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"बिंदु"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"वर्गमूल"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"पाइ"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"डेल्टा"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"ट्रेडमार्क"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"संरक्षक"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"तारा"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"पाउंड"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"पदलोप चिह्न"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"निम्न दोहरा उद्धरण"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"ध्‍वनि इनपुट"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ध्‍वनि इनपुट आपकी भाषा के लिए अभी समर्थित नहीं है, पर अंग्रेज़ी में कार्य करता है."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ध्‍वनि इनपुट Google की वाक् पहचान का उपयोग करता है. "<a href="http://m.google.com/privacy">"मोबाइल गोपनीयता नीति"</a>" लागू होती है."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"उपयोगकर्ता फ़ीडबैक सक्षम करें"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"उपयोग के आंकड़े और क्रैश रिपोर्ट Google को स्वचालित रूप से भेज कर इस इनपुट पद्धति संपादक को बेहतर बनाने में सहायता करें."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"कीबोर्ड थीम"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"जर्मन QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेज़ी (यूके)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेज़ी (यूएस)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"उपयोगिता अध्ययन मोड"</string>
diff --git a/java/res/values-hr/donottranslate-more-keys.xml b/java/res/values-hr/donottranslate-more-keys.xml
index c34e0e646..112c444c3 100644
--- a/java/res/values-hr/donottranslate-more-keys.xml
+++ b/java/res/values-hr/donottranslate-more-keys.xml
@@ -21,7 +21,7 @@
<string name="more_keys_for_s">š,ś,ß</string>
<string name="more_keys_for_n">ñ,ń</string>
<string name="more_keys_for_y"></string>
- <string name="more_keys_for_z">6,ž,ź,ż</string>
+ <string name="more_keys_for_z">ž,ź,ż</string>
<string name="more_keys_for_c">č,ć,ç</string>
<string name="more_keys_for_d">đ</string>
</resources>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 30c20b3cc..1d35c613e 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android tipkovnica"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android tipkovnica (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Postavke tipkovnice za Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opcije ulaza"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Ispravak za Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Postavke provjere pravopisa"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Upotreba podataka blizine"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Za prov. pravopisa upotrijebi algoritam blizine kao na tipkovnici"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Potražite imena kontakata"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Provjera pravopisa upotrebljava unose iz vašeg popisa kontakata"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibracija pri pritisku na tipku"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk pri pritisku tipke"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Povećanja na pritisak tipke"</string>
@@ -35,7 +36,7 @@
<string name="misc_category" msgid="6894192814868233453">"Ostale opcije"</string>
<string name="advanced_settings" msgid="362895144495591463">"Napredne postavke"</string>
<string name="advanced_settings_summary" msgid="5193513161106637254">"Opcije za stručne korisnike"</string>
- <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Bez odgode klj. skočnih"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Odgoda prikaza tipki"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez odgode"</string>
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Zadano"</string>
<string name="use_contacts_dict" msgid="4435317977804180815">"Predlaži imena kontakata"</string>
@@ -52,7 +53,7 @@
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Uvijek sakrij"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Prikaži tipku postavki"</string>
<string name="auto_correction" msgid="4979925752001319458">"Samoispravak"</string>
- <string name="auto_correction_summary" msgid="5625751551134658006">"Razm. i intrp. aut. ispr. kr. rči."</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Razmak i interpunkcija automatski ispravljaju krive riječi"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Isključeno"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Skromno"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivno"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Spremljeno"</string>
<string name="label_go_key" msgid="1635148082137219148">"Idi"</string>
<string name="label_next_key" msgid="362972844525672568">"Dalje"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Gotovo"</string>
<string name="label_send_key" msgid="2815056534433717444">"Pošalji"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Glasovni unos"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smješko"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Zarez"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Točka"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Lijeva zagrada"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Desna zagrada"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dvotočka"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Točka-zarez"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Uskličnik"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Upitnik"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dvostruki navodnici"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Jednostruki navodnici"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Točka"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Kvadratni korijen"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Zaštitni znak"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"U ruke"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Zvjezdica"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"funta"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Tri točke"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Donji dvostruki navodnici"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Glasovni ulaz"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Vaš jezik trenutno nije podržan za glasovni unos, ali radi za engleski."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Glasovni unos upotrebljava Googleovo prepoznavanje govora. Primjenjuju se "<a href="http://m.google.com/privacy">"Pravila o privatnosti za uslugu Mobile"</a>"."</string>
@@ -132,7 +116,7 @@
<string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Na glavnoj tipkovnici"</string>
<string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Na tipkovnici simb."</string>
<string name="voice_input_modes_off" msgid="3745699748218082014">"Isključeno"</string>
- <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mik. na gl. tipk."</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mikrofon na gl. tipkovnici"</string>
<string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mik. na tipk. simb."</string>
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Glas. unos onemog."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Odabir ulazne metode"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Omogući korisničke povratne informacije"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Pomozite u poboljšanju ovog urednika ulazne metode automatskim slanjem statistike upotrebe i padova Googleu."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"njemački QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engleski (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engleski (SAD)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način studije upotrebljivosti"</string>
diff --git a/java/res/values-hu/donottranslate-more-keys.xml b/java/res/values-hu/donottranslate-more-keys.xml
index 42b330199..cc23dff48 100644
--- a/java/res/values-hu/donottranslate-more-keys.xml
+++ b/java/res/values-hu/donottranslate-more-keys.xml
@@ -19,10 +19,8 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">á,à,â,ä,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,é,è,ê,ë,ę,ė,ē</string>
- <string name="more_keys_for_i">8,í,î,ï,ì,į,ī</string>
- <string name="more_keys_for_o">9,ó,ö,ő,ô,ò,õ,œ,ø,ō</string>
- <string name="more_keys_for_u">7,ú,ü,ű,û,ù,ū</string>
- <string name="more_keys_for_y"></string>
- <string name="more_keys_for_z">6</string>
+ <string name="more_keys_for_e">é,è,ê,ë,ę,ė,ē</string>
+ <string name="more_keys_for_i">í,î,ï,ì,į,ī</string>
+ <string name="more_keys_for_o">ó,ö,ő,ô,ò,õ,œ,ø,ō</string>
+ <string name="more_keys_for_u">ú,ü,ű,û,ù,ū</string>
</resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index 180b6fcf9..de2e812d7 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android-billentyűzet"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-billentyűzet (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android billentyűzetbeállítások"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Beviteli beállítások"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android korrekció"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Helyesírás-ellenőrzés beállításai"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Közelségi adatok haszn."</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Billentyűzetszerű algoritmus a helyesírás-ellenőrzéshez"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Névjegyek keresése"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"A helyesírás-ellenőrző használja a névjegyek bejegyzéseit"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Rezgés billentyű megnyomása esetén"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Hangjelzés billentyű megnyomása esetén"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Legyen nagyobb billentyű lenyomásakor"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : mentve"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ugrás"</string>
<string name="label_next_key" msgid="362972844525672568">"Tovább"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Kész"</string>
<string name="label_send_key" msgid="2815056534433717444">"Küldés"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Hangbevitel"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Mosolygós arc"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Vessző"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Pont"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Nyitó zárójel"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Berekesztő zárójel"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Kettőspont"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Pontosvessző"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Felkiáltójel"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Kérdőjel"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dupla idézőjel"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Szimpla idézőjel"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Pont"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Négyzetgyök"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Védjegy"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Százalék"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Csillag"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Kettős kereszt"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Kihagyás"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Alsó dupla idézőjel"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Hangbevitel"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A hangbevitel szolgáltatás jelenleg nem támogatja az Ön nyelvét, ám angolul működik."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A hangbevitel a Google beszédfelismerő technológiáját használja, amelyre a "<a href="http://m.google.com/privacy">"Mobil adatvédelmi irányelvek"</a>" érvényesek."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Felhasználói visszajelzés engedélyezése"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Segíthet ennek a beviteli módszernek a javításában, ha engedélyezi a használati statisztikák és a hibajelentések elküldését a Google-nak."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Billentyűzettéma"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Német QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angol (brit)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angol (amerikai)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Használhatósági teszt"</string>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index a023b6477..92b485622 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Keyboard Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Keyboard Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Setelan keyboard Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opsi masukan"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Koreksi android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Setelan pemeriksaan ejaan"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Gunakan data kedekatan"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Gunakan algoritme kedekatan seperti keyboard untuk memeriksa ejaan"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cari nama kenalan"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Pemeriksa ejaan menggunakan entri dari daftar kenalan Anda"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Getar jika tombol ditekan"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Berbunyi jika tombol ditekan"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Muncul saat tombol ditekan"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Telah disimpan"</string>
<string name="label_go_key" msgid="1635148082137219148">"Buka"</string>
<string name="label_next_key" msgid="362972844525672568">"Berikutnya"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Selesai"</string>
<string name="label_send_key" msgid="2815056534433717444">"Kirimkan"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Masukan suara"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Wajah tersenyum"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Kembali"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Koma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Titik"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Kurung tutup"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Kurung buka"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Titik Dua"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Titik koma"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Tanda seru"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Tanda tanya"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Tanda petik"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Petik tunggal"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Akar pangkat dua"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Merek dagang"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Dengan alamat"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Bintang"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Pon"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Elipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Tanda petik bawah"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Masukan suara"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Masukan suara saat ini tidak didukung untuk bahasa Anda, tetapi bekerja dalam Bahasa Inggris."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Masukan suara menggunakan pengenalan ucapan Google. "<a href="http://m.google.com/privacy">"Kebijakan Privasi Seluler"</a>" berlaku."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Aktifkan umpan balik pengguna"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Bantu tingkatkan metode editor masukan dengan mengirim statistik penggunaan dan laporan kerusakan ke Google secara otomatis."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema keyboard"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY Jerman"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inggris (Inggris)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inggris (AS)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus studi daya guna"</string>
diff --git a/java/res/values-it/donottranslate-more-keys.xml b/java/res/values-it/donottranslate-more-keys.xml
index fa1537bec..69659a389 100644
--- a/java/res/values-it/donottranslate-more-keys.xml
+++ b/java/res/values-it/donottranslate-more-keys.xml
@@ -19,8 +19,8 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">à,á,â,ä,æ,ã,å,ā,ª</string>
- <string name="more_keys_for_e">3,è,é,ê,ë,ę,ė,ē</string>
- <string name="more_keys_for_i">8,ì,í,î,ï,į,ī</string>
- <string name="more_keys_for_o">9,ò,ó,ô,ö,õ,œ,ø,ō,º</string>
- <string name="more_keys_for_u">7,ù,ú,û,ü,ū</string>
+ <string name="more_keys_for_e">è,é,ê,ë,ę,ė,ē</string>
+ <string name="more_keys_for_i">ì,í,î,ï,į,ī</string>
+ <string name="more_keys_for_o">ò,ó,ô,ö,õ,œ,ø,ō,º</string>
+ <string name="more_keys_for_u">ù,ú,û,ü,ū</string>
</resources>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 58c0e2c3b..38e622c2c 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Tastiera Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Tastiera Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Impostazioni tastiera Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opzioni inserimento"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Correzione Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Impostazioni di controllo ortografico"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Usa i dati di prossimità"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Usa algoritmo prossimità (come in tastiere) per controllo ortografico"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cerca in nomi contatti"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"La funzione di controllo ortografico usa voci dell\'elenco contatti"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrazione tasti"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Suono tasti"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup sui tasti"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string>
<string name="label_go_key" msgid="1635148082137219148">"Vai"</string>
<string name="label_next_key" msgid="362972844525672568">"Avanti"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Fine"</string>
<string name="label_send_key" msgid="2815056534433717444">"Invia"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Input vocale"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smile"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Invio"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Virgola"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punto"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Parentesi aperta"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Parentesi chiusa"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Due punti"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Punto e virgola"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Punto esclamativo"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Punto interrogativo"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Virgolette doppie"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Virgolette semplici"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Pallino"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Radice quadrata"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi greco"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marchio commerciale"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Presso"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Asterisco"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Cancelletto"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellissi"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Virgolette doppie basse"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Comandi vocali"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"L\'input vocale utilizza il riconoscimento vocale di Google. Sono valide le "<a href="http://m.google.com/privacy">"norme sulla privacy di Google Mobile"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Attiva commenti degli utenti"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Aiuta a migliorare l\'editor del metodo di inserimento inviando automaticamente a Google statistiche sull\'utilizzo e segnalazioni sugli arresti anomali."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema della tastiera"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY tedesca"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglese (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglese (USA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modalità Studio sull\'usabilità"</string>
diff --git a/java/res/values-iw/donottranslate-more-keys.xml b/java/res/values-iw/donottranslate-more-keys.xml
index 829486f7b..f44ff2123 100644
--- a/java/res/values-iw/donottranslate-more-keys.xml
+++ b/java/res/values-iw/donottranslate-more-keys.xml
@@ -20,4 +20,41 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_star">★</string>
<string name="more_keys_for_plus">±,﬩</string>
+ <!-- The all letters need to be mirrored are found at
+ http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+ <integer name="keycode_for_left_parenthesis">0x0029</integer>
+ <integer name="keycode_for_right_parenthesis">0x0028</integer>
+ <string name="more_keys_for_left_parenthesis">[|],{|},&lt;|&gt;</string>
+ <string name="more_keys_for_right_parenthesis">]|[,}|{,&gt;|&lt;</string>
+ <integer name="keycode_for_less_than">0x003e</integer>
+ <integer name="keycode_for_greater_than">0x003c</integer>
+ <!-- \u2264: LESS-THAN OR EQUAL TO
+ \u2265: GREATER-THAN EQUAL TO
+ \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ The following characters don't need BIDI mirroring.
+ \u2018: LEFT SINGLE QUOTATION MARK
+ \u2019: RIGHT SINGLE QUOTATION MARK
+ \u201a: SINGLE LOW-9 QUOTATION MARK
+ \u201b: SINGLE HIGH-REVERSED-9 QUOTATION MARK
+ \u201c: LEFT DOUBLE QUOTATION MARK
+ \u201d: RIGHT DOUBLE QUOTATION MARK
+ \u201e: DOUBLE LOW-9 QUOTATION MARK
+ \u201f: DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+ <string name="more_keys_for_less_than">\u2264|\u2265,\u00ab|\u00bb,\u2039|\u203a</string>
+ <string name="more_keys_for_greater_than">\u2265|\u2264,\u00bb|\u00ab,\u203a|\u2039</string>
+ <integer name="keycode_for_left_square_bracket">0x005d</integer>
+ <integer name="keycode_for_right_square_bracket">0x005b</integer>
+ <integer name="keycode_for_left_curly_bracket">0x007d</integer>
+ <integer name="keycode_for_right_curly_bracket">0x007b</integer>
+ <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+ <!-- <string name="more_keys_for_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb</string> -->
+ <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+ <string name="more_keys_for_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab</string>
+ <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+ <!-- <string name="more_keys_for_tablet_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb,\u2018,\u2019,\u201a,\u201b</string> -->
+ <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
+ <string name="more_keys_for_tablet_double_quote">\u201d,\u00ab|\u00bb,\u201c,\u00bb|\u00ab,\u2019,\u201a,\u2018,\u201b</string>
</resources>
diff --git a/java/res/values-iw/donottranslate.xml b/java/res/values-iw/donottranslate.xml
new file mode 100644
index 000000000..a9aad4e3c
--- /dev/null
+++ b/java/res/values-iw/donottranslate.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- The all letters need to be mirrored are found at
+ http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+ <!-- Symbols that are suggested between words -->
+ <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
+</resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 292517c68..9aeaffd89 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"מקלדת Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"מקלדת Android ‏(AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"הגדרות מקלדת של Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"אפשרויות קלט"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"תיקון Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"הגדרות בדיקת איות"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"שימוש בנתוני הקירבה"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"השתמש באלגוריתם קירבה דמוי-מקלדת עבור בדיקת איות"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"חפש שמות של אנשי קשר"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"בודק האיות משתמש בערכים מרשימת אנשי הקשר שלך"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"רטט בלחיצה על מקשים"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"צלילים בעת לחיצה על מקשים"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"חלון קופץ בלחיצה על מקש"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : נשמרה"</string>
<string name="label_go_key" msgid="1635148082137219148">"בצע"</string>
<string name="label_next_key" msgid="362972844525672568">"הבא"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"סיום"</string>
<string name="label_send_key" msgid="2815056534433717444">"שלח"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"אבג"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"קלט קולי"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"פרצוף סמיילי"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"חזור"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"פסיק"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"נקודה"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"סוגריים שמאליים"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"סוגריים ימניים"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"נקודתיים"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"נקודה פסיק"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"סימן קריאה"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"סימן שאלה"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"מרכאות כפולות"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"גרש בודד"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"נקודה"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"שורש ריבועי"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"פאי"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"דלתה"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"סימן מסחרי"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"לכבוד"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"כוכב"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"סולמית"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"שלוש נקודות"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"מרכאות כפולות תחתונות"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"קלט קולי"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"קלט קולי אינו נתמך בשלב זה בשפתך, אך הוא פועל באנגלית."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"קלט קולי משתמש בזיהוי דיבור של Google.‏ "<a href="http://m.google.com/privacy">"מדיניות הפרטיות של \'Google לנייד\'"</a>" חלה במקרה זה."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"הפוך משוב ממשתמשים לפעיל"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"עזור לשפר את עורך שיטת הקלט על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסת מחשב ל-Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"עיצוב מקלדת"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"מקלדת QWERTY גרמנית"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"אנגלית (בריטניה)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"אנגלית (ארה\"ב)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"מצב מחקר שימושיות"</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 540bb4688..f684e2131 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Androidキーボード"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Androidキーボード(AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Androidキーボードの設定"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"入力オプション"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Androidスペルチェッカー"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"スペルチェックの設定"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"近接データを使用"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"スペルチェックでキーボードと同じような近接アルゴリズムを使用する"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"連絡先名の検索"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"スペルチェッカーでは連絡先リストのエントリを使用します"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"キー操作バイブ"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"キー操作音"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"キー押下時ポップアップ"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:保存しました"</string>
<string name="label_go_key" msgid="1635148082137219148">"実行"</string>
<string name="label_next_key" msgid="362972844525672568">"次へ"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"完了"</string>
<string name="label_send_key" msgid="2815056534433717444">"送信"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"音声入力"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"顔文字"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"カンマ"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"ピリオド"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"左かっこ"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"右かっこ"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"コロン"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"セミコロン"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"感嘆符"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"疑問符"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"二重引用符"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"単一引用符"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"中点"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"平方根"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"円周率記号"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"デルタ"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"商標記号"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"宛名記号"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"アスタリスク"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"ナンバー記号"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"省略記号"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"下付き二重引用符"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"音声入力"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"音声入力は現在英語には対応していますが、日本語には対応していません。"</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"音声入力ではGoogleの音声認識技術を利用します。"<a href="http://m.google.com/privacy">"モバイルプライバシーポリシー"</a>"が適用されます。"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"ユーザーフィードバックを有効にする"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"IMEの機能向上のため、使用統計状況やクラッシュレポートをGoogleに自動送信します。"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"キーボードのテーマ"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"ドイツ語QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英語(英国)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英語(米国)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"使いやすさの研究モード"</string>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index bc2b6289c..56705953c 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android 키보드"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android 키보드(AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android 키보드 설정"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"입력 옵션"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android 교정"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"맞춤법 검사 설정"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"근접 데이터 사용"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"맞춤법 검사에 대해 키보드와 유사한 근접 알고리즘 사용"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"연락처 이름 조회"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"맞춤법 검사기가 주소록의 항목을 사용합니다."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"키를 누를 때 진동 발생"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"키를 누를 때 소리 발생"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"키를 누를 때 팝업"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: 저장됨"</string>
<string name="label_go_key" msgid="1635148082137219148">"이동"</string>
<string name="label_next_key" msgid="362972844525672568">"다음"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"완료"</string>
<string name="label_send_key" msgid="2815056534433717444">"전송"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"음성 입력"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"웃는 얼굴"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"리턴 키"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"쉼표"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"마침표"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"왼쪽 괄호"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"오른쪽 괄호"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"콜론"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"세미콜론"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"느낌표"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"물음표"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"큰따옴표"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"작은따옴표"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"점"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"제곱근"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"파이"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"델타"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"상표(™)"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"퍼센트 키"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"별표"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"파운드"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"생략 부호"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"아래쪽 큰따옴표"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"음성 입력"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"음성 입력은 현재 자국어로 지원되지 않으며 영어로 작동됩니다."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"음성 입력에서는 Google의 음성 인식 기능을 사용합니다. "<a href="http://m.google.com/privacy">"모바일 개인정보취급방침"</a>"이 적용됩니다."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"사용자 의견 사용"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"사용 통계 및 충돌 보고서를 Google에 자동으로 전송하여 입력 방법 편집기의 개선에 도움을 줍니다."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"키보드 테마"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"독일어 QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"영어(영국)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"영어(미국)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"가용성 연구 모드"</string>
diff --git a/java/res/values-fr-rCA/donottranslate-more-keys.xml b/java/res/values-ky/donottranslate-more-keys.xml
index 80e9d9346..44720aa7f 100644
--- a/java/res/values-fr-rCA/donottranslate-more-keys.xml
+++ b/java/res/values-ky/donottranslate-more-keys.xml
@@ -18,8 +18,7 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">à,â,æ,á,ä,ã,å,ā,ª</string>
- <string name="more_keys_for_q">1</string>
- <string name="more_keys_for_w">2</string>
- <string name="more_keys_for_z"></string>
+ <string name="more_keys_for_slavic_u">ү</string>
+ <string name="more_keys_for_slavic_en">ң</string>
+ <string name="more_keys_for_slavic_o">ө</string>
</resources>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index 4a5c5a44c..f9cce839a 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -53,6 +53,7 @@
<fraction name="key_hint_label_ratio">52%</fraction>
<fraction name="key_uppercase_letter_ratio">40%</fraction>
<fraction name="key_preview_text_ratio">90%</fraction>
+ <fraction name="spacebar_text_ratio">40.000%</fraction>
<dimen name="key_preview_offset">0.08in</dimen>
<dimen name="key_preview_offset_ics">0.01in</dimen>
@@ -65,7 +66,7 @@
<dimen name="key_preview_backing_height">72dip</dimen>
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
<!-- popup_key_height x 1.2 -->
- <dimen name="mini_keyboard_slide_allowance">0.336in</dimen>
+ <dimen name="more_keys_keyboard_slide_allowance">0.336in</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="mini_keyboard_vertical_correction">-0.280in</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction">-0.280in</dimen>
</resources>
diff --git a/java/res/values-lt/donottranslate-more-keys.xml b/java/res/values-lt/donottranslate-more-keys.xml
index 6b81e4509..fc6c84b2d 100644
--- a/java/res/values-lt/donottranslate-more-keys.xml
+++ b/java/res/values-lt/donottranslate-more-keys.xml
@@ -18,11 +18,20 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">ą,à,á,â,ä,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,ė,ę,è,é,ê,ë,ē</string>
- <string name="more_keys_for_i">8,į,î,ï,ì,í,ī</string>
- <string name="more_keys_for_u">7,ų,ū,û,ü,ù,ú</string>
- <string name="more_keys_for_s">š,ß,ś</string>
+ <string name="more_keys_for_a">ą,ä,ā,à,á,â,ã,å,æ</string>
+ <string name="more_keys_for_e">ė,ę,ē,è,é,ê,ë,ě</string>
+ <string name="more_keys_for_i">į,ī,ì,í,î,ï,ı</string>
+ <string name="more_keys_for_o">ö,õ,ò,ó,ô,œ,ő,ø</string>
+ <string name="more_keys_for_u">ū,ų,ü,ū,ù,ú,û,ů,ű</string>
+ <string name="more_keys_for_s">š,ß,ś,ş</string>
+ <string name="more_keys_for_n">ņ,ñ,ń,ń</string>
<string name="more_keys_for_c">č,ç,ć</string>
- <string name="more_keys_for_z">ž,ź,ż</string>
+ <string name="more_keys_for_y">ý,ÿ</string>
+ <string name="more_keys_for_d">ď</string>
+ <string name="more_keys_for_r">ŗ,ř,ŕ</string>
+ <string name="more_keys_for_t">ţ,ť</string>
+ <string name="more_keys_for_z">ž,ż,ź</string>
+ <string name="more_keys_for_k">ķ</string>
+ <string name="more_keys_for_l">ļ,ł,ĺ,ľ</string>
+ <string name="more_keys_for_g">ģ,ğ</string>
</resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 6263f6706..93b52b530 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"„Android“ klaviatūra"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"„Android“ klaviatūra (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"„Android“ klaviatūros nustatymai"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Įvesties parinktys"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"„Android“ korekcijos"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Rašybos tikrinimo nustatymai"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Naudoti artimumo duomenis"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Naudokite klaviatūros tipo artimumo algoritmą rašybai patikrinti"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontaktų vardų paieška"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Rašybos tikrinimo progr. naudoja įrašus, esančius kontaktų sąraše"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibruoti, kai paspaudžiami klavišai"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Klavišo paspaudimo garsas"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Iššoka paspaudus klavišą"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: išsaugota"</string>
<string name="label_go_key" msgid="1635148082137219148">"Pradėti"</string>
<string name="label_next_key" msgid="362972844525672568">"Kitas"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Atlikta"</string>
<string name="label_send_key" msgid="2815056534433717444">"Siųsti"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Įvestis balsu"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Šypsenėlė"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Grįžti"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Kablelis"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Taškas"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Kairysis skliaustas"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Dešinysis skliaustas"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dvitaškis"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Kabliataškis"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Šauktukas"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Klaustukas"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dvigubos kabutės"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Viengubos kabutės"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Taškas"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Kvadratinė šaknis"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Prekės ženklas"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Perduoti"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Pažymėti žvaigždute"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Svaras"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Daugtaškis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Apatinės dvigubos kabutės"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Balso įvestis"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Šiuo metu balso įvestis jūsų kompiuteryje nepalaikoma, bet ji veikia anglų k."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Balso įvesčiai naudojamas „Google“ kalbos atpažinimas. Taikoma "<a href="http://m.google.com/privacy">"privatumo politika mobiliesiems"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Įgalinti naudotojų atsiliepimus"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Padėkite patobulinti šią įvesties metodo redagavimo programą automatiškai „Google“ siųsdami naudojimo statistiką ir strigčių ataskaitas."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klaviatūros tema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Vokiška QWERTY klaviatūra"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglų k. (JK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglų k. (JAV)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tinkamumo tyrimo režimas"</string>
diff --git a/java/res/values-lv/donottranslate-more-keys.xml b/java/res/values-lv/donottranslate-more-keys.xml
index 77e1c26a0..3b937dfe3 100644
--- a/java/res/values-lv/donottranslate-more-keys.xml
+++ b/java/res/values-lv/donottranslate-more-keys.xml
@@ -18,16 +18,20 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">ā,à,á,â,ä,æ,ã,å</string>
- <string name="more_keys_for_e">3,ē,è,é,ê,ë,ę,ė</string>
- <string name="more_keys_for_i">8,ī,î,ï,ì,í,į</string>
- <string name="more_keys_for_u">7,ū,û,ü,ù,ú</string>
- <string name="more_keys_for_s">š,ß,ś</string>
- <string name="more_keys_for_n">ņ,ñ,ń</string>
+ <string name="more_keys_for_a">ā,à,á,â,ã,ä,å,æ,ą</string>
+ <string name="more_keys_for_e">ē,ė,è,é,ê,ë,ę,ě</string>
+ <string name="more_keys_for_i">ī,į,ì,í,î,ï,ı</string>
+ <string name="more_keys_for_o">ò,ó,ô,õ,ö,œ,ő,ø</string>
+ <string name="more_keys_for_u">ū,ų,ù,ú,û,ü,ů,ű</string>
+ <string name="more_keys_for_s">š,ß,ś,ş</string>
+ <string name="more_keys_for_n">ņ,ñ,ń,ń</string>
<string name="more_keys_for_c">č,ç,ć</string>
- <string name="more_keys_for_r">4,ŗ</string>
- <string name="more_keys_for_z">ž,ź,ż</string>
+ <string name="more_keys_for_y">ý,ÿ</string>
+ <string name="more_keys_for_d">ď</string>
+ <string name="more_keys_for_r">ŗ,ř,ŕ</string>
+ <string name="more_keys_for_t">ţ,ť</string>
+ <string name="more_keys_for_z">ž,ż,ź</string>
<string name="more_keys_for_k">ķ</string>
- <string name="more_keys_for_l">ļ,ł</string>
- <string name="more_keys_for_g">ģ</string>
+ <string name="more_keys_for_l">ļ,ł,ĺ,ľ</string>
+ <string name="more_keys_for_g">ģ,ğ</string>
</resources>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index af01d92f6..6fc1d996e 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android tastatūra"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android tastatūra (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android tastatūras iestatījumi"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Ievades opcijas"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android korekcija"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Pareizrakstības pārbaudes iestatījumi"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Tuvuma datu izmantošana"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Pareizrakstības pārbaudei izmantojiet tastatūrai līdzīgu tuvuma algoritmu."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Meklēt kontaktp. vārdus"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Pareizrakst. pārbaudītājs lieto ierakstus no kontaktp. saraksta."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrēt, nospiežot taustiņu"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Skaņa, nospiežot taustiņu"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Nospiežot taustiņu, parādīt uznirstošo izvēlni"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: saglabāts"</string>
<string name="label_go_key" msgid="1635148082137219148">"Sākt"</string>
<string name="label_next_key" msgid="362972844525672568">"Tālāk"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Gatavs"</string>
<string name="label_send_key" msgid="2815056534433717444">"Sūtīt"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Balss ievade"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smaidoša seja"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Ievadīšanas taustiņš"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komats"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punkts"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Kreisā iekava"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Labā iekava"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Kols"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikols"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Izsaukuma zīme"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Jautājuma zīme"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Pēdiņas"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Vienpēdiņas"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkts"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Kvadrātsakne"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pī"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Preču zīme"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"c/o"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Zvaigznīte"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Cipara simbols"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Daudzpunkte"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Apakšējās pēdiņas"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Balss ievade"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Balss ievade jūsu valodā pašlaik netiek atbalstīta, taču tā ir pieejama angļu valodā."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Balss ievadei tiek izmantota Google runas atpazīšanas funkcija. Uz šīs funkcijas lietošanu attiecas "<a href="http://m.google.com/privacy">"mobilo sakaru ierīču lietošanas konfidencialitātes politika"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Iespējot lietotāju atsauksmes"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Palīdziet uzlabot šo ievades metodes redaktoru, automātiski nosūtot lietojuma statistiku un pārskatus par avārijām uzņēmumam Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastatūras motīvs"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Vācu valodas QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Angļu valoda (Lielbritānija)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Angļu valoda (ASV)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Lietojamības izpētes režīms"</string>
diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml
index d6bf559e7..e75cc80e3 100644
--- a/java/res/values-ms/strings.xml
+++ b/java/res/values-ms/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Papan kekunci Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Papan kekunci Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Tetapan papan kekunci Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Pilihan input"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Pembetulan Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Tetapan penyemakan ejaan"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Gunakan data kehampiran"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Gunakan algoritma kehampiran ala papan kekunci untuk pemeriksaan ejaan"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cari nama kenalan"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Penyemak ejaan menggunakan entri dari senarai kenalan anda"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Getar pada tekanan kekunci"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Bunyi pada tekanan kekunci"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop timbul pada tekanan kunci"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Disimpan"</string>
<string name="label_go_key" msgid="1635148082137219148">"Pergi"</string>
<string name="label_next_key" msgid="362972844525672568">"Seterusnya"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Selesai"</string>
<string name="label_send_key" msgid="2815056534433717444">"Hantar"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Input suara"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Muka senyum"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Koma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Tempoh"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Tanda kurung kiri"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Tanda kurung kanan"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Titik bertindih"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Koma bertitik"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Tanda seru"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Tanda soal"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Tanda petikan berganda"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Tanda petikan tunggal"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Punca kuasa dua"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Tanda dagangan"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Dengan alamat"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Bintang"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Paun"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Elipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Tanda petikan berganda rendah"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Input suara"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Input suara tidak disokong untuk bahasa anda pada masa ini tetapi ia berfungsi dalam bahasa Inggeris."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Input suara menggunakan pengecaman pertuturan Google. "<a href="http://m.google.com/privacy">"Dasar Privasi Mudah Alih"</a>" digunakan."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Dayakan maklum balas pengguna"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Bantu memperbaik editor input ini dengan menghantar statistik penggunaan dan laporan runtuhan kepada Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema papan kekunci"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY Bahasa Jerman"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Bahasa Inggeris (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Bahasa Inggeris (AS)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mod kajian kebolehgunaan"</string>
diff --git a/java/res/values-nb/donottranslate-more-keys.xml b/java/res/values-nb/donottranslate-more-keys.xml
index b98341c6a..cf6e4d1ce 100644
--- a/java/res/values-nb/donottranslate-more-keys.xml
+++ b/java/res/values-nb/donottranslate-more-keys.xml
@@ -19,9 +19,10 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">à,ä,á,â,ã,ā</string>
- <string name="more_keys_for_e">3,é,è,ê,ë,ę,ė,ē</string>
- <string name="more_keys_for_o">9,ô,ò,ó,ö,õ,œ,ō</string>
- <string name="more_keys_for_u">7,ü,û,ù,ú,ū</string>
+ <string name="more_keys_for_e">é,è,ê,ë,ę,ė,ē</string>
+ <string name="more_keys_for_o">ô,ò,ó,ö,õ,œ,ō</string>
+ <string name="more_keys_for_u">ü,û,ù,ú,ū</string>
+ <string name="keylabel_for_scandinavia_row1_11">å</string>
<string name="keylabel_for_scandinavia_row2_10">ø</string>
<string name="keylabel_for_scandinavia_row2_11">æ</string>
<string name="more_keys_for_scandinavia_row2_10">ö</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index acd636bdd..1141e3314 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Skjermtastatur"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-tastatur (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Innstillinger for skjermtastatur"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Inndataalternativer"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android-stavekontroll"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Innstillinger for stavekontroll"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Bruk nærhetsdata"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Bruk en tastaturlignende algoritme til stavekontroll"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Slå opp kontaktnavn"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Stavekontrollen bruker oppføringer fra kontaktlisten din"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer ved tastetrykk"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetrykk"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Hurtigvindu ved tastetrykk"</string>
@@ -64,6 +65,7 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string>
<string name="label_go_key" msgid="1635148082137219148">"Gå"</string>
<string name="label_next_key" msgid="362972844525672568">"Neste"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Tidl."</string>
<string name="label_done_key" msgid="2441578748772529288">"Utfør"</string>
<string name="label_send_key" msgid="2815056534433717444">"Send"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +90,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Taleinndata"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smilefjes"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punktum"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Venstre parentes"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Høyre parentes"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Kolon"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikolon"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Utropstegn"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Spørsmålstegn"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dobbelt anførselstegn"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Enkelt anførselstegn"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Prikk"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Kvadratrot"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Varemerke"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"c/o"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Stjerne"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Firkant"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipse"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Lavt dobbelt anførselstegn"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Stemmedata"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmedata håndteres foreløpig ikke på ditt språk, men fungerer på engelsk."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Google Voice bruker Googles talegjenkjenning. "<a href="http://m.google.com/privacy">"Personvernreglene for mobil"</a>" gjelder."</string>
@@ -144,7 +127,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Aktiver brukertilbakemelding"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Ved å sende bruksstatistikk og programstopprapporter til Google automatisk, hjelper du oss med å gjøre redigeringsfunksjonen for denne inndatametoden enda bedre."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Tysk QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engelsk (Storbritannia)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engelsk (USA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Nyttighetsmodus"</string>
diff --git a/java/res/values-nl/donottranslate-more-keys.xml b/java/res/values-nl/donottranslate-more-keys.xml
index 49cc41964..ac03872f3 100644
--- a/java/res/values-nl/donottranslate-more-keys.xml
+++ b/java/res/values-nl/donottranslate-more-keys.xml
@@ -19,9 +19,9 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">á,ä,â,à,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,é,ë,ê,è,ę,ė,ē</string>
- <string name="more_keys_for_i">8,í,ï,ì,î,į,ī</string>
- <string name="more_keys_for_o">9,ó,ö,ô,ò,õ,œ,ø,ō</string>
- <string name="more_keys_for_u">7,ú,ü,û,ù,ū</string>
+ <string name="more_keys_for_e">é,ë,ê,è,ę,ė,ē</string>
+ <string name="more_keys_for_i">í,ï,ì,î,į,ī</string>
+ <string name="more_keys_for_o">ó,ö,ô,ò,õ,œ,ø,ō</string>
+ <string name="more_keys_for_u">ú,ü,û,ù,ū</string>
<string name="more_keys_for_n">ñ,ń</string>
</resources>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 7f0ff7eaf..6da587a73 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android-toetsenbord"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android-toetsenbord (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Instellingen voor Android-toetsenbord"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Invoeropties"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android-spellingcontrole"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Instellingen voor spellingcontrole"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Nabije toetsinfo gebr."</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Algoritme voor nabije toetsen gebruiken voor spellingcontrole"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Contactnamen opzoeken"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"De spellingcontrole gebruikt items uit uw contactenlijst"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Trillen bij toetsaanslag"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Geluid bij toetsaanslag"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bij toetsaanslag"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: opgeslagen"</string>
<string name="label_go_key" msgid="1635148082137219148">"Start"</string>
<string name="label_next_key" msgid="362972844525672568">"Verder"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Gereed"</string>
<string name="label_send_key" msgid="2815056534433717444">"Zenden"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Spraakinvoer"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley-gezichtje"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punt"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Linkerhaakje"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Rechterhaakje"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dubbele punt"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Puntkomma"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Uitroepteken"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Vraagteken"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dubbele aanhalingstekens"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Enkel aanhalingsteken"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Stip"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Vierkantswortel"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Handelsmerk"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Ten attentie van"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Ster"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Hekje"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Weglatingsteken"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Lage dubbele aanhalingstekens"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Spraakinvoer"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Spraakinvoer maakt gebruik van de spraakherkenning van Google. Het "<a href="http://m.google.com/privacy">"Privacybeleid van Google Mobile"</a>" is van toepassing."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Gebruikersfeedback inschakelen."</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Help deze invoermethode te verbeteren door automatisch gebruiksstatistieken en crashmeldingen naar Google te verzenden."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Toetsenbordthema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Duits QWERTY-toetsenbord"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engels (GB)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engels (VS)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus voor gebruiksvriendelijkheidsonderzoek"</string>
diff --git a/java/res/values-pl/donottranslate-more-keys.xml b/java/res/values-pl/donottranslate-more-keys.xml
index 18e149991..84e74e849 100644
--- a/java/res/values-pl/donottranslate-more-keys.xml
+++ b/java/res/values-pl/donottranslate-more-keys.xml
@@ -19,8 +19,8 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">ą,á,à,â,ä,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,ę,è,é,ê,ë,ė,ē</string>
- <string name="more_keys_for_o">9,ó,ö,ô,ò,õ,œ,ø,ō</string>
+ <string name="more_keys_for_e">ę,è,é,ê,ë,ė,ē</string>
+ <string name="more_keys_for_o">ó,ö,ô,ò,õ,œ,ø,ō</string>
<string name="more_keys_for_s">ś,ß,š</string>
<string name="more_keys_for_n">ń,ñ</string>
<string name="more_keys_for_c">ć,ç,č</string>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index a9a6a76b6..cda725bc3 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Klawiatura Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Klawiatura Androida (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Ustawienia klawiatury Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opcje wprowadzania"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Korekta Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Ustawienia sprawdzania pisowni"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Użyj danych o klawiszach"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Przy sprawdzaniu pisowni używaj algorytmu uwzględniającego położenie klawiszy na klawiaturze"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Przeszukaj nazwy kontaktów"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Sprawdzanie pisowni bierze pod uwagę wpisy z listy kontaktów."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Wibracja przy naciśnięciu"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Dźwięk przy naciśnięciu"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Powiększ po naciśnięciu"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Dalej"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"OK"</string>
<string name="label_send_key" msgid="2815056534433717444">"Wyślij"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,29 +91,10 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Wprowadzanie głosowe"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Uśmiechnięta buźka"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Przecinek"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Kropka"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Lewy nawias"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Prawy nawias"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dwukropek"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Średnik"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Wykrzyknik"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Pytajnik"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Cudzysłów podwójny"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Cudzysłów pojedynczy"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Pierwiastek kwadratowy"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Znak towarowy"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Znak „przez grzeczność”"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Gwiazdka"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Krzyżyk"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Wielokropek"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Cudzysłów podwójny dolny"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Wprowadzanie głosowe"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Wprowadzanie głosowe obecnie nie jest obsługiwane w Twoim języku, ale działa w języku angielskim."</string>
- <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Funkcja wprowadzania głosowego wykorzystuje mechanizm rozpoznawania mowy. Obowiązuje "<a href="http://m.google.com/privacy">"Polityka prywatności Google Mobile"</a>"."</string>
+ <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Funkcja wprowadzania głosowego wykorzystuje mechanizm rozpoznawania mowy. Obowiązuje "<a href="http://m.google.com/privacy">"Polityka prywatności w usługach mobilnych"</a>"."</string>
<string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"Aby wyłączyć rozpoznawanie mowy, przejdź do ustawień sposobu wprowadzania tekstu."</string>
<string name="voice_hint_dialog_message" msgid="1420686286820661548">"Aby użyć wprowadzania głosowego, naciśnij przycisk mikrofonu."</string>
<string name="voice_listening" msgid="467518160751321844">"Mów teraz"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Włącz przesyłanie opinii użytkownika"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Pomóż ulepszyć edytor wprowadzania tekstu, automatycznie wysyłając do Google statystyki użycia i raporty o awariach."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Motyw klawiatury"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Niemiecka QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Angielska (Wielka Brytania)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Angielska (Stany Zjednoczone)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tryb badania przydatności"</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 0a30235f4..52a497f5f 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Teclado do Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Teclado Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Definições de teclado do Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opções de introdução"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Correção do Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Definições da verificação ortográfica"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Utilizar dados de prox."</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Util. algoritmo de prox. semelhante a teclado para verif. ortog."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Procurar nomes de contac."</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"O corretor ortográfico utiliza entradas da sua lista de contactos"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar ao primir as teclas"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Som ao premir as teclas"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Mostrar popup ao premir tecla"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Avançar"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Feito"</string>
<string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Cara sorridente"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Vírgula"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Ponto final"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Parêntese esquerdo"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Parêntese direito"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dois pontos"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Ponto e vírgula"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Ponto de exclamação"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Ponto de interrogação"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Aspas"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Plica"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Raiz quadrada"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marca comercial"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Ao cuidado de"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Marcar com estrela"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Cardinal"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Reticências"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Aspas duplas baixas"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A entrada de voz utiliza o reconhecimento de voz da Google. É aplicável a "<a href="http://m.google.com/privacy">"Política de privacidade do Google Mobile"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Activar comentários do utilizador"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Envie automaticamente estatísticas de utilização e relatórios de falhas para a Google e ajude-nos a melhorar este editor de método de introdução."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY Alemão"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglês (RU)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglês (EUA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo da capacidade de utilização"</string>
diff --git a/java/res/values-pt/donottranslate-more-keys.xml b/java/res/values-pt/donottranslate-more-keys.xml
index 31d9417ab..868fe7824 100644
--- a/java/res/values-pt/donottranslate-more-keys.xml
+++ b/java/res/values-pt/donottranslate-more-keys.xml
@@ -19,9 +19,9 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">á,ã,à,â,ä,å,æ,ª</string>
- <string name="more_keys_for_e">3,é,ê,è,ę,ė,ē,ë</string>
- <string name="more_keys_for_i">8,í,î,ì,ï,į,ī</string>
- <string name="more_keys_for_o">9,ó,õ,ô,ò,ö,œ,ø,ō,º</string>
- <string name="more_keys_for_u">7,ú,ü,ù,û,ū</string>
+ <string name="more_keys_for_e">é,ê,è,ę,ė,ē,ë</string>
+ <string name="more_keys_for_i">í,î,ì,ï,į,ī</string>
+ <string name="more_keys_for_o">ó,õ,ô,ò,ö,œ,ø,ō,º</string>
+ <string name="more_keys_for_u">ú,ü,ù,û,ū</string>
<string name="more_keys_for_c">ç,č,ć</string>
</resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index 36a70daa6..8d1218910 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Teclado Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Teclado Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Configurações de teclado Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opções de entrada"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Correção do Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Configurações de verificação ortográfica"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Usar dados de proximidade"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Usar algoritmo de prox. tipo teclado para verificação ortográfica"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Buscar nomes de contatos"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"O corretor ortográfico usa entradas de sua lista de contatos"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar ao tocar a tecla"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Som ao tocar a tecla"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Exibir pop-up ao digitar"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Avançar"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Feito"</string>
<string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Entrada de voz"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Carinha sorridente"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Voltar"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Vírgula"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Ponto final"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Parêntese esquerdo"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Parêntese direito"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dois pontos"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Ponto e vírgula"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Ponto de exclamação"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Ponto de interrogação"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Aspa dupla"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Aspa simples"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Ponto"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Raiz quadrada"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marca registrada"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Porcentagem"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Asterisco"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Sustenido"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Reticências"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Aspas duplas inferiores"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"A entrada de texto por voz usa o reconhecimento de voz do Google. "<a href="http://m.google.com/privacy">"A política de privacidade para celulares"</a>" é aplicada."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentário do usuário"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Ajude a melhorar este editor de método de entrada enviando automaticamente ao Google estatísticas de uso e relatórios de falhas."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY alemão"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglês (Reino Unido)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglês (EUA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo de utilização"</string>
diff --git a/java/res/values-rm/donottranslate-more-keys.xml b/java/res/values-rm/donottranslate-more-keys.xml
index ea9a55944..c40c29b13 100644
--- a/java/res/values-rm/donottranslate-more-keys.xml
+++ b/java/res/values-rm/donottranslate-more-keys.xml
@@ -18,5 +18,5 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_o">9,ò,ó,ö,ô,õ,œ,ø</string>
+ <string name="more_keys_for_o">ò,ó,ö,ô,õ,œ,ø</string>
</resources>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 090f3fc47..7138da469 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -21,6 +21,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Tastatura Android"</string>
+ <!-- no translation found for aosp_android_keyboard_ime_name (7877134937939182296) -->
+ <skip />
<string name="english_ime_settings" msgid="6661589557206947774">"Parameters da la tastatura Android"</string>
<!-- no translation found for english_ime_input_options (3909945612939668554) -->
<skip />
@@ -28,9 +30,9 @@
<skip />
<!-- no translation found for android_spell_checker_settings (5822324635435443689) -->
<skip />
- <!-- no translation found for use_proximity_option_title (7469233942295924620) -->
+ <!-- no translation found for use_contacts_for_spellchecking_option_title (5374120998125353898) -->
<skip />
- <!-- no translation found for use_proximity_option_summary (2857708859847261945) -->
+ <!-- no translation found for use_contacts_for_spellchecking_option_summary (8754413382543307713) -->
<skip />
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar cun smatgar in buttun"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Tun cun smatgar in buttun"</string>
@@ -76,8 +78,10 @@
<skip />
<!-- no translation found for prefs_settings_key (4623341240804046498) -->
<skip />
- <!-- outdated translation 7911639788808958255 --> <string name="auto_correction" msgid="4979925752001319458">"Propostas da pleds"</string>
- <!-- outdated translation 6881047311475758267 --> <string name="auto_correction_summary" msgid="5625751551134658006">"Curreger automaticamain il pled precedent"</string>
+ <!-- no translation found for auto_correction (4979925752001319458) -->
+ <skip />
+ <!-- no translation found for auto_correction_summary (5625751551134658006) -->
+ <skip />
<!-- no translation found for auto_correction_threshold_mode_off (8470882665417944026) -->
<skip />
<!-- no translation found for auto_correction_threshold_mode_modest (8788366690620799097) -->
@@ -86,7 +90,8 @@
<skip />
<!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) -->
<skip />
- <!-- outdated translation 1323347224043514969 --> <string name="bigram_suggestion" msgid="2636414079905220518">"Propostas da tip bigram"</string>
+ <!-- no translation found for bigram_suggestion (2636414079905220518) -->
+ <skip />
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Meglierar la proposta cun agid dal pled precedent"</string>
<!-- no translation found for bigram_prediction (8914273444762259739) -->
<skip />
@@ -95,6 +100,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Memorisà"</string>
<string name="label_go_key" msgid="1635148082137219148">"Dai"</string>
<string name="label_next_key" msgid="362972844525672568">"Vinavant"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Finì"</string>
<string name="label_send_key" msgid="2815056534433717444">"Trametter"</string>
<!-- no translation found for label_to_alpha_key (4793983863798817523) -->
@@ -141,51 +148,16 @@
<skip />
<!-- no translation found for spoken_description_return (8178083177238315647) -->
<skip />
- <!-- no translation found for spoken_description_comma (4970844442999724586) -->
- <skip />
- <!-- no translation found for spoken_description_period (5286614628077903945) -->
- <skip />
- <!-- no translation found for spoken_description_left_parenthesis (8524822120595052415) -->
- <skip />
- <!-- no translation found for spoken_description_right_parenthesis (1085757995851933164) -->
- <skip />
- <!-- no translation found for spoken_description_colon (4312420908484277077) -->
- <skip />
- <!-- no translation found for spoken_description_semicolon (37737920987155179) -->
- <skip />
- <!-- no translation found for spoken_description_exclamation_mark (2625684427460737157) -->
- <skip />
- <!-- no translation found for spoken_description_question_mark (7074097784255379666) -->
- <skip />
- <!-- no translation found for spoken_description_double_quote (5485320575389905967) -->
- <skip />
- <!-- no translation found for spoken_description_single_quote (4451320362665463938) -->
- <skip />
<!-- no translation found for spoken_description_dot (40711082435231673) -->
<skip />
- <!-- no translation found for spoken_description_square_root (190595160284757811) -->
- <skip />
- <!-- no translation found for spoken_description_pi (4554418247799952239) -->
- <skip />
- <!-- no translation found for spoken_description_delta (3607948313655721579) -->
- <skip />
- <!-- no translation found for spoken_description_trademark (475877774077871369) -->
- <skip />
- <!-- no translation found for spoken_description_care_of (7492800237237796530) -->
- <skip />
- <!-- no translation found for spoken_description_star (1009742725387231977) -->
- <skip />
- <!-- no translation found for spoken_description_pound (5530577649206922631) -->
+ <string name="voice_warning_title" msgid="4419354150908395008">"Cumonds vocals"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\""</string>
+ <!-- no translation found for voice_warning_may_not_understand (5596289095878251072) -->
<skip />
- <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <!-- no translation found for voice_warning_how_to_turn_off (3190378129944934856) -->
<skip />
- <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
+ <!-- no translation found for voice_hint_dialog_message (1420686286820661548) -->
<skip />
- <string name="voice_warning_title" msgid="4419354150908395008">"Cumonds vocals"</string>
- <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\""</string>
- <!-- outdated translation 4611518823070986445 --> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Ils cumonds vocals èn ina funcziunalitad experimentala che utilisescha la renconuschientscha vocala da rait da Google."</string>
- <!-- outdated translation 5652369578498701761 --> <string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"\"Per deactivar ils cumonds vocals, avri ils parameters da tastatura.\""</string>
- <!-- outdated translation 6892342981545727994 --> <string name="voice_hint_dialog_message" msgid="1420686286820661548">"\"Per utilisar ils cumonds vocals, smatgai il buttun dal microfon u stritgai cun il det sur la tastatura dal visur.\""</string>
<string name="voice_listening" msgid="467518160751321844">"Ussa discurrer"</string>
<string name="voice_working" msgid="6666937792815731889">"Operaziun en progress"</string>
<string name="voice_initializing" msgid="661962047129906646"></string>
@@ -201,7 +173,8 @@
<string name="voice_punctuation_hint" msgid="1611389463237317754">"\""<b>"Commentari:"</b>" Empruvai la proxima giada d\'agiuntar segns d\'interpuncziun sco \"\"punct\"\", \"\"comma\"\" u \"\"segn da dumonda\"\" cun cumonds vocals.\""</string>
<string name="cancel" msgid="6830980399865683324">"Interrumper"</string>
<string name="ok" msgid="7898366843681727667">"OK"</string>
- <!-- outdated translation 2466640768843347841 --> <string name="voice_input" msgid="3583258583521397548">"Cumonds vocals"</string>
+ <!-- no translation found for voice_input (3583258583521397548) -->
+ <skip />
<!-- no translation found for voice_input_modes_main_keyboard (3360660341121083174) -->
<skip />
<!-- no translation found for voice_input_modes_symbols_keyboard (7203213240786084067) -->
@@ -221,12 +194,12 @@
<string name="language_selection_title" msgid="1651299598555326750">"Linguas da cumonds vocals"</string>
<!-- no translation found for select_language (3693815588777926848) -->
<skip />
- <!-- outdated translation 8058519710062071085 --> <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tippar danovamain per memorisar"</string>
+ <!-- no translation found for hint_add_to_dictionary (9006292060636342317) -->
+ <skip />
<string name="has_dictionary" msgid="6071847973466625007">"Dicziunari disponibel"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Activar il feedback da l\'utilisader"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Gidai a meglierar quest editur da la metoda d\'endataziun cun trametter automaticamain datas statisticas davart l\'utilisaziun e rapports da collaps a Google."</string>
- <!-- outdated translation 437433231038683666 --> <string name="keyboard_layout" msgid="8451164783510487501">"Design da la tastatura"</string>
- <!-- no translation found for subtype_de_qwerty (3358900499589259491) -->
+ <!-- no translation found for keyboard_layout (8451164783510487501) -->
<skip />
<!-- no translation found for subtype_en_GB (88170601942311355) -->
<skip />
diff --git a/java/res/values-ro/donottranslate-more-keys.xml b/java/res/values-ro/donottranslate-more-keys.xml
index d7e6a171d..42fd91336 100644
--- a/java/res/values-ro/donottranslate-more-keys.xml
+++ b/java/res/values-ro/donottranslate-more-keys.xml
@@ -18,8 +18,8 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">ă,â,à,á,ä,æ,ã,å,ā</string>
- <string name="more_keys_for_i">8,î,ï,ì,í,į,ī</string>
+ <string name="more_keys_for_a">â,ã,ă,à,á,ä,æ,å,ā</string>
+ <string name="more_keys_for_i">î,ï,ì,í,į,ī</string>
<string name="more_keys_for_s">ș,ß,ś,š</string>
- <string name="more_keys_for_t">5,ț</string>
+ <string name="more_keys_for_t">ț</string>
</resources>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index c1dea5431..b967eacec 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Tastatură Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Tastatură Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Setările tastaturii Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Opţiuni de introducere text"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Corecţie Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Setări de verificare ortografică"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Utiliz. datele de proxim."</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Utilizaţi un algor. de prox. similar tastat. pt. verif. ortograf."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Verificare nume în agendă"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Verificatorul ortografic utilizează intrări din lista de contacte"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrare la apăsarea tastei"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Sunet la apăsarea tastei"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Fereastră pop-up la apăsarea tastei"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: salvat"</string>
<string name="label_go_key" msgid="1635148082137219148">"OK"</string>
<string name="label_next_key" msgid="362972844525672568">"Înainte"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Terminat"</string>
<string name="label_send_key" msgid="2815056534433717444">"Trimiteţi"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Intrare vocală"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Faţă zâmbitoare"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Virgulă"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punct"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Paranteză închisă"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Paranteză deschisă"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Două puncte"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Punct şi virgulă"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Semn de exclamaţie"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Semn de întrebare"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Ghilimele duble"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Ghilimele simple"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punct"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Rădăcină pătrată"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Marcă comercială"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"În atenţia"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Stea"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Diez"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Puncte de suspensie"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Ghilimele duble de deschidere"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Intrare voce"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Intrarea vocală nu este acceptată în prezent pentru limba dvs., însă funcţionează în limba engleză."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Intrarea vocală utilizează funcţia Google de recunoaştere vocală. Se aplică "<a href="http://m.google.com/privacy">"Politica de confidenţialitate Google Mobil"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Activaţi feedback de la utilizatori"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Ajutaţi la îmbunătăţirea acestui instrument de editare a metodelor de introducere a textului trimiţând în mod automat la Google statistici de utilizare şi rapoarte de blocare."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Temă pentru tastatură"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Tastatură germană QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engleză (Marea Britanie)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engleză (S.U.A.)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modul Studiu privind utilizarea"</string>
diff --git a/java/res/values-ru/donottranslate-more-keys.xml b/java/res/values-ru/donottranslate-more-keys.xml
index f7e006e84..b7e74660d 100644
--- a/java/res/values-ru/donottranslate-more-keys.xml
+++ b/java/res/values-ru/donottranslate-more-keys.xml
@@ -18,7 +18,5 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_cyrillic_e">5,ё</string>
- <string name="more_keys_for_cyrillic_soft_sign">ъ</string>
- <string name="more_keys_for_cyrillic_ha">ъ</string>
+ <string name="more_keys_for_slavic_ye">ё</string>
</resources>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 863c8a28c..13607fffa 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Клавиатура Android"</string>
- <string name="english_ime_settings" msgid="6661589557206947774">"Настройки клавиатуры Android"</string>
- <string name="english_ime_input_options" msgid="3909945612939668554">"Параметры ввода"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Клавиатура Android (AOSP)"</string>
+ <string name="english_ime_settings" msgid="6661589557206947774">"Клавиатура Android"</string>
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Настройки"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Исправления Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Настройка проверки правописания"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Алгоритм близости клавиш"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Использовать алгоритм близости клавиш для проверки правописания"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Поиск контактов"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Обращаться к списку контактов при проверке правописания"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Виброотклик клавиш"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук клавиш"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Увеличение нажатых"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: сохранено"</string>
<string name="label_go_key" msgid="1635148082137219148">"Поиск"</string>
<string name="label_next_key" msgid="362972844525672568">"Далее"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
<string name="label_send_key" msgid="2815056534433717444">"Отправить"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"АБВ"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Голосовой ввод"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Смайлик"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Клавиша \"Ввод\""</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Запятая"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Точка"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Открывающая скобка"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Закрывающая скобка"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Двоеточие"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Точка с запятой"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Восклицательный знак"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Вопросительный знак"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Двойная кавычка"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Одинарные кавычки"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Точка"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Квадратный корень"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Число \"пи\""</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Дельта"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Товарный знак"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Знак процента"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Пометить"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Английский фунт"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Многоточие"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Нижние двойные кавычки"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Голосовой ввод"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"В настоящее время функция голосового ввода не поддерживает ваш язык, но вы можете пользоваться ей на английском."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Голосовой ввод использует алгоритмы распознавания речи Google. Действует "<a href="http://m.google.com/privacy">"политика конфиденциальности для мобильных устройств"</a>"."</string>
@@ -144,9 +128,8 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Включить отправку сведений"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Помогите усовершенствовать редактор способа ввода, разрешив отправку статистики и отчетов о сбоях в Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема клавиатуры"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Немецкая клавиатура QWERTY"</string>
- <string name="subtype_en_GB" msgid="88170601942311355">"Английский (Великобритания)"</string>
- <string name="subtype_en_US" msgid="6160452336634534239">"Английский (США)"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"английский (Великобритания)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"английский (США)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим проверки удобства использования"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="1829950405285211668">"Настройки вибросигнала при нажатии клавиш"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="5875933757082305040">"Настройки громкости звука при нажатии клавиш"</string>
diff --git a/java/res/values-sk/donottranslate-more-keys.xml b/java/res/values-sk/donottranslate-more-keys.xml
index b73db0a46..574eedb1f 100644
--- a/java/res/values-sk/donottranslate-more-keys.xml
+++ b/java/res/values-sk/donottranslate-more-keys.xml
@@ -18,18 +18,20 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">ä,á,à,â,æ,ã,å,ā</string>
- <string name="more_keys_for_e">3,é,ě,è,ê,ë,ę,ė,ē</string>
- <string name="more_keys_for_i">8,í,î,ï,ì,į,ī</string>
- <string name="more_keys_for_o">9,ô,ó,ö,ò,õ,œ,ø,ō</string>
- <string name="more_keys_for_u">7,ú,ú,û,ü,ù,ū</string>
- <string name="more_keys_for_s">š,ß,ś</string>
- <string name="more_keys_for_n">ň,ñ,ń</string>
+ <string name="more_keys_for_a">á,ä,ā,à,â,ã,å,æ,ą</string>
+ <string name="more_keys_for_e">é,ě,ē,ė,è,ê,ë,ę</string>
+ <string name="more_keys_for_i">í,ī,į,ì,î,ï,ı</string>
+ <string name="more_keys_for_o">ô,ó,ö,ò,õ,œ,ő,ø</string>
+ <string name="more_keys_for_u">ú,ů,ü,ū,ų,ù,û,ű</string>
+ <string name="more_keys_for_s">š,ß,ś,ş</string>
+ <string name="more_keys_for_n">ň,ņ,ñ,ń,ń</string>
<string name="more_keys_for_c">č,ç,ć</string>
- <string name="more_keys_for_y">6,ý,ÿ</string>
+ <string name="more_keys_for_y">ý,ÿ</string>
<string name="more_keys_for_d">ď</string>
- <string name="more_keys_for_r">4,ŕ,ř</string>
- <string name="more_keys_for_t">5,ť</string>
- <string name="more_keys_for_z">ž,ź,ż</string>
- <string name="more_keys_for_l">ľ,ĺ,ł</string>
+ <string name="more_keys_for_r">ŕ,ř,ŗ</string>
+ <string name="more_keys_for_t">ť,ţ</string>
+ <string name="more_keys_for_z">ž,ż,ź</string>
+ <string name="more_keys_for_k">ķ</string>
+ <string name="more_keys_for_l">ľ,ĺ,ļ,ł</string>
+ <string name="more_keys_for_g">ģ,ğ</string>
</resources>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index b7ab8f204..c9a5f00b0 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Klávesnica Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Klávesnica Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Nastavenia klávesnice Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti zadávania textu a údajov"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Opravy pravopisu Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Nastavenia kontroly pravopisu"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Použiť údaje o blízkosti"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Na kontr. pravopis. použiť algor. vzdialenosti ako pri kláves."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Vyhľadať kontakty"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Kontrola pravopisu používa záznamy z vášho zoznamu kontaktov"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Pri stlačení klávesu vibrovať"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Zvuk pri stlačení klávesu"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Zobraziť znaky pri stlačení klávesu"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uložené"</string>
<string name="label_go_key" msgid="1635148082137219148">"Hľadať"</string>
<string name="label_next_key" msgid="362972844525672568">"Ďalej"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Hotovo"</string>
<string name="label_send_key" msgid="2815056534433717444">"Odoslať"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Hlasový vstup"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Usmiata tvár"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Čiarka"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Bodka"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Ľavá zátvorka"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Pravá zátvorka"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dvojbodka"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Bodkočiarka"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Výkričník"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Otáznik"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Úvodzovky"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Jednoduché úvodzovky"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Bodka"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Odmocnina"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pí"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Trademark"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Percento"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Hviezdička"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Libra"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Tri bodky"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Dolné úvodzovky"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pre váš jazyk aktuálne nie je hlasový vstup podporovaný, ale funguje v angličtine."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Hlasový vstup používa rozpoznávanie hlasu Google. Na používanie hlasového vstupu sa vzťahujú "<a href="http://m.google.com/privacy">"Pravidlá ochrany osobných údajov pre mobilné služby"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Povoliť spätnú väzbu od používateľov"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Automatickým zasielaním štatistík o využívaní editora metódy vstupu a správ o jeho zlyhaní do služby Google môžete prispieť k vylepšeniu tohto nástroja."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Motív klávesnice"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Nemecká klávesnica QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglická klávesnica (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglická klávesnica (US)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim štúdie použiteľnosti"</string>
diff --git a/java/res/values-fr-rCH/donottranslate-more-keys.xml b/java/res/values-sl/donottranslate-more-keys.xml
index 561c5e52f..b72c6799e 100644
--- a/java/res/values-fr-rCH/donottranslate-more-keys.xml
+++ b/java/res/values-sl/donottranslate-more-keys.xml
@@ -18,9 +18,8 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_a">à,â,æ,á,ä,ã,å,ā,ª</string>
- <string name="more_keys_for_y">ÿ</string>
- <string name="more_keys_for_q">1</string>
- <string name="more_keys_for_w">2</string>
- <string name="more_keys_for_z">6</string>
+ <string name="more_keys_for_s">š</string>
+ <string name="more_keys_for_c">č,ć</string>
+ <string name="more_keys_for_d">đ</string>
+ <string name="more_keys_for_z">ž</string>
</resources>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index d7f357aa0..c1e8a6ff4 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Tipkovnica Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Tipkovnica Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Nastavitve tipkovnice Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti vnosa"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Preverjanje črkovanja za Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Nastavitve preverjanja črkovanja"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Uporabi podatke bližine"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Uporaba algoritma za preverjanje črkovanja na podlagi bližine znakov na tipkovnici"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Iskanje imen stikov"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Črkovalnik uporablja vnose s seznama stikov"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibriranje ob pritisku tipke"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Zvok ob pritisku tipke"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Povečaj črko ob pritisku"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: shranjeno"</string>
<string name="label_go_key" msgid="1635148082137219148">"Pojdi"</string>
<string name="label_next_key" msgid="362972844525672568">"Naprej"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Dokončano"</string>
<string name="label_send_key" msgid="2815056534433717444">"Pošlji"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Glasovni vnos"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smeško"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Vračalka"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Vejica"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Pika"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Levi oklepaj"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Desni oklepaj"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dvopičje"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Podpičje"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Klicaj"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Vprašaj"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dvojni narekovaji"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Enojni narekovaj"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Pika"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Koren"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Blagovna znamka"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Odstotek"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Zvezdica"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Lojtra"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Tri pike"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Spodnji dvojni narekovaji"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Glasovni vnos"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Glasovni vnos trenutno ni podprt v vašem jeziku, deluje pa v angleščini."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Glasovni vnos uporablja Googlovo prepoznavanje govora. Zanj velja "<a href="http://m.google.com/privacy">"pravilnik o zasebnosti za mobilne naprave"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Omogoči povratne informacije uporabnikov"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"S samodejnim pošiljanjem statističnih podatkov o uporabi in poročil o zrušitvah Googlu nam lahko pomagate izboljšati urejevalnik načina vnosa."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Nemška QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angleščina (Združeno kraljestvo)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angleščina (ZDA)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način za preučevanje uporabnosti"</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 0906fce6e..20279a852 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android тастатура"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android тастатура (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Подешавања Android тастатуре"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Опције уноса"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android исправљање"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Подешавања провере правописа"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Употреба података близине"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Употреба алгоритма близине попут тастатуре за проверу правописа"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Потражи имена контаката"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Контролор правописа користи уносе са листе контаката"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Вибрирај на притисак тастера"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук на притисак тастера"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Искачући прозор приликом притиска тастера"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Сачувано"</string>
<string name="label_go_key" msgid="1635148082137219148">"Иди"</string>
<string name="label_next_key" msgid="362972844525672568">"Следеће"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
<string name="label_send_key" msgid="2815056534433717444">"Пошаљи"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Гласовни унос"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Смајли"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Зарез"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Тачка"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Лева заграда"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Десна заграда"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Две тачке"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Тачка-зарез"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Знак узвика"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Знак питања"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Дупли наводник"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Полунаводник"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Тачка"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Квадратни корен"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Пи"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Делта"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Жиг"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"За"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Звездица"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Фунта"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Три тачке"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Отворени доњи наводници"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Гласовни унос"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Гласовни унос тренутно није подржан за ваш језик, али функционише на енглеском."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Гласовни унос користи Google-ову функцију за препознавање гласа. Примењује се "<a href="http://m.google.com/privacy">"политика приватности за мобилне уређаје"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Омогући повратну информацију корисника"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Помозите да се побољша овај уређивач режима уноса тако што ће се аутоматски послати статистика о коришћењу и извештаји о грешкама компанији Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема тастатуре"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY тастатура за немачки"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"енглески (УК)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"енглески (САД)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за студију могућности коришћења"</string>
diff --git a/java/res/values-sv/donottranslate-more-keys.xml b/java/res/values-sv/donottranslate-more-keys.xml
index 1fa29a83e..6d9800e57 100644
--- a/java/res/values-sv/donottranslate-more-keys.xml
+++ b/java/res/values-sv/donottranslate-more-keys.xml
@@ -18,10 +18,11 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="more_keys_for_e">3,é,è,ê,ë,ę</string>
- <string name="more_keys_for_o">9,œ,ô,ò,ó,õ,ō</string>
- <string name="more_keys_for_u">7,ü,û,ù,ú,ū</string>
+ <string name="more_keys_for_e">é,è,ê,ë,ę</string>
+ <string name="more_keys_for_o">œ,ô,ò,ó,õ,ō</string>
+ <string name="more_keys_for_u">ü,û,ù,ú,ū</string>
<string name="more_keys_for_s">ß,ś,š</string>
+ <string name="keylabel_for_scandinavia_row1_11">å</string>
<string name="keylabel_for_scandinavia_row2_10">ö</string>
<string name="keylabel_for_scandinavia_row2_11">ä</string>
<string name="more_keys_for_scandinavia_row2_10">ø</string>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 46760bbe2..eb2007382 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Androids tangentbord"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Androids tangentbord (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Inställningar för Androids tangentbord"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Inmatningsalternativ"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android-korrigering"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Inställningar för stavningskontroll"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Använd närhetsinformation"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Använd tangentbordsliknande närhetsalgoritm för stavningskontroll"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Sök namn på kontakter"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"I stavningskontrollen används poster från kontaktlistan"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrera vid tangenttryck"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Knappljud"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup vid knapptryck"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string>
<string name="label_go_key" msgid="1635148082137219148">"Kör"</string>
<string name="label_next_key" msgid="362972844525672568">"Nästa"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Färdig"</string>
<string name="label_send_key" msgid="2815056534433717444">"Skicka"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Röstinmatning"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Uttryckssymbol"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Retur"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Komma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Punkt"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Vänster parentes"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Högerparentes"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Kolon"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikolon"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Utropstecken"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Frågetecken"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dubbla citattecken"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Enkla citattecken"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Kvadratrot"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Trademark"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Care of"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Stjärna"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Fyrkant"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellips"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Nedre dubbla citattecken"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Röstindata"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Röstindata stöds inte på ditt språk än, men tjänsten fungerar på engelska."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Röstinmatning använder sig av Googles tjänst för taligenkänning. "<a href="http://m.google.com/privacy">"Sekretesspolicyn för mobila enheter"</a>" gäller."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Aktivera synpunkter från användare"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Du kan hjälpa till att förbättra inmatningsmetoden genom att automatiskt skicka användningsstatistik och felrapporter till Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tangentbordstema"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Tyskt QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engelskt (brittiskt)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engelskt (amerikanskt)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Läge för studie av användbarhet"</string>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 822907b05..983754014 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Kibodi ya Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Kicharazio cha Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Mipangilio ya kibodi ya Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Chaguo za uingizaji"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Masahihisho ya Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Mipangilio ya kukagua sarufi"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Tumia data ya ukaribu"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Tumia kibodi kama ukaribu wa algorithmu kwa ukaguzi wa sarufi"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Angalia majina ya wasiliani"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Kikagua tahajia hutumia ingizo kutoka kwa orodha yako ya anwani"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Tetema unabofya kitufe"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Toa sauti unapobofya kitufe"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Ibuka kitufe kinapobonyezwa"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Imehifadhiwa"</string>
<string name="label_go_key" msgid="1635148082137219148">"Nenda"</string>
<string name="label_next_key" msgid="362972844525672568">"Ifuatayo"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Kwisha"</string>
<string name="label_send_key" msgid="2815056534433717444">"Tuma"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Uingizaji sauti"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Uso wenye tabasamu"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Rudi"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Koma"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Muda"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Mabano ya kushoto"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"mabano ya kulia"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Nukta mbili juu na chini"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Semikoloni"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Alama ya mshangao"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Alama ya kiulizio"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Nukuu mara mbili"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Nukuu moja"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Nukta"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Square root"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Chapa ya Biashara"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Kwa ulinzi wa"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Nyota"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Pauni"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Nukuu ya chini maradufu"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Uingizaji wa sauti"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Uingizaji wa sauti hauhimiliwi kwa lugha yako kwa sasa, lakini inafanya kazi kwa Kiingereza."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Uingizaji wa sauti hutumia utambuaji wa usemi wa Google. "<a href="http://m.google.com/privacy">"Sera ya Faragha ya Simu za mkononi "</a>" hutumika."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Wezesha maoni ya watumiaji"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Saidia kuimarisha mbinu ya uingizaji wa kihariri, kwa kutuma takwimu za matumizi na ripoti za kuvurugika kwa Google kiotomatiki."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Maandhari ya kibodi"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY ya Kijerumani"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Kiingereza cha (Uingereza)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Kiingereza cha (Marekani)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modi ya uchunguzi wa utumizi"</string>
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 1b8c8a64a..1c725a484 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -48,6 +48,7 @@
<fraction name="key_hint_letter_ratio">23%</fraction>
<fraction name="key_hint_label_ratio">34%</fraction>
<fraction name="key_uppercase_letter_ratio">29%</fraction>
+ <fraction name="spacebar_text_ratio">33.33%</fraction>
<dimen name="suggestions_strip_padding">40.0mm</dimen>
<integer name="max_more_suggestions_row">5</integer>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index 1854a8696..ecc5b7136 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -24,20 +24,22 @@
<bool name="config_enable_show_voice_key_option">false</bool>
<bool name="config_enable_show_popup_on_keypress_option">false</bool>
<bool name="config_enable_bigram_suggestions_option">false</bool>
- <bool name="config_sliding_key_input_enabled">false</bool>
- <bool name="config_digit_more_keys_enabled">false</bool>
<!-- Whether or not Popup on key press is enabled by default -->
<bool name="config_default_popup_preview">false</bool>
<bool name="config_default_sound_enabled">true</bool>
<bool name="config_auto_correction_spacebar_led_enabled">false</bool>
- <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false -->
- <bool name="config_show_mini_keyboard_at_touched_point">true</bool>
<!-- The language is never displayed if == 0, always displayed if < 0 -->
<integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer>
<!-- Long pressing space will invoke IME switcher if > 0, never invoke IME switcher if == 0 -->
<integer name="config_long_press_space_key_timeout">0</integer>
<!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
<string name="config_default_keyboard_theme_id" translatable="false">5</string>
- <string name="config_text_size_of_language_on_spacebar" translatable="false">medium</string>
<integer name="config_max_more_keys_column">5</integer>
+ <!--
+ Configuration for LatinKeyboardView
+ -->
+ <bool name="config_sliding_key_input_enabled">false</bool>
+ <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
+ false -->
+ <bool name="config_show_more_keys_keyboard_at_touched_point">true</bool>
</resources>
diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml
index 31830239d..e04609f2a 100644
--- a/java/res/values-sw600dp/dimens.xml
+++ b/java/res/values-sw600dp/dimens.xml
@@ -40,12 +40,12 @@
<fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
- <dimen name="mini_keyboard_key_horizontal_padding">6dip</dimen>
+ <dimen name="more_keys_keyboard_key_horizontal_padding">6dip</dimen>
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
<!-- popup_key_height x 1.2 -->
- <dimen name="mini_keyboard_slide_allowance">15.6mm</dimen>
+ <dimen name="more_keys_keyboard_slide_allowance">15.6mm</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction">-13.0mm</dimen>
<!-- left or right padding of label alignment -->
<dimen name="key_label_horizontal_padding">6dip</dimen>
@@ -59,6 +59,7 @@
<fraction name="key_hint_label_ratio">28%</fraction>
<fraction name="key_uppercase_letter_ratio">26%</fraction>
<fraction name="key_preview_text_ratio">50%</fraction>
+ <fraction name="spacebar_text_ratio">32.14%</fraction>
<dimen name="key_preview_height">15.0mm</dimen>
<dimen name="key_preview_offset">0.1in</dimen>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index 664e8c159..ef39f4393 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -52,6 +52,7 @@
<fraction name="key_hint_letter_ratio">23%</fraction>
<fraction name="key_hint_label_ratio">28%</fraction>
<fraction name="key_uppercase_letter_ratio">24%</fraction>
+ <fraction name="spacebar_text_ratio">24.00%</fraction>
<dimen name="key_preview_height">17.0mm</dimen>
<dimen name="key_preview_height_ics">26.5mm</dimen>
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index c25139a42..c1f9179ee 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -24,20 +24,22 @@
<bool name="config_enable_show_voice_key_option">false</bool>
<bool name="config_enable_show_popup_on_keypress_option">false</bool>
<bool name="config_enable_bigram_suggestions_option">false</bool>
- <bool name="config_sliding_key_input_enabled">false</bool>
- <bool name="config_digit_more_keys_enabled">false</bool>
<!-- Whether or not Popup on key press is enabled by default -->
<bool name="config_default_popup_preview">false</bool>
<bool name="config_default_sound_enabled">true</bool>
<bool name="config_auto_correction_spacebar_led_enabled">false</bool>
- <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false -->
- <bool name="config_show_mini_keyboard_at_touched_point">true</bool>
<!-- Long pressing space will invoke IME switcher if > 0, never invoke IME switcher if == 0 -->
<integer name="config_long_press_space_key_timeout">0</integer>
<!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
<string name="config_default_keyboard_theme_id" translatable="false">5</string>
- <string name="config_text_size_of_language_on_spacebar" translatable="false">medium</string>
<integer name="config_max_more_keys_column">5</integer>
+ <!--
+ Configuration for LatinKeyboardView
+ -->
+ <bool name="config_sliding_key_input_enabled">false</bool>
+ <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
+ false -->
+ <bool name="config_show_more_keys_keyboard_at_touched_point">true</bool>
<!-- Screen metrics for logging.
0 = "mdpi phone screen"
1 = "hdpi phone screen"
diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml
index bb4937dd5..f33a657af 100644
--- a/java/res/values-sw768dp/dimens.xml
+++ b/java/res/values-sw768dp/dimens.xml
@@ -43,12 +43,12 @@
<dimen name="popup_key_height">10.0mm</dimen>
- <dimen name="mini_keyboard_key_horizontal_padding">12dip</dimen>
+ <dimen name="more_keys_keyboard_key_horizontal_padding">12dip</dimen>
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
<!-- popup_key_height x 1.2 -->
- <dimen name="mini_keyboard_slide_allowance">15.6mm</dimen>
+ <dimen name="more_keys_keyboard_slide_allowance">15.6mm</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction">-13.0mm</dimen>
<!-- left or right padding of label alignment -->
<dimen name="key_label_horizontal_padding">6dip</dimen>
@@ -62,6 +62,7 @@
<fraction name="key_hint_label_ratio">28%</fraction>
<fraction name="key_uppercase_letter_ratio">26%</fraction>
<fraction name="key_preview_text_ratio">50%</fraction>
+ <fraction name="spacebar_text_ratio">29.03%</fraction>
<dimen name="key_preview_height">15.0mm</dimen>
<dimen name="key_preview_offset">0.1in</dimen>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index 53f56606c..700361a7b 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"แป้นพิมพ์ Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android keyboard (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"การตั้งค่าแป้นพิมพ์ Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"ตัวเลือกการป้อนข้อมูล"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"การแก้ไขของ Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"การตั้งค่าการตรวจสอบการสะกด"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"ใช้ข้อมูลที่ใกล้เคียง"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"ใช้อัลกอริทึมใกล้เคียงที่คล้ายกับแป้นพิมพ์สำหรับตรวจสอบการสะกด"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"ค้นหารายชื่อติดต่อ"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"เครื่องมือตรวจการสะกดใช้รายการจากรายชื่อติดต่อของคุณ"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"สั่นเมื่อกดปุ่ม"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"ส่งเสียงเมื่อกดปุ่ม"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"ป๊อปอัปเมื่อกดแป้น"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : บันทึกแล้ว"</string>
<string name="label_go_key" msgid="1635148082137219148">"ไป"</string>
<string name="label_next_key" msgid="362972844525672568">"ถัดไป"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"เสร็จสิ้น"</string>
<string name="label_send_key" msgid="2815056534433717444">"ส่ง"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"การป้อนข้อมูลด้วยเสียง"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"หน้ายิ้ม"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"เครื่องหมายจุลภาค"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"มหัพภาค"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"วงเล็บซ้าย"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"วงเล็บขวา"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"เครื่องหมายจุดคู่"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"อัฒภาค"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"อัศเจรีย์"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"เครื่องหมายคำถาม"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"อัญประกาศ"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"เครื่องหมายคำพูดเดี่ยว"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"เครื่องหมายจุด"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"รากที่สอง"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"เดลตา"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"เครื่องหมายการค้า"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Care of"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"ติดดาว"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"ปอนด์"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"จุดไข่ปลา"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"อัญประกาศล่าง"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"การป้อนข้อมูลด้วยเสียง"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ขณะนี้การป้อนข้อมูลด้วยเสียงยังไม่ได้รับการสนับสนุนในภาษาของคุณ แต่ใช้ได้ในภาษาอังกฤษ"</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"ป้อนข้อมูลด้วยเสียงใช้การจดจำคำพูดของ Google "<a href="http://m.google.com/privacy">" นโยบายส่วนบุคคลของมือถือ"</a>"มีผลบังคับใช้"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"เปิดใช้งานการแสดงความคิดเห็นจากผู้ใช้"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"ช่วยปรับปรุงตัวแก้ไขวิธีการป้อนข้อมูลนี้โดยการส่งสถิติการใช้งานและรายงานการขัดข้องถึง Google โดยอัตโนมัติ"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"ชุดรูปแบบแป้นพิมพ์"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"QWERTY ภาษาเยอรมัน"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"อังกฤษ (สหราชอาณาจักร)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"อังกฤษ (อเมริกัน)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"โหมดศึกษาประโยชน์ในการใช้งาน"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 701963f2a..812d200ef 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android keyboard"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android keyboard (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Mga setting ng Android keyboard"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Mga pagpipilian sa input"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Pagwawasto sa Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Mga setting ng pang-check ng pagbabaybay"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Gamitin ang proximity data"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Gumamit ng proximity algorithm na tulad ng keyboard para sa pag-check ng pagbabaybay"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Maghanap pangalan contact"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Gumagamit pang-check pagbabaybay entry sa iyong listahan contact"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Mag-vibrate sa keypress"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Tunog sa keypress"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup sa keypress"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Na-save"</string>
<string name="label_go_key" msgid="1635148082137219148">"Punta"</string>
<string name="label_next_key" msgid="362972844525672568">"Susunod"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Tapos na"</string>
<string name="label_send_key" msgid="2815056534433717444">"Ipadala"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Input ng boses"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Smiley na mukha"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Bumalik"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Kuwit"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Tuldok"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Kaliwang panaklong"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Kanang panaklong"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Tutuldok"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Tuldukuwit"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Tandang padamdam"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Tandang pananong"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Panipi"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Kudlit"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Tuldok"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Square root"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Trademark"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Care of"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Star"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Pound"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Mababang panipi"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Pag-input ng boses"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Hindi kasalukuyang suportado ang pag-input ng boses para sa iyong wika, ngunit gumagana sa Ingles."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Gumagamit ang pag-input ng boses ng speech recognition ng Google. Nalalapat "<a href="http://m.google.com/privacy">"Ang Patakaran sa Privacy ng Mobile"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Paganahin ang feedback ng user"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Tumulong na pahusayin ang editor ng paraan ng pag-input na ito sa pamamagitan ng awtomatikong pagpapadala ng mga istatistika ng paggamit at mga ulat ng crash sa Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema ng keyboard"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"German na QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Ingles (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Ingles (Estados Unidos)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Study mode ng pagiging kapaki-pakinabang"</string>
diff --git a/java/res/values-tr/donottranslate-more-keys.xml b/java/res/values-tr/donottranslate-more-keys.xml
index 6906b3580..227ebf98c 100644
--- a/java/res/values-tr/donottranslate-more-keys.xml
+++ b/java/res/values-tr/donottranslate-more-keys.xml
@@ -19,9 +19,9 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a">â</string>
- <string name="more_keys_for_i">8,ı,î,ï,ì,í,į,ī</string>
- <string name="more_keys_for_o">9,ö,ô,œ,ò,ó,õ,ø,ō</string>
- <string name="more_keys_for_u">7,ü,û,ù,ú,ū</string>
+ <string name="more_keys_for_i">ı,î,ï,ì,í,į,ī</string>
+ <string name="more_keys_for_o">ö,ô,œ,ò,ó,õ,ø,ō</string>
+ <string name="more_keys_for_u">ü,û,ù,ú,ū</string>
<string name="more_keys_for_s">ş,ß,ś,š</string>
<string name="more_keys_for_g">ğ</string>
<string name="more_keys_for_c">ç,ć,č</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 4ae7d78c9..d67def9e3 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android klavyesi"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android klavye (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android klavye ayarları"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Giriş seçenekleri"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android düzeltme"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Yazım denetimi ayarları"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Yakınlık verilri kullan"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Yazım denetimi içn klavye benzeri yakınlık algoritması kullan"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kişi adlarını denetle"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Yazım denetleyici, kişi listenizdeki girişleri kullanır"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Tuşa basıldığında titret"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Tuşa basıldığında ses çıkar"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Tuşa basıldığında pop-up aç"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string>
<string name="label_go_key" msgid="1635148082137219148">"Git"</string>
<string name="label_next_key" msgid="362972844525672568">"İleri"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Bitti"</string>
<string name="label_send_key" msgid="2815056534433717444">"Gönder"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Ses girişi"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Gülen yüz"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Virgül"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Nokta"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Sol parantez"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Sağ parantez"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"İki Nokta"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Noktalı virgül"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Ünlem işareti"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Soru işareti"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Çift tırnak"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Tek tırnak işareti"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Nokta"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Karekök"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Ticari marka"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Yüzde işareti"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Yıldız"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Kare"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Üç nokta"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Alt çift tırnak"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Ses girişi"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Ses girişi, şu anda sizin diliniz için desteklenmiyor ama İngilizce dilinde kullanılabilir."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Ses girişi Google\'ın konuşma tanıma işlevini kullanır. "<a href="http://m.google.com/privacy">" Mobil Gizlilik Politikası"</a>" geçerlidir."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Kullanıcı geri bildirimini etkinleştir"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Kullanım istatistiklerini ve kilitlenme raporlarını Google\'a otomatik olarak göndererek bu giriş yöntemi düzenleyicisinin iyileştirilmesine yardımcı olun."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klavye teması"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Almanca QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"İngilizce (BK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"İngilizce (ABD)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kullanılabilirlik çalışması modu"</string>
diff --git a/java/res/values-uk/donottranslate-more-keys.xml b/java/res/values-uk/donottranslate-more-keys.xml
new file mode 100644
index 000000000..4e7910128
--- /dev/null
+++ b/java/res/values-uk/donottranslate-more-keys.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keylabel_for_slavic_yery">і</string>
+ <string name="more_keys_for_slavic_yery">ї</string>
+</resources>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 234a9c56a..71ae6d152 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Клавіатура Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Клавіатура Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Налашт-ня клавіат. Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Парам. введення"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Виправлення Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Налаштування перевірки орфографії"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Використ. дані близькості"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Для перевірки орфогр. викор. алгоритм близьк., аналог. клавіат."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Шукати імена контактів"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Програма перевірки правопису використ. записи зі списку контактів"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Вібр при натиску клав."</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натиску клав."</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Сплив. при нат.клав."</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : збережено"</string>
<string name="label_go_key" msgid="1635148082137219148">"Іти"</string>
<string name="label_next_key" msgid="362972844525672568">"Далі"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Готово"</string>
<string name="label_send_key" msgid="2815056534433717444">"Надісл."</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"Алфавіт"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Голосовий ввід"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Смайлик"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Клавіша Return"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Кома"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Крапка"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Ліва дужка"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Права дужка"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Двокрапка"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Крапка з комою"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Знак оклику"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Знак питання"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Подвійні лапки"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Одинарні лапки"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Крапка"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Квадратний корінь"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Пі"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Дельта"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Торговельна марка"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Через"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Зірочка"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Решітка"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Три крапки"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Нижні подвійні лапки"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Голос. ввід"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Голос. ввід наразі не підтрим. для вашої мови, але можна користуватися англійською."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Голосовий ввід використовує розпізнавання мовлення Google. Застосовується "<a href="http://m.google.com/privacy">"Політика конфіденційності для мобільних пристроїв"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Увімк. відгуки корист."</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Допоможіть покращ. редактор методу введ., автомат. надсилаючи в Google статистику використ. та звіти про збої."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема клавіатури"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Німецька клавіатура QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Англійська (Великобританія)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Англійська (США)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим вивчення зручності у використанні"</string>
diff --git a/java/res/values-vi/donottranslate-more-keys.xml b/java/res/values-vi/donottranslate-more-keys.xml
new file mode 100644
index 000000000..9e2f6b8fd
--- /dev/null
+++ b/java/res/values-vi/donottranslate-more-keys.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="more_keys_for_a">à,á,ả,ã,ạ,ă,ằ,ắ,ẳ,ẵ,ặ,â,ầ,ấ,ẩ,ẫ,ậ</string>
+ <string name="more_keys_for_e">è,é,ẻ,ẽ,ẹ,ê,ề,ế,ể,ễ,ệ</string>
+ <string name="more_keys_for_i">ì,í,ỉ,ĩ,ị</string>
+ <string name="more_keys_for_o">ò,ó,ỏ,õ,ọ,ô,ồ,ố,ổ,ỗ,ộ,ơ,ờ,ớ,ở,ỡ,ợ</string>
+ <string name="more_keys_for_u">ù,ú,ủ,ũ,ụ,ư,ừ,ứ,ử,ữ,ự</string>
+ <string name="more_keys_for_y">ỳ,ý,ỷ,ỹ,ỵ</string>
+ <string name="more_keys_for_d">đ</string>
+</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index e602b495a..7d6a85400 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Bàn phím Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Bàn phím Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Cài đặt bàn phím Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Tùy chọn nhập"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Dịch vụ sửa chính tả của Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Cài đặt kiểm tra chính tả"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Sử dụng dữ liệu gần"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Dùng thuật toán gần, như của bàn phím để k.tra chính tả"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Tra cứu tên liên hệ"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Trình kiểm tra chính tả sử dụng các mục nhập từ danh sách liên hệ của bạn"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Rung khi nhấn phím"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Âm thanh khi nhấn phím"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Cửa sổ bật lên khi nhấn phím"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Đã lưu"</string>
<string name="label_go_key" msgid="1635148082137219148">"Tìm"</string>
<string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Xong"</string>
<string name="label_send_key" msgid="2815056534433717444">"Gửi"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Nhập dữ liệu bằng giọng nói"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Mặt cười"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Quay lại"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Dấu phẩy"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Dấu chấm"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"Dấu ngoặc trái"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"Dấu ngoặc phải"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Dấu hai chấm"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Dấu chấm phẩy"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Dấu hỏi chấm"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Dấu chấm hỏi"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Dấu ngoặc kép"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Dấu nháy đơn"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Dấu chấm"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Dấu khai căn"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Số Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Thương hiệu"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Dấu phần trăm"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Dấu sao"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Dấu thăng"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Dấu ba chấm"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Dấu nháy kép dưới"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Nhập liệu bằng giọng nói"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Nhập liệu bằng giọng nói hiện không được hỗ trợ cho ngôn ngữ của bạn nhưng hoạt động với ngôn ngữ tiếng Anh."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Nhập liệu bằng giọng nói sử dụng nhận dạng giọng nói của Google. Áp dụng "<a href="http://m.google.com/privacy">"Chính sách bảo mật dành cho điện thoại di động"</a>"."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Bật phản hồi của người dùng"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Giúp nâng cao trình chỉnh sửa phương thức nhập này bằng cách tự động gửi thống kê sử dụng và báo cáo sự cố cho Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Chủ đề bàn phím"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"Bàn phím QWERTY tiếng Đức"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Tiếng Anh (Anh)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Tiếng Anh (Mỹ)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Chế độ nghiên cứu tính khả dụng"</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index c3adf23c0..65729265f 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android 键盘"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android 键盘 (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android 键盘设置"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"输入选项"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android 更正"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"拼写检查设置"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"使用邻近度数据"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"使用类似键盘的邻近度算法进行拼写检查"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查找联系人姓名"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼写检查工具会使用您的联系人列表中的条目"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按键时振动"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"按键时播放音效"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"按键时显示弹出窗口"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已保存"</string>
<string name="label_go_key" msgid="1635148082137219148">"开始"</string>
<string name="label_next_key" msgid="362972844525672568">"下一步"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"完成"</string>
<string name="label_send_key" msgid="2815056534433717444">"发送"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"语音输入"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"笑脸"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"逗号"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"句号"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"左括号"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"右括号"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"冒号"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"分号"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"感叹号"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"问号"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"双引号"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"单引号"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"点"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"平方根"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"圆周率"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"商标符号"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"百分号"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"星号"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"井号"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"省略号"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"低双引号"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"语音输入"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"语音输入功能当前还不支持您的语言,您只能输入英语语音。"</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"语音输入采用了 Google 的语音识别技术,因此请遵守"<a href="http://m.google.com/privacy">"“Google 移动”隐私权政策"</a>"。"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"启用用户反馈"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"自动向 Google 发送使用情况统计信息和崩溃报告,帮助改进该输入法编辑器。"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"键盘主题"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"德语 QWERTY 键盘"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英语(英国)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英语(美国)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"可用性研究模式"</string>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 8d60fb7cd..5ac3a38c8 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Android 鍵盤"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Android 鍵盤 (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Android 鍵盤設定"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"輸入選項"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Android 拼字修正服務"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"拼字檢查設定"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"使用鄰近資料"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"運用類似鍵盤的鄰近演算法進行拼字檢查"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查詢聯絡人姓名"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼字檢查程式使用您的聯絡人清單項目"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"按鍵時顯示彈出式視窗"</string>
@@ -50,7 +51,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"一律顯示"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"以垂直模式顯示"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"永遠隱藏"</string>
- <string name="prefs_settings_key" msgid="4623341240804046498">"顯示設定金鑰"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"顯示設定鍵"</string>
<string name="auto_correction" msgid="4979925752001319458">"自動修正"</string>
<string name="auto_correction_summary" msgid="5625751551134658006">"按空白鍵或標點符號時,自動修正前面的錯字"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"關閉"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲存"</string>
<string name="label_go_key" msgid="1635148082137219148">"開始"</string>
<string name="label_next_key" msgid="362972844525672568">"繼續"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"完成"</string>
<string name="label_send_key" msgid="2815056534433717444">"傳送"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"語音輸入"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"笑臉"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"返回"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"逗號"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"句號"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"左括弧"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"右括弧"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"冒號"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"分號"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"驚嘆號"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"問號"</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"雙引號"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"單引號"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"點"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"平方根"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"圓周率"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"商標"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"百分比"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"星號"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"井字鍵"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"省略符號"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"下雙引號"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"語音輸入"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"語音輸入目前不支援您的語言,但是可以辨識英文。"</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"語音輸入使用 Google 的語音辨識功能,並遵循《"<a href="http://m.google.com/privacy">"行動服務隱私權政策"</a>"》。"</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"啟用使用者意見回饋"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"自動將使用統計資料和當機報告傳送給 Google,協助改善這個輸入法編輯器。"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"德文 QWERTY"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英文 (英式)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英文 (美式)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"使用性研究模式"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 072d17cba..012bf7fc9 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -21,12 +21,13 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Ikhibhodi ye-Android"</string>
+ <string name="aosp_android_keyboard_ime_name" msgid="7877134937939182296">"Ikhibhodi ye-Android (AOSP)"</string>
<string name="english_ime_settings" msgid="6661589557206947774">"Izilungiselelo zekhibhodi ye-Android"</string>
<string name="english_ime_input_options" msgid="3909945612939668554">"Okukhethwa kukho kokungenayo"</string>
<string name="spell_checker_service_name" msgid="2003013122022285508">"Ukulungisa kwe-Android"</string>
<string name="android_spell_checker_settings" msgid="5822324635435443689">"Izilungiselelo zokuhlola ukupela"</string>
- <string name="use_proximity_option_title" msgid="7469233942295924620">"Sebenzisa imininingo ye-proximity"</string>
- <string name="use_proximity_option_summary" msgid="2857708859847261945">"Sebenzisa i-proximity algorithm efana ne-keyboard ukuhlola ukupela"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Bheka amagama woxhumana nabo"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Isihloli sokupela sisebenzisa okungenayo kusuka kuhlu lalabo oxhumana nabo"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Dlidlizelisa ngokucindezela inkinobho"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Umsindo wokucindezela ukhiye"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Ugaxekile ngokucindezela ukhiye"</string>
@@ -64,6 +65,8 @@
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kulondoloziwe"</string>
<string name="label_go_key" msgid="1635148082137219148">"Iya"</string>
<string name="label_next_key" msgid="362972844525672568">"Okulandelayo"</string>
+ <!-- no translation found for label_previous_key (1211868118071386787) -->
+ <skip />
<string name="label_done_key" msgid="2441578748772529288">"Kwenziwe"</string>
<string name="label_send_key" msgid="2815056534433717444">"Thumela"</string>
<string name="label_to_alpha_key" msgid="4793983863798817523">"ABC"</string>
@@ -88,26 +91,7 @@
<string name="spoken_description_mic" msgid="615536748882611950">"Okungenayo kwezwi"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Ubuso-obumomothekayo"</string>
<string name="spoken_description_return" msgid="8178083177238315647">"Buyisela"</string>
- <string name="spoken_description_comma" msgid="4970844442999724586">"Ikhefu"</string>
- <string name="spoken_description_period" msgid="5286614628077903945">"Isikhathi"</string>
- <string name="spoken_description_left_parenthesis" msgid="8524822120595052415">"ama-parenthesis esobunxele"</string>
- <string name="spoken_description_right_parenthesis" msgid="1085757995851933164">"I-parenthesis yesokudla"</string>
- <string name="spoken_description_colon" msgid="4312420908484277077">"Ikholoni"</string>
- <string name="spoken_description_semicolon" msgid="37737920987155179">"Ikhefanangqi"</string>
- <string name="spoken_description_exclamation_mark" msgid="2625684427460737157">"Uphawu lokumemeza"</string>
- <string name="spoken_description_question_mark" msgid="7074097784255379666">"Imaki yombuzo."</string>
- <string name="spoken_description_double_quote" msgid="5485320575389905967">"Ukusho kabili"</string>
- <string name="spoken_description_single_quote" msgid="4451320362665463938">"Isibizo esisodwa"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Icashazi"</string>
- <string name="spoken_description_square_root" msgid="190595160284757811">"Impande yesikwele"</string>
- <string name="spoken_description_pi" msgid="4554418247799952239">"Pi"</string>
- <string name="spoken_description_delta" msgid="3607948313655721579">"i-Delta"</string>
- <string name="spoken_description_trademark" msgid="475877774077871369">"Uphawu lomkhiqizo"</string>
- <string name="spoken_description_care_of" msgid="7492800237237796530">"Ukunakekela ko"</string>
- <string name="spoken_description_star" msgid="1009742725387231977">"Inkanyezi"</string>
- <string name="spoken_description_pound" msgid="5530577649206922631">"Iphawundi"</string>
- <string name="spoken_description_ellipsis" msgid="1687670869947652062">"Ellipsis"</string>
- <string name="spoken_description_low_double_quote" msgid="3551394572784840975">"Isilinganiso esikabili esiphansi"</string>
<string name="voice_warning_title" msgid="4419354150908395008">"Okufakwa ngezwi"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Okufakwa ngezwi akusekelwa olimini lwakho, kodwa kuyasebenza nge-English."</string>
<string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Okufakwayo ngezwi kusebenzisa ukufanisa izwi kwe-Google. "<a href="http://m.google.com/privacy">"Inqubomgomo Yobumfihlo Yefoni"</a>" iyasebenza."</string>
@@ -144,7 +128,6 @@
<string name="prefs_enable_log" msgid="6620424505072963557">"Vumela impendulo yomsebenzisi"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Siza ukuthuthukisa lo mhleli wendlela yokufakwa ngokusithumela ngokuzenzakalela izibalo zokusetshenziswa nokukhubeka ku-Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Indikimba yekhibhodi"</string>
- <string name="subtype_de_qwerty" msgid="3358900499589259491">"i-QWERTY yesi-German"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"i-English(UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"i-English (US)"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Imodi yesitadi yokusebenziseka"</string>
diff --git a/java/res/values/additional-proximitychars.xml b/java/res/values/additional-proximitychars.xml
new file mode 100644
index 000000000..03d10d5d8
--- /dev/null
+++ b/java/res/values/additional-proximitychars.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="additional_proximitychars">
+ </string-array>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 0c9ca4f4a..2dea8fbb4 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -18,15 +18,18 @@
<declare-styleable name="KeyboardTheme">
<!-- Keyboard style -->
<attr name="keyboardStyle" format="reference" />
+ <!-- TODO: Get rid of latinKeyboardStyle -->
<!-- LatinKeyboard style -->
<attr name="latinKeyboardStyle" format="reference" />
<!-- KeyboardView style -->
<attr name="keyboardViewStyle" format="reference" />
- <!-- MiniKeyboard style -->
- <attr name="miniKeyboardStyle" format="reference" />
- <!-- MiniKeyboardView style -->
- <attr name="miniKeyboardViewStyle" format="reference" />
- <attr name="miniKeyboardPanelStyle" format="reference" />
+ <!-- LatinKeyboardView style -->
+ <attr name="latinKeyboardViewStyle" format="reference" />
+ <!-- MoreKeysKeyboard style -->
+ <attr name="moreKeysKeyboardStyle" format="reference" />
+ <!-- MoreKeysKeyboardView style -->
+ <attr name="moreKeysKeyboardViewStyle" format="reference" />
+ <attr name="moreKeysKeyboardPanelStyle" format="reference" />
<!-- Suggestions strip style -->
<attr name="suggestionsStripBackgroundStyle" format="reference" />
<attr name="suggestionsViewStyle" format="reference" />
@@ -57,16 +60,16 @@
<attr name="keyHintLetterRatio" format="float" />
<!-- Size of the text for hint label, in the proportion of key height. -->
<attr name="keyHintLabelRatio" format="float" />
- <!-- Size of the text for upper case letter, in the proportion of key height. -->
- <attr name="keyUppercaseLetterRatio" format="float" />
+ <!-- Size of the text for shifted letter hint, in the proportion of key height. -->
+ <attr name="keyShiftedLetterHintRatio" format="float" />
<!-- Horizontal padding of left/right aligned key label to the edge of the key. -->
<attr name="keyLabelHorizontalPadding" format="dimension" />
<!-- Top and right padding of hint letter to the edge of the key.-->
<attr name="keyHintLetterPadding" format="dimension" />
<!-- Bottom padding of popup hint letter "..." to the edge of the key.-->
<attr name="keyPopupHintLetterPadding" format="dimension" />
- <!-- Top and right padding of upper case letter to the edge of the key.-->
- <attr name="keyUppercaseLetterPadding" format="dimension" />
+ <!-- Top and right padding of shifted letter hint to the edge of the key.-->
+ <attr name="keyShiftedLetterHintPadding" format="dimension" />
<!-- Color to use for the label in a key. -->
<attr name="keyTextColor" format="color" />
@@ -76,9 +79,9 @@
<attr name="keyHintLetterColor" format="color" />
<!-- Key hint label color -->
<attr name="keyHintLabelColor" format="color" />
- <!-- Upper case letter colors -->
- <attr name="keyUppercaseLetterInactivatedColor" format="color" />
- <attr name="keyUppercaseLetterActivatedColor" format="color" />
+ <!-- Shifted letter hint colors -->
+ <attr name="keyShiftedLetterHintInactivatedColor" format="color" />
+ <attr name="keyShiftedLetterHintActivatedColor" format="color" />
<!-- Layout resource for key press feedback.-->
<attr name="keyPreviewLayout" format="reference" />
@@ -100,6 +103,8 @@
<attr name="keyPreviewHeight" format="dimension" />
<!-- Size of the text for key press feedback popup, int the proportion of key height -->
<attr name="keyPreviewTextRatio" format="float" />
+ <!-- Delay after key releasing and key press feedback dismissing in millisecond -->
+ <attr name="keyPreviewLingerTimeout" format="integer" />
<!-- Amount to offset the touch Y coordinate by, for bias correction. -->
<attr name="verticalCorrection" format="dimension" />
@@ -120,6 +125,37 @@
</attr>
</declare-styleable>
+ <declare-styleable name="LatinKeyboardView">
+ <attr name="autoCorrectionSpacebarLedEnabled" format="boolean" />
+ <attr name="autoCorrectionSpacebarLedIcon" format="reference" />
+ <!-- Size of the text for spacebar language label, in the proportion of key height. -->
+ <attr name="spacebarTextRatio" format="fraction" />
+ <attr name="spacebarTextColor" format="color" />
+ <attr name="spacebarTextShadowColor" format="color" />
+ <!-- Key detection hysteresis distance. -->
+ <attr name="keyHysteresisDistance" format="dimension" />
+ <!-- Touch noise threshold time in millisecond -->
+ <attr name="touchNoiseThresholdTime" format="integer" />
+ <!-- Touch noise threshold distance in millimeter -->
+ <attr name="touchNoiseThresholdDistance" format="dimension" />
+ <!-- Sliding key input enable -->
+ <attr name="slidingKeyInputEnable" format="boolean" />
+ <!-- Key repeat start timeout -->
+ <attr name="keyRepeatStartTimeout" format="integer" />
+ <!-- Key repeat interval in millisecond. -->
+ <attr name="keyRepeatInterval" format="integer" />
+ <!-- Long press timeout of letter key in millisecond. -->
+ <attr name="longPressKeyTimeout" format="integer" />
+ <!-- Long press timeout of shift key in millisecond. -->
+ <attr name="longPressShiftKeyTimeout" format="integer" />
+ <!-- Long press timeout of space key in millisecond. -->
+ <attr name="longPressSpaceKeyTimeout" format="integer" />
+ <!-- Ignore special key timeout while typing in millisecond. -->
+ <attr name="ignoreSpecialKeyTimeout" format="integer" />
+ <!-- More keys keyboard will shown at touched point. -->
+ <attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" />
+ </declare-styleable>
+
<declare-styleable name="SuggestionsView">
<attr name="suggestionStripOption" format="integer">
<!-- This should be aligned with SuggestionsViewParams.AUTO_CORRECT_* and etc. -->
@@ -127,9 +163,11 @@
<flag name="autoCorrectUnderline" value="0x02" />
<flag name="validTypedWordBold" value="0x04" />
</attr>
+ <attr name="colorValidTypedWord" format="color" />
<attr name="colorTypedWord" format="color" />
<attr name="colorAutoCorrect" format="color" />
<attr name="colorSuggested" format="color" />
+ <attr name="alphaValidTypedWord" format="integer" />
<attr name="alphaTypedWord" format="integer" />
<attr name="alphaAutoCorrect" format="integer" />
<attr name="alphaSuggested" format="integer" />
@@ -164,10 +202,6 @@
<attr name="verticalGap" format="dimension|fraction" />
<!-- More keys keyboard layout template -->
<attr name="moreKeysTemplate" format="reference" />
- <!-- Locale of the keyboard layout -->
- <attr name="keyboardLocale" format="string" />
- <!-- True if the keyboard is Right-To-Left -->
- <attr name="isRtlKeyboard" format="boolean" />
<!-- Icon set for key top and key preview. -->
<attr name="iconShiftKey" format="reference" />
<attr name="iconDeleteKey" format="reference" />
@@ -178,15 +212,25 @@
<attr name="iconTabKey" format="reference" />
<attr name="iconShortcutKey" format="reference" />
<attr name="iconShortcutForLabel" format="reference" />
- <attr name="iconShiftedShiftKey" format="reference" />
+ <attr name="iconSpaceKeyForNumberLayout" format="reference" />
+ <attr name="iconShiftKeyShifted" format="reference" />
+ <attr name="iconDisabledShortcutKey" format="reference" />
<attr name="iconPreviewTabKey" format="reference" />
</declare-styleable>
<declare-styleable name="Keyboard_Key">
<!-- The unicode value that this key outputs. -->
<attr name="code" format="integer" />
+ <!-- The alternate unicode value that this key outputs while typing. -->
+ <attr name="altCode" format="integer" />
<!-- The keys to display in the more keys keyboard. -->
<attr name="moreKeys" format="string" />
+ <!-- The keys to display in the more keys keyboard in addition to moreKeys.
+ The additional more keys are inserted at the '%' markers in the moreKeys if any.
+ They are inserted at the head of moreKeys if none.
+ If there are remaining entries of additionalMoreKeys even after all '%' markers have
+ been replaced, those remaining entries are appended at the end of moreKeys. -->
+ <attr name="additionalMoreKeys" format="string" />
<!-- Maximum column of more keys keyboard -->
<attr name="maxMoreKeysColumn" format="integer" />
<attr name="backgroundType" format="enum">
@@ -194,19 +238,26 @@
<enum name="normal" value="0" />
<enum name="functional" value="1" />
<enum name="action" value="2" />
- <enum name="sticky" value="3" />
+ <enum name="stickyOff" value="3" />
+ <enum name="stickyOn" value="4" />
+ </attr>
+ <!-- The key action flags. -->
+ <attr name="keyActionFlags" format="integer">
+ <!-- This should be aligned with Key.ACTION_FLAGS_* -->
+ <flag name="isRepeatable" value="0x01" />
+ <flag name="noKeyPreview" value="0x02" />
+ <flag name="altCodeWhileTyping" value="0x04" />
+ <flag name="enableLongPress" value="0x08" />
</attr>
- <!-- Whether long-pressing on this key will make it repeat. -->
- <attr name="isRepeatable" format="boolean" />
<!-- The string of characters to output when this key is pressed. -->
<attr name="keyOutputText" format="string" />
<!-- The label to display on the key. -->
<attr name="keyLabel" format="string" />
<!-- The hint label to display on the key in conjunction with the label. -->
<attr name="keyHintLabel" format="string" />
- <!-- The key label option. -->
- <attr name="keyLabelOption" format="integer">
- <!-- This should be aligned with Key.LABEL_OPTION_* -->
+ <!-- The key label flags. -->
+ <attr name="keyLabelFlags" format="integer">
+ <!-- This should be aligned with Key.LABEL_FLAGS__* -->
<flag name="alignLeft" value="0x01" />
<flag name="alignRight" value="0x02" />
<flag name="alignLeftOfCenter" value="0x08" />
@@ -216,15 +267,24 @@
<flag name="followKeyLetterRatio" value="0x80" />
<flag name="followKeyHintLabelRatio" value="0x100" />
<flag name="hasPopupHint" value="0x200" />
- <flag name="hasUppercaseLetter" value="0x400" />
+ <flag name="hasShiftedLetterHint" value="0x400" />
<flag name="hasHintLabel" value="0x800" />
<flag name="withIconLeft" value="0x1000" />
<flag name="withIconRight" value="0x2000" />
<flag name="autoXScale" value="0x4000" />
+ <!-- If true, character case of code, altCode, moreKeys, keyOutputText, keyLabel,
+ or keyHintLabel will never be subject to change. -->
+ <flag name="preserveCase" value="0x8000" />
+ <!-- If true, use keyShiftedLetterHintActivatedColor for the shifted letter hint and
+ keyTextInactivatedColor for the primary key top label. -->
+ <flag name="shiftedLetterActivated" value="0x10000" />
+ <!-- If true, use EditorInfo.actionLabel for the key label. -->
+ <flag name="fromCustomActionLabel" value="0x20000" />
</attr>
<!-- The icon to display on the key instead of the label. -->
<attr name="keyIcon" format="enum">
- <!-- This should be aligned with KeyboardIcons.ICON_* -->
+ <!-- This should be aligned with the KeyboardIconsSet.ICON_* -->
+ <enum name="iconUndefined" value="0" />
<enum name="iconShiftKey" value="1" />
<enum name="iconDeleteKey" value="2" />
<enum name="iconSettingsKey" value="3" />
@@ -234,21 +294,21 @@
<enum name="iconTabKey" value="7" />
<enum name="iconShortcutKey" value="8" />
<enum name="iconShortcutForLabel" value="9" />
+ <enum name="iconSpaceKeyForNumberLayout" value="10" />
+ <enum name="iconShiftKeyShifted" value="11" />
</attr>
- <!-- Shift key icon for shifted state -->
- <attr name="keyIconShifted" format="enum">
- <!-- This should be aligned with KeyboardIcons.ICON_SHIFTED_* -->
- <enum name="iconShiftedShiftKey" value="10" />
+ <!-- The icon for disabled key -->
+ <attr name="keyIconDisabled" format="enum">
+ <!-- This should be aligned with the KeyboardIconsSet.ICON_* -->
+ <enum name="iconDisabledShortcutKey" value="12" />
</attr>
<!-- The icon to show in the popup preview. -->
<attr name="keyIconPreview" format="enum">
- <!-- This should be aligned with KeyboardIcons.ICON_PREVIEW_* -->
- <enum name="iconPreviewTabKey" value="11" />
+ <!-- This should be aligned with the KeyboardIconsSet.ICON_* -->
+ <enum name="iconPreviewTabKey" value="13" />
</attr>
<!-- The key style to specify a set of key attributes defined by <key_style/> -->
<attr name="keyStyle" format="string" />
- <!-- The key is enabled and responds on press. -->
- <attr name="enabled" format="boolean" />
<!-- Visual insets -->
<attr name="visualInsetsLeft" format="dimension|fraction" />
<attr name="visualInsetsRight" format="dimension|fraction" />
@@ -273,6 +333,19 @@
</declare-styleable>
<declare-styleable name="Keyboard_Case">
+ <!-- This should be aligned with KeyboardSet_Element's elementName. -->
+ <attr name="keyboardSetElement" format="enum|string">
+ <enum name="alphabet" value="0" />
+ <enum name="alphabetManualShifted" value="1" />
+ <enum name="alphabetAutomaticShifted" value="2" />
+ <enum name="alphabetShiftLocked" value="3" />
+ <enum name="alphabetShiftLockShifted" value="4" />
+ <enum name="symbols" value="5" />
+ <enum name="symbolsShifted" value="6" />
+ <enum name="phone" value="7" />
+ <enum name="phoneSymbols" value="8" />
+ <enum name="number" value="9" />
+ </attr>
<!-- This should be aligned with KeyboardId.MODE_* -->
<attr name="mode" format="enum|string">
<enum name="text" value="0" />
@@ -295,6 +368,7 @@
<attr name="clobberSettingsKey" format="boolean" />
<attr name="shortcutKeyEnabled" format="boolean" />
<attr name="hasShortcutKey" format="boolean" />
+ <attr name="isMultiLine" format="boolean" />
<attr name="imeAction" format="enum">
<!-- This should be aligned with EditorInfo.IME_ACTION_* -->
<enum name="actionUnspecified" value="0" />
@@ -305,6 +379,8 @@
<enum name="actionNext" value="5" />
<enum name="actionDone" value="6" />
<enum name="actionPrevious" value="7" />
+ <!-- This should be aligned with KeyboardId.IME_ACTION_* -->
+ <enum name="actionCustomLabel" value="0x100" />
</attr>
<attr name="localeCode" format="string" />
<attr name="languageCode" format="string" />
@@ -316,11 +392,25 @@
<attr name="parentStyle" format="string" />
</declare-styleable>
- <declare-styleable name="LatinKeyboard">
- <attr name="autoCorrectionSpacebarLedEnabled" format="boolean" />
- <attr name="autoCorrectionSpacebarLedIcon" format="reference" />
- <attr name="disabledShortcutIcon" format="reference" />
- <attr name="spacebarTextColor" format="color" />
- <attr name="spacebarTextShadowColor" format="color" />
+ <declare-styleable name="KeyboardSet">
+ <!-- Locale of the keyboard layouts -->
+ <attr name="keyboardLocale" format="string" />
+ </declare-styleable>
+
+ <declare-styleable name="KeyboardSet_Element">
+ <!-- This should be aligned with KeyboardId.ELEMENT_* -->
+ <attr name="elementName" format="enum">
+ <enum name="alphabet" value="0" />
+ <enum name="alphabetManualShifted" value="1" />
+ <enum name="alphabetAutomaticShifted" value="2" />
+ <enum name="alphabetShiftLocked" value="3" />
+ <enum name="alphabetShiftLockShifted" value="4" />
+ <enum name="symbols" value="5" />
+ <enum name="symbolsShifted" value="6" />
+ <enum name="phone" value="7" />
+ <enum name="phoneSymbols" value="8" />
+ <enum name="number" value="9" />
+ </attr>
+ <attr name="elementKeyboard" format="reference"/>
</declare-styleable>
</resources>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 3f676ab25..cb13ba30b 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -25,9 +25,8 @@
<bool name="config_enable_show_voice_key_option">true</bool>
<bool name="config_enable_show_popup_on_keypress_option">true</bool>
<bool name="config_enable_bigram_suggestions_option">true</bool>
- <bool name="config_enable_usability_study_mode_option">false</bool>
- <bool name="config_sliding_key_input_enabled">true</bool>
- <bool name="config_digit_more_keys_enabled">true</bool>
+ <!-- TODO: Disable the following configuration for production. -->
+ <bool name="config_enable_usability_study_mode_option">true</bool>
<!-- Whether or not Popup on key press is enabled by default -->
<bool name="config_default_popup_preview">true</bool>
<!-- Default value for bigram suggestion: while showing suggestions for a word should we weigh
@@ -38,9 +37,6 @@
<bool name="config_default_bigram_prediction">false</bool>
<bool name="config_default_sound_enabled">false</bool>
<bool name="config_default_vibration_enabled">true</bool>
- <bool name="config_auto_correction_spacebar_led_enabled">false</bool>
- <!-- Showing mini keyboard, just above the touched point if true, aligned to the key if false -->
- <bool name="config_show_mini_keyboard_at_touched_point">false</bool>
<!-- The language is never displayed if == 0, always displayed if < 0 -->
<integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer>
<integer name="config_delay_update_suggestions">100</integer>
@@ -48,27 +44,40 @@
<integer name="config_delay_update_shift_state">100</integer>
<integer name="config_duration_of_fadeout_language_on_spacebar">50</integer>
<integer name="config_final_fadeout_percentage_of_language_on_spacebar">50</integer>
- <integer name="config_delay_before_preview">0</integer>
- <integer name="config_delay_after_preview">70</integer>
- <integer name="config_mini_keyboard_fadein_anim_time">0</integer>
- <integer name="config_mini_keyboard_fadeout_anim_time">100</integer>
- <integer name="config_delay_before_key_repeat_start">400</integer>
- <integer name="config_key_repeat_interval">50</integer>
+ <integer name="config_more_keys_keyboard_fadein_anim_time">0</integer>
+ <integer name="config_more_keys_keyboard_fadeout_anim_time">100</integer>
<integer name="config_keyboard_grid_width">32</integer>
<integer name="config_keyboard_grid_height">16</integer>
+ <integer name="config_double_spaces_turn_into_period_timeout">1100</integer>
+ <!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
+ <string name="config_default_keyboard_theme_id" translatable="false">5</string>
+ <integer name="config_max_more_keys_column">5</integer>
+ <!--
+ Configuration for KeyboardView
+ -->
+ <integer name="config_key_preview_linger_timeout">70</integer>
+ <!--
+ Configuration for LatinKeyboardView
+ -->
+ <dimen name="config_key_hysteresis_distance">0.05in</dimen>
+ <integer name="config_touch_noise_threshold_time">40</integer>
+ <dimen name="config_touch_noise_threshold_distance">2.0mm</dimen>
+ <bool name="config_sliding_key_input_enabled">true</bool>
+ <integer name="config_key_repeat_start_timeout">400</integer>
+ <integer name="config_key_repeat_interval">50</integer>
<integer name="config_long_press_key_timeout">400</integer>
<!-- Long pressing shift will invoke caps-lock if > 0, never invoke caps-lock if == 0 -->
<integer name="config_long_press_shift_key_timeout">1200</integer>
<!-- Long pressing space will invoke IME switcher if > 0, never invoke IME switcher if == 0 -->
- <integer name="config_long_press_space_key_timeout">@integer/config_long_press_key_timeout</integer>
- <integer name="config_touch_noise_threshold_millis">40</integer>
- <integer name="config_double_spaces_turn_into_period_timeout">1100</integer>
+ <integer name="config_long_press_space_key_timeout">
+ @integer/config_long_press_key_timeout</integer>
<integer name="config_ignore_special_key_timeout">700</integer>
- <dimen name="config_touch_noise_threshold_distance">2.0mm</dimen>
- <!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
- <string name="config_default_keyboard_theme_id" translatable="false">5</string>
- <string name="config_text_size_of_language_on_spacebar" translatable="false">small</string>
- <integer name="config_max_more_keys_column">5</integer>
+ <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if
+ false -->
+ <bool name="config_show_more_keys_keyboard_at_touched_point">false</bool>
+ <!--
+ Configuration for auto correction
+ -->
<string-array name="auto_correction_threshold_values" translatable="false">
<!-- Off, When auto correction setting is Off, this value is not used. -->
<item></item>
@@ -81,9 +90,11 @@
will be subject to auto-correction. -->
<item>0</item>
</string-array>
- <!-- Threshold of the normalized score of the best suggestion for the spell checker to declare a word to be "likely" -->
- <string name="spellchecker_likely_threshold_value" translatable="false">0.11</string>
- <!-- Threshold of the normalized score of any dictionary lookup to be offered as a suggestion by the spell checker -->
+ <!-- Threshold of the normalized score of the best suggestion for the spell checker to declare
+ a word to be "recommended" -->
+ <string name="spellchecker_recommended_threshold_value" translatable="false">0.11</string>
+ <!-- Threshold of the normalized score of any dictionary lookup to be offered as a suggestion
+ by the spell checker -->
<string name="spellchecker_suggestion_threshold_value" translatable="false">0.03</string>
<!-- Screen metrics for logging.
0 = "mdpi phone screen"
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 352141ca6..41a297902 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -26,8 +26,8 @@
<dimen name="popup_key_height">0.330in</dimen>
- <dimen name="mini_keyboard_horizontal_edges_padding">16dip</dimen>
- <dimen name="mini_keyboard_key_horizontal_padding">8dip</dimen>
+ <dimen name="more_keys_keyboard_horizontal_edges_padding">16dip</dimen>
+ <dimen name="more_keys_keyboard_key_horizontal_padding">8dip</dimen>
<fraction name="keyboard_top_padding">1.556%p</fraction>
<fraction name="keyboard_bottom_padding">4.669%p</fraction>
@@ -48,13 +48,13 @@
<fraction name="keyboard_bottom_padding_ics">4.669%p</fraction>
<fraction name="key_bottom_gap_ics">6.127%p</fraction>
<fraction name="key_horizontal_gap_ics">1.739%p</fraction>
- <dimen name="mini_keyboard_horizontal_edges_padding_ics">4dip</dimen>
+ <dimen name="more_keys_keyboard_horizontal_edges_padding_ics">4dip</dimen>
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
<!-- popup_key_height x 1.2 -->
- <dimen name="mini_keyboard_slide_allowance">0.396in</dimen>
+ <dimen name="more_keys_keyboard_slide_allowance">0.396in</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="mini_keyboard_vertical_correction">-0.330in</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction">-0.330in</dimen>
<!-- We use "inch", not "dip" because this value tries dealing with physical distance related
to user's finger. -->
<dimen name="keyboard_vertical_correction">0.0in</dimen>
@@ -66,6 +66,7 @@
<fraction name="key_hint_label_ratio">44%</fraction>
<fraction name="key_uppercase_letter_ratio">35%</fraction>
<fraction name="key_preview_text_ratio">82%</fraction>
+ <fraction name="spacebar_text_ratio">33.735%</fraction>
<dimen name="key_preview_height">80sp</dimen>
<dimen name="key_preview_offset">0.1in</dimen>
@@ -95,6 +96,4 @@
<dimen name="more_suggestions_hint_text_size">27dip</dimen>
<integer name="suggestions_count_in_strip">3</integer>
<integer name="center_suggestion_percentile">36</integer>
-
- <dimen name="key_hysteresis_distance">0.05in</dimen>
</resources>
diff --git a/java/res/values/donottranslate-more-keys.xml b/java/res/values/donottranslate-more-keys.xml
index 6c7753999..57a6d6bda 100644
--- a/java/res/values/donottranslate-more-keys.xml
+++ b/java/res/values/donottranslate-more-keys.xml
@@ -19,39 +19,44 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="more_keys_for_a"></string>
- <string name="more_keys_for_e">3</string>
- <string name="more_keys_for_i">8</string>
- <string name="more_keys_for_o">9</string>
- <string name="more_keys_for_u">7</string>
+ <string name="more_keys_for_e"></string>
+ <string name="more_keys_for_i"></string>
+ <string name="more_keys_for_o"></string>
+ <string name="more_keys_for_u"></string>
<string name="more_keys_for_s"></string>
<string name="more_keys_for_n"></string>
<string name="more_keys_for_c"></string>
- <string name="more_keys_for_y">6</string>
- <string name="more_keys_for_q">1</string>
- <string name="more_keys_for_w">2</string>
+ <string name="more_keys_for_y"></string>
<string name="more_keys_for_d"></string>
- <string name="more_keys_for_r">4</string>
- <string name="more_keys_for_t">5</string>
+ <string name="more_keys_for_r"></string>
+ <string name="more_keys_for_t"></string>
<string name="more_keys_for_z"></string>
<string name="more_keys_for_k"></string>
<string name="more_keys_for_l"></string>
<string name="more_keys_for_g"></string>
- <string name="more_keys_for_p">0</string>
<string name="more_keys_for_v"></string>
+ <string name="keylabel_for_scandinavia_row1_11"></string>
<string name="keylabel_for_scandinavia_row2_10"></string>
<string name="keylabel_for_scandinavia_row2_11"></string>
<string name="more_keys_for_scandinavia_row2_10"></string>
<string name="more_keys_for_scandinavia_row2_11"></string>
- <string name="more_keys_for_cyrillic_e"></string>
- <string name="more_keys_for_cyrillic_soft_sign"></string>
- <string name="more_keys_for_cyrillic_ha"></string>
+ <string name="keylabel_for_slavic_shcha">щ</string>
+ <string name="keylabel_for_slavic_yery">ы</string>
+ <string name="keylabel_for_slavic_i">и</string>
+ <string name="more_keys_for_slavic_u"></string>
+ <string name="more_keys_for_slavic_ye"></string>
+ <string name="more_keys_for_slavic_en"></string>
+ <string name="more_keys_for_slavic_ha">ъ</string>
+ <string name="more_keys_for_slavic_yery"></string>
+ <string name="more_keys_for_slavic_o"></string>
+ <string name="more_keys_for_slavic_soft_sign">ъ</string>
<string name="more_keys_for_currency_dollar">¢,£,€,¥,₱</string>
<string name="more_keys_for_currency_euro">¢,£,$,¥,₱</string>
<string name="more_keys_for_currency_pound">¢,$,€,¥,₱</string>
<string name="more_keys_for_currency_general">¢,$,€,£,¥,₱</string>
- <string name="more_keys_for_smiley">":-)|:-) ,:-(|:-( ,;-)|;-) ,:-P|:-P ,=-O|=-O ,:-*|:-* ,:O|:O ,B-)|B-) ,:-$|:-$ ,:-!|:-! ,:-[|:-[ ,O:-)|O:-) ,:-\\\\\\\\|:-\\\\\\\\ ,:\'(|:\'( ,:-D|:-D "</string>
+ <string name="more_keys_for_smiley">":-)|:-) ,:-(|:-( ,;-)|;-) ,:-P|:-P ,=-O|=-O ,:-*|:-* ,:O|:O ,B-)|B-) ,:-$|:-$ ,:-!|:-! ,:-[|:-[ ,O:-)|O:-) ,:-\\\\|:-\\\\ ,:\'(|:\'( ,:-D|:-D "</string>
<string name="more_keys_for_punctuation">"\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
- <integer name="mini_keyboard_column_for_punctuation">7</integer>
+ <integer name="more_keys_keyboard_column_for_punctuation">7</integer>
<string name="keyhintlabel_for_punctuation"></string>
<string name="keylabel_for_popular_domain">".com"</string>
<!-- popular web domains for the locale - most popular, displayed on the keyboard -->
@@ -66,6 +71,16 @@
<string name="keylabel_for_symbols_8">8</string>
<string name="keylabel_for_symbols_9">9</string>
<string name="keylabel_for_symbols_0">0</string>
+ <string name="additional_more_keys_for_symbols_1"></string>
+ <string name="additional_more_keys_for_symbols_2"></string>
+ <string name="additional_more_keys_for_symbols_3"></string>
+ <string name="additional_more_keys_for_symbols_4"></string>
+ <string name="additional_more_keys_for_symbols_5"></string>
+ <string name="additional_more_keys_for_symbols_6"></string>
+ <string name="additional_more_keys_for_symbols_7"></string>
+ <string name="additional_more_keys_for_symbols_8"></string>
+ <string name="additional_more_keys_for_symbols_9"></string>
+ <string name="additional_more_keys_for_symbols_0"></string>
<string name="more_keys_for_symbols_1">¹,½,⅓,¼,⅛</string>
<string name="more_keys_for_symbols_2">²,⅔</string>
<string name="more_keys_for_symbols_3">³,¾,⅜</string>
@@ -83,10 +98,8 @@
<string name="keylabel_for_symbols_percent">%</string>
<string name="more_keys_for_comma"></string>
<string name="more_keys_for_f1"></string>
- <!-- @icon/3 is iconSettingsKey -->
- <string name="more_keys_for_f1_settings">\@icon/3|\@integer/key_settings</string>
- <!-- @icon/7 is iconTabKey -->
- <string name="more_keys_for_f1_navigate">\@icon/7|\@integer/key_tab</string>
+ <string name="more_keys_for_f1_settings">\@icon/settingsKey|\@integer/key_settings</string>
+ <string name="more_keys_for_f1_navigate">\@icon/tabKey|\@integer/key_tab</string>
<string name="more_keys_for_symbols_question">¿</string>
<string name="more_keys_for_symbols_semicolon"></string>
<string name="more_keys_for_symbols_percent">‰</string>
@@ -99,6 +112,43 @@
<string name="more_keys_for_bullet">♪,♥,♠,♦,♣</string>
<string name="more_keys_for_star">†,‡,★</string>
<string name="more_keys_for_plus">±</string>
+ <!-- The all letters need to be mirrored are found at
+ http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt -->
+ <integer name="keycode_for_left_parenthesis">0x0028</integer>
+ <integer name="keycode_for_right_parenthesis">0x0029</integer>
<string name="more_keys_for_left_parenthesis">[,{,&lt;</string>
<string name="more_keys_for_right_parenthesis">],},&gt;</string>
+ <integer name="keycode_for_less_than">0x003c</integer>
+ <integer name="keycode_for_greater_than">0x003e</integer>
+ <!-- \u2264: LESS-THAN OR EQUAL TO
+ \u2265: GREATER-THAN EQUAL TO
+ \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ The following characters don't need BIDI mirroring.
+ \u2018: LEFT SINGLE QUOTATION MARK
+ \u2019: RIGHT SINGLE QUOTATION MARK
+ \u201a: SINGLE LOW-9 QUOTATION MARK
+ \u201b: SINGLE HIGH-REVERSED-9 QUOTATION MARK
+ \u201c: LEFT DOUBLE QUOTATION MARK
+ \u201d: RIGHT DOUBLE QUOTATION MARK
+ \u201e: DOUBLE LOW-9 QUOTATION MARK
+ \u201f: DOUBLE HIGH-REVERSED-9 QUOTATION MARK -->
+ <string name="more_keys_for_less_than">\u2264,\u00ab,\u2039</string>
+ <string name="more_keys_for_greater_than">\u2265,\u00bb,\u203a</string>
+ <integer name="keycode_for_left_square_bracket">0x005b</integer>
+ <integer name="keycode_for_right_square_bracket">0x005d</integer>
+ <integer name="keycode_for_left_curly_bracket">0x007b</integer>
+ <integer name="keycode_for_right_curly_bracket">0x007d</integer>
+ <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+ <string name="more_keys_for_single_quote">\u2019,\u201a,\u2018,\u201b</string>
+ <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+ <!-- <string name="more_keys_for_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb</string> -->
+ <!-- The 4-more keys will be displayed in order of "3,1,2,4". -->
+ <string name="more_keys_for_double_quote">\u201d,\u00ab,\u201c,\u00bb</string>
+ <!-- Note: Neither DroidSans nor Roboto have a glyph for DOUBLE HIGH-REVERSED-9 QUOTATION MARK. -->
+ <!-- <string name="more_keys_for_tablet_double_quote">\u201c,\u201d,\u201e,\u201f,\u00ab,\u00bb,\u2018,\u2019,\u201a,\u201b</string> -->
+ <!-- The 8-more keys with maxMoreKeysColumn=4 will be displayed in order of "3,1,2,4|7,5,6,8". -->
+ <string name="more_keys_for_tablet_double_quote">\u201d,\u00ab,\u201c,\u00bb,\u2019,\u201a,\u2018,\u201b</string>
</resources>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index aefaec9ef..cd5e3d8ea 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -19,7 +19,7 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Symbols that are suggested between words -->
- <string name="suggested_punctuations">!?,:;\u0022()\u0027-/@_</string>
+ <string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(,),\u0027,-,/,@,_</string>
<!-- Symbols that should be swapped with a magic space -->
<string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
<!-- Symbols that should strip a magic space -->
@@ -120,6 +120,7 @@
<!-- Title for Latin keyboard debug settings activity / dialog -->
<string name="english_ime_debug_settings">Android keyboard Debug settings</string>
<string name="prefs_debug_mode">Debug Mode</string>
+ <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
<!-- Keyboard theme names -->
<string name="layout_basic">Basic</string>
@@ -161,9 +162,12 @@
<!-- Generic subtype label -->
<string name="subtype_generic">%s</string>
+ <!-- Description for generic QWERTY keyboard subtype -->
+ <string name="subtype_generic_qwerty">%s (QWERTY)</string>
<!-- dictionary pack package name /settings activity (for shared prefs and settings) -->
<string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string>
<string name="dictionary_pack_settings_activity">com.google.android.inputmethod.latin.dictionarypack.DictionarySettingsActivity</string>
<string name="settings_ms">ms</string>
+ <string name="settings_warning_researcher_mode">Attention! You are using the special keyboard for research purposes.</string>
</resources>
diff --git a/java/res/values/keyboard-icons-black.xml b/java/res/values/keyboard-icons-black.xml
index f767cb349..1c5a5f720 100644
--- a/java/res/values/keyboard-icons-black.xml
+++ b/java/res/values/keyboard-icons-black.xml
@@ -30,10 +30,9 @@
<item name="iconTabKey">@drawable/sym_bkeyboard_tab</item>
<item name="iconShortcutKey">@drawable/sym_bkeyboard_mic</item>
<item name="iconShortcutForLabel">@drawable/sym_bkeyboard_label_mic</item>
- <item name="iconShiftedShiftKey">@drawable/sym_bkeyboard_shift_locked</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_bkeyboard_space</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_bkeyboard_shift_locked</item>
+ <item name="iconDisabledShortcutKey">@drawable/sym_bkeyboard_voice_off</item>
<item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
- <!-- LatinKeyboard icons -->
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="disabledShortcutIcon">@drawable/sym_bkeyboard_voice_off</item>
</style>
</resources>
diff --git a/java/res/values/keyboard-icons-ics.xml b/java/res/values/keyboard-icons-ics.xml
index f1021433d..f68be5f1e 100644
--- a/java/res/values/keyboard-icons-ics.xml
+++ b/java/res/values/keyboard-icons-ics.xml
@@ -23,16 +23,15 @@
<item name="iconShiftKey">@drawable/sym_keyboard_shift_holo</item>
<item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo</item>
<item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo</item>
- <item name="iconSpaceKey">@drawable/sym_keyboard_space_holo</item>
+ <item name="iconSpaceKey">@null</item>
<item name="iconReturnKey">@drawable/sym_keyboard_return_holo</item>
<item name="iconSearchKey">@drawable/sym_keyboard_search_holo</item>
<item name="iconTabKey">@drawable/sym_keyboard_tab_holo</item>
<item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo</item>
<item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo</item>
- <item name="iconShiftedShiftKey">@drawable/sym_keyboard_shift_locked_holo</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space_holo</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo</item>
+ <item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item>
<item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
- <!-- LatinKeyboard icons -->
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
- <item name="disabledShortcutIcon">@drawable/sym_keyboard_voice_off_holo</item>
</style>
</resources>
diff --git a/java/res/values/keyboard-icons-white.xml b/java/res/values/keyboard-icons-white.xml
index 07ece66b1..35197a1c0 100644
--- a/java/res/values/keyboard-icons-white.xml
+++ b/java/res/values/keyboard-icons-white.xml
@@ -26,10 +26,10 @@
<item name="iconTabKey">@drawable/sym_keyboard_tab</item>
<item name="iconShortcutKey">@drawable/sym_keyboard_mic</item>
<item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic</item>
- <item name="iconShiftedShiftKey">@drawable/sym_keyboard_shift_locked</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked</item>
+ <!-- TODO: Needs non-holo disabled shortcut icon drawable -->
+ <item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item>
<item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
- <!-- LatinKeyboard icons -->
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="disabledShortcutIcon">@drawable/sym_keyboard_voice_off_holo</item>
</style>
</resources>
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
index 59cc07531..c85c02263 100644
--- a/java/res/values/keycodes.xml
+++ b/java/res/values/keycodes.xml
@@ -21,11 +21,14 @@
<resources>
<!-- These code should be aligned with Keyboard.CODE_*. -->
<integer name="key_tab">9</integer>
- <integer name="key_return">10</integer>
+ <integer name="key_enter">10</integer>
<integer name="key_space">32</integer>
<integer name="key_shift">-1</integer>
<integer name="key_switch_alpha_symbol">-2</integer>
- <integer name="key_delete">-5</integer>
- <integer name="key_settings">-6</integer>
- <integer name="key_shortcut">-7</integer>
+ <integer name="key_output_text">-3</integer>
+ <integer name="key_delete">-4</integer>
+ <integer name="key_settings">-5</integer>
+ <integer name="key_shortcut">-6</integer>
+ <integer name="key_action_enter">-7</integer>
+ <integer name="key_unspecified">-9</integer>
</resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index e00547a62..1e8b7db96 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -20,6 +20,8 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Title for Latin keyboard -->
<string name="english_ime_name">Android keyboard</string>
+ <!-- Application name for opensource Android keyboard. AOSP(Android Open Source Project) should not be translated. -->
+ <string name="aosp_android_keyboard_ime_name">Android keyboard (AOSP)</string>
<!-- Title for Latin keyboard settings activity / dialog -->
<string name="english_ime_settings">Android keyboard settings</string>
<!-- Title for Latin keyboard input options dialog [CHAR LIMIT=25] -->
@@ -31,11 +33,11 @@
<!-- Title for the spell checking service settings screen -->
<string name="android_spell_checker_settings">Spell checking settings</string>
- <!-- Title for the "use proximity" option for spell checking [CHAR LIMIT=25] -->
- <string name="use_proximity_option_title">Use proximity data</string>
+ <!-- Title for the spell checker option to turn on/off contact names lookup [CHAR LIMIT=25] -->
+ <string name="use_contacts_for_spellchecking_option_title">Look up contact names</string>
- <!-- Description for the "use proximity" option for spell checking [CHAR LIMIT=65] -->
- <string name="use_proximity_option_summary">Use a keyboard-like proximity algorithm for spell checking</string>
+ <!-- Description for the spell checker option to turn on/off contact names lookup. [CHAR LIMIT=65] -->
+ <string name="use_contacts_for_spellchecking_option_summary">Spell checker uses entries from your contact list</string>
<!-- Option to provide vibrate/haptic feedback on keypress -->
<string name="vibrate_on_keypress">Vibrate on keypress</string>
@@ -126,6 +128,8 @@
<string name="label_go_key">Go</string>
<!-- Label for soft enter key when it performs NEXT action. Must be short to fit on key! [CHAR LIMIT=5] -->
<string name="label_next_key">Next</string>
+ <!-- Label for soft enter key when it performs PREVIOUS action. Must be short to fit on key! [CHAR LIMIT=5] -->
+ <string name="label_previous_key">Prev</string>
<!-- Label for soft enter key when it performs DONE action. Must be short to fit on key! [CHAR LIMIT=5] -->
<string name="label_done_key">Done</string>
<!-- Label for soft enter key when it performs SEND action. Must be short to fit on key! [CHAR LIMIT=5] -->
@@ -152,12 +156,12 @@
<!-- Spoken description for unknown keyboard keys. -->
<string name="spoken_description_unknown">Key code %d</string>
- <!-- Spoken description for the "Shift" keyboard key. -->
+ <!-- Spoken description for the "Shift" keyboard key when "Shift" is off. -->
<string name="spoken_description_shift">Shift</string>
- <!-- Spoken description for the "Shift" keyboard key's pressed state. -->
- <string name="spoken_description_shift_shifted">Shift enabled</string>
- <!-- Spoken description for the "Shift" keyboard key's pressed state. -->
- <string name="spoken_description_caps_lock">Caps lock enabled</string>
+ <!-- Spoken description for the "Shift" keyboard key when "Shift" is on. -->
+ <string name="spoken_description_shift_shifted">Shift on (tap to disable)</string>
+ <!-- Spoken description for the "Shift" keyboard key when "Caps lock" is on. -->
+ <string name="spoken_description_caps_lock">Caps lock on (tap to disable)</string>
<!-- Spoken description for the "Delete" keyboard key. -->
<string name="spoken_description_delete">Delete</string>
<!-- Spoken description for the "To Symbol" keyboard key. -->
@@ -178,47 +182,24 @@
<string name="spoken_description_smiley">Smiley face</string>
<!-- Spoken description for the "Return" keyboard key. -->
<string name="spoken_description_return">Return</string>
-
- <!-- Spoken description for the "," keyboard key. -->
- <string name="spoken_description_comma">Comma</string>
- <!-- Spoken description for the "." keyboard key. -->
- <string name="spoken_description_period">Period</string>
- <!-- Spoken description for the "(" keyboard key. -->
- <string name="spoken_description_left_parenthesis">Left parenthesis</string>
- <!-- Spoken description for the ")" keyboard key. -->
- <string name="spoken_description_right_parenthesis">Right parenthesis</string>
- <!-- Spoken description for the ":" keyboard key. -->
- <string name="spoken_description_colon">Colon</string>
- <!-- Spoken description for the ";" keyboard key. -->
- <string name="spoken_description_semicolon">Semicolon</string>
- <!-- Spoken description for the "!" keyboard key. -->
- <string name="spoken_description_exclamation_mark">Exclamation mark</string>
- <!-- Spoken description for the "?" keyboard key. -->
- <string name="spoken_description_question_mark">Question mark</string>
- <!-- Spoken description for the """ keyboard key. -->
- <string name="spoken_description_double_quote">Double quote</string>
- <!-- Spoken description for the "'" keyboard key. -->
- <string name="spoken_description_single_quote">Single quote</string>
<!-- Spoken description for the "\u2022" (BULLET) keyboard key. -->
<string name="spoken_description_dot">Dot</string>
- <!-- Spoken description for the "\u221a" (SQUARE ROOT) keyboard key. -->
- <string name="spoken_description_square_root">Square root</string>
- <!-- Spoken description for the "\u03C0" (GREEK SMALL LETTER PI) keyboard key. -->
- <string name="spoken_description_pi">Pi</string>
- <!-- Spoken description for the "\u0394" (GREEK CAPITAL LETTER DELTA) keyboard key. -->
- <string name="spoken_description_delta">Delta</string>
- <!-- Spoken description for the "\u2122" (TRADE MARK SIGN) keyboard key. -->
- <string name="spoken_description_trademark">Trademark</string>
- <!-- Spoken description for the "\u2105" (CARE OF) keyboard key. -->
- <string name="spoken_description_care_of">Care of</string>
- <!-- Spoken description for the "*" keyboard key. -->
- <string name="spoken_description_star">Star</string>
- <!-- Spoken description for the "#" keyboard key. -->
- <string name="spoken_description_pound">Pound</string>
- <!-- Spoken description for the "\u2026" (HORIZONTAL ELLIPSIS) keyboard key. -->
- <string name="spoken_description_ellipsis">Ellipsis</string>
- <!-- Spoken description for the "\u201E" (DOUBLE LOW-9 QUOTATION MARK) keyboard key. -->
- <string name="spoken_description_low_double_quote">Low double quote</string>
+
+ <!-- Spoken feedback after turning "Shift" mode on. -->
+ <string name="spoken_description_shiftmode_on">Shift enabled</string>
+ <!-- Spoken feedback after turning "Caps lock" mode on. -->
+ <string name="spoken_description_shiftmode_locked">Caps lock enabled</string>
+ <!-- Spoken feedback after turning "Shift" mode off. -->
+ <string name="spoken_description_shiftmode_off">Shift disabled</string>
+
+ <!-- Spoken feedback after changing to the symbols keyboard. -->
+ <string name="spoken_description_mode_symbol">Symbols mode</string>
+ <!-- Spoken feedback after changing to the alphanumeric keyboard. -->
+ <string name="spoken_description_mode_alpha">Letters mode</string>
+ <!-- Spoken feedback after changing to the phone dialer keyboard. -->
+ <string name="spoken_description_mode_phone">Phone mode</string>
+ <!-- Spoken feedback after changing to the shifted phone dialer (symbols) keyboard. -->
+ <string name="spoken_description_mode_phone_shift">Phone symbols mode</string>
<!-- Voice related labels -->
@@ -333,8 +314,6 @@
<!-- Title of the item to change the keyboard theme [CHAR LIMIT=20]-->
<string name="keyboard_layout">Keyboard theme</string>
- <!-- Description for German QWERTY keyboard subtype [CHAR LIMIT=22] -->
- <string name="subtype_de_qwerty">German QWERTY</string>
<!-- Description for English (United Kingdom) keyboard subtype [CHAR LIMIT=22] -->
<string name="subtype_en_GB">English (UK)</string>
<!-- Description for English (United States) keyboard subtype [CHAR LIMIT=22] -->
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 43aa58388..b9e8b26a3 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -23,7 +23,7 @@
<item name="keyboardHeight">@dimen/keyboardHeight</item>
<item name="maxKeyboardHeight">@fraction/maxKeyboardHeight</item>
<item name="minKeyboardHeight">@fraction/minKeyboardHeight</item>
- <item name="moreKeysTemplate">@xml/kbd_mini_keyboard_template</item>
+ <item name="moreKeysTemplate">@xml/kbd_more_keys_keyboard_template</item>
<item name="keyboardTopPadding">@fraction/keyboard_top_padding</item>
<item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding</item>
<item name="keyboardHorizontalEdgesPadding">@fraction/keyboard_horizontal_edges_padding</item>
@@ -31,12 +31,6 @@
<item name="verticalGap">@fraction/key_bottom_gap</item>
<item name="maxMoreKeysColumn">@integer/config_max_more_keys_column</item>
</style>
- <style name="LatinKeyboard">
- <item name="autoCorrectionSpacebarLedEnabled">@bool/config_auto_correction_spacebar_led_enabled
- </item>
- <item name="spacebarTextColor">#FFC0C0C0</item>
- <item name="spacebarTextShadowColor">#80000000</item>
- </style>
<style name="KeyboardView">
<item name="android:background">@drawable/keyboard_background</item>
<item name="keyBackground">@drawable/btn_keyboard_key</item>
@@ -45,18 +39,18 @@
<item name="keyLabelRatio">@fraction/key_label_ratio</item>
<item name="keyHintLetterRatio">@fraction/key_hint_letter_ratio</item>
<item name="keyHintLabelRatio">@fraction/key_hint_label_ratio</item>
- <item name="keyUppercaseLetterRatio">@fraction/key_uppercase_letter_ratio</item>
+ <item name="keyShiftedLetterHintRatio">@fraction/key_uppercase_letter_ratio</item>
<item name="keyTextStyle">normal</item>
<item name="keyTextColor">#FFFFFFFF</item>
<item name="keyTextInactivatedColor">#FFFFFFFF</item>
<item name="keyHintLetterColor">#80000000</item>
<item name="keyHintLabelColor">#E0E0E4E5</item>
- <item name="keyUppercaseLetterInactivatedColor">#66E0E4E5</item>
- <item name="keyUppercaseLetterActivatedColor">#CCE0E4E5</item>
+ <item name="keyShiftedLetterHintInactivatedColor">#66E0E4E5</item>
+ <item name="keyShiftedLetterHintActivatedColor">#CCE0E4E5</item>
<item name="keyLabelHorizontalPadding">@dimen/key_label_horizontal_padding</item>
<item name="keyHintLetterPadding">@dimen/key_hint_letter_padding</item>
<item name="keyPopupHintLetterPadding">@dimen/key_popup_hint_letter_padding</item>
- <item name="keyUppercaseLetterPadding">@dimen/key_uppercase_letter_padding</item>
+ <item name="keyShiftedLetterHintPadding">@dimen/key_uppercase_letter_padding</item>
<item name="keyPreviewLayout">@layout/key_preview</item>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback</item>
<item name="keyPreviewLeftBackground">@null</item>
@@ -65,14 +59,36 @@
<item name="keyPreviewOffset">@dimen/key_preview_offset</item>
<item name="keyPreviewHeight">@dimen/key_preview_height</item>
<item name="keyPreviewTextRatio">@fraction/key_preview_text_ratio</item>
- <item name="moreKeysLayout">@layout/mini_keyboard</item>
+ <item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
+ <item name="moreKeysLayout">@layout/more_keys_keyboard</item>
<item name="verticalCorrection">@dimen/keyboard_vertical_correction</item>
<item name="shadowColor">#BB000000</item>
<item name="shadowRadius">2.75</item>
<item name="backgroundDimAmount">0.5</item>
+ <!-- Common attributes of LatinKeyboardView -->
+ <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
+ <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
+ <item name="touchNoiseThresholdDistance">@dimen/config_touch_noise_threshold_distance</item>
+ <item name="slidingKeyInputEnable">@bool/config_sliding_key_input_enabled</item>
+ <item name="keyRepeatStartTimeout">@integer/config_key_repeat_start_timeout</item>
+ <item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
+ <item name="longPressKeyTimeout">@integer/config_long_press_key_timeout</item>
+ <item name="longPressShiftKeyTimeout">@integer/config_long_press_shift_key_timeout</item>
+ <item name="longPressSpaceKeyTimeout">@integer/config_long_press_space_key_timeout</item>
+ <item name="ignoreSpecialKeyTimeout">@integer/config_ignore_special_key_timeout</item>
+ <item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
</style>
<style
- name="MiniKeyboard"
+ name="LatinKeyboardView"
+ parent="KeyboardView">
+ <item name="autoCorrectionSpacebarLedEnabled">true</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="spacebarTextColor">#FFC0C0C0</item>
+ <item name="spacebarTextShadowColor">#80000000</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard"
parent="Keyboard"
>
<item name="keyboardTopPadding">0dip</item>
@@ -80,16 +96,16 @@
<item name="horizontalGap">0dip</item>
</style>
<style
- name="MiniKeyboardView"
+ name="MoreKeysKeyboardView"
parent="KeyboardView"
>
<item name="keyBackground">@drawable/btn_keyboard_key_popup</item>
- <item name="verticalCorrection">@dimen/mini_keyboard_vertical_correction</item>
+ <item name="verticalCorrection">@dimen/more_keys_keyboard_vertical_correction</item>
</style>
- <style name="MiniKeyboardPanelStyle">
+ <style name="MoreKeysKeyboardPanelStyle">
<item name="android:background">@drawable/keyboard_popup_panel_background</item>
- <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding</item>
- <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding</item>
+ <item name="android:paddingLeft">@dimen/more_keys_keyboard_horizontal_edges_padding</item>
+ <item name="android:paddingRight">@dimen/more_keys_keyboard_horizontal_edges_padding</item>
</style>
<style name="SuggestionsStripBackgroundStyle">
<item name="android:background">@drawable/keyboard_suggest_strip</item>
@@ -98,7 +114,8 @@
name="SuggestionsViewStyle"
parent="SuggestionsStripBackgroundStyle"
>
- <item name="suggestionStripOption">autoCorrectBold</item>
+ <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
+ <item name="colorValidTypedWord">#FFFCAE00</item>
<item name="colorTypedWord">@android:color/white</item>
<item name="colorAutoCorrect">#FFFCAE00</item>
<item name="colorSuggested">#FFFCAE00</item>
@@ -110,7 +127,7 @@
</style>
<style
name="MoreSuggestionsViewStyle"
- parent="MiniKeyboardView"
+ parent="MoreKeysKeyboardView"
>
</style>
<style name="SuggestionBackgroundStyle">
@@ -133,6 +150,16 @@
<item name="android:background">@android:color/black</item>
<item name="keyBackground">@drawable/btn_keyboard_key3</item>
</style>
+ <style
+ name="LatinKeyboardView.HighContrast"
+ parent="KeyboardView.HighContrast"
+ >
+ <item name="autoCorrectionSpacebarLedEnabled">true</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="spacebarTextColor">#FFC0C0C0</item>
+ <item name="spacebarTextShadowColor">#80000000</item>
+ </style>
<!-- Theme "Stone" -->
<style
name="Keyboard.Stone"
@@ -146,13 +173,6 @@
<item name="verticalGap">@fraction/key_bottom_gap_stone</item>
</style>
<style
- name="LatinKeyboard.Stone"
- parent="LatinKeyboard"
- >
- <item name="spacebarTextColor">#FF000000</item>
- <item name="spacebarTextShadowColor">#D0FFFFFF</item>
- </style>
- <style
name="KeyboardView.Stone"
parent="KeyboardView"
>
@@ -161,12 +181,22 @@
<item name="keyTextInactivatedColor">#FF808080</item>
<item name="keyHintLetterColor">#80000000</item>
<item name="keyHintLabelColor">#E0000000</item>
- <item name="keyUppercaseLetterInactivatedColor">#66000000</item>
- <item name="keyUppercaseLetterActivatedColor">#CC000000</item>
+ <item name="keyShiftedLetterHintInactivatedColor">#66000000</item>
+ <item name="keyShiftedLetterHintActivatedColor">#CC000000</item>
<item name="shadowColor">#FFFFFFFF</item>
</style>
<style
- name="MiniKeyboard.Stone"
+ name="LatinKeyboardView.Stone"
+ parent="KeyboardView.Stone"
+ >
+ <item name="autoCorrectionSpacebarLedEnabled">true</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="spacebarTextColor">#FF000000</item>
+ <item name="spacebarTextShadowColor">#D0FFFFFF</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard.Stone"
parent="Keyboard.Stone"
>
<item name="keyboardTopPadding">0dip</item>
@@ -174,8 +204,8 @@
<item name="horizontalGap">0dip</item>
</style>
<style
- name="MiniKeyboardView.Stone"
- parent="MiniKeyboardView"
+ name="MoreKeysKeyboardView.Stone"
+ parent="MoreKeysKeyboardView"
>
<item name="keyBackground">@drawable/btn_keyboard_key_stone</item>
<item name="keyTextColor">#FF000000</item>
@@ -194,6 +224,16 @@
>
<item name="keyTextStyle">bold</item>
</style>
+ <style
+ name="LatinKeyboardView.Stone.Bold"
+ parent="KeyboardView.Stone.Bold"
+ >
+ <item name="autoCorrectionSpacebarLedEnabled">true</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="spacebarTextColor">#FF000000</item>
+ <item name="spacebarTextShadowColor">#D0FFFFFF</item>
+ </style>
<!-- Theme "Gingerbread" -->
<style
name="Keyboard.Gingerbread"
@@ -213,7 +253,17 @@
<item name="keyTextStyle">bold</item>
</style>
<style
- name="MiniKeyboard.Gingerbread"
+ name="LatinKeyboardView.Gingerbread"
+ parent="KeyboardView.Gingerbread"
+ >
+ <item name="autoCorrectionSpacebarLedEnabled">true</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="spacebarTextColor">#FFC0C0C0</item>
+ <item name="spacebarTextShadowColor">#80000000</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard.Gingerbread"
parent="Keyboard.Gingerbread"
>
<item name="keyboardTopPadding">0dip</item>
@@ -221,8 +271,8 @@
<item name="horizontalGap">0dip</item>
</style>
<style
- name="MiniKeyboardView.Gingerbread"
- parent="MiniKeyboardView"
+ name="MoreKeysKeyboardView.Gingerbread"
+ parent="MoreKeysKeyboardView"
>
<item name="android:background">@null</item>
</style>
@@ -239,12 +289,6 @@
<item name="touchPositionCorrectionData">@array/touch_position_correction_data_ice_cream_sandwich</item>
</style>
<style
- name="LatinKeyboard.IceCreamSandwich"
- parent="LatinKeyboard"
- >
- <item name="disabledShortcutIcon">@drawable/sym_keyboard_voice_off_holo</item>
- </style>
- <style
name="KeyboardView.IceCreamSandwich"
parent="KeyboardView"
>
@@ -254,8 +298,8 @@
<item name="keyTextInactivatedColor">#66E0E4E5</item>
<item name="keyHintLetterColor">#80000000</item>
<item name="keyHintLabelColor">#A0FFFFFF</item>
- <item name="keyUppercaseLetterInactivatedColor">#66E0E4E5</item>
- <item name="keyUppercaseLetterActivatedColor">#FFFFFFFF</item>
+ <item name="keyShiftedLetterHintInactivatedColor">#66E0E4E5</item>
+ <item name="keyShiftedLetterHintActivatedColor">#FFFFFFFF</item>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_ics</item>
<item name="keyPreviewLeftBackground">@drawable/keyboard_key_feedback_left_ics</item>
<item name="keyPreviewRightBackground">@drawable/keyboard_key_feedback_right_ics</item>
@@ -268,7 +312,17 @@
<item name="shadowRadius">0.0</item>
</style>
<style
- name="MiniKeyboard.IceCreamSandwich"
+ name="LatinKeyboardView.IceCreamSandwich"
+ parent="KeyboardView.IceCreamSandwich"
+ >
+ <item name="autoCorrectionSpacebarLedEnabled">false</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="spacebarTextColor">#FFC0C0C0</item>
+ <item name="spacebarTextShadowColor">#80000000</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard.IceCreamSandwich"
parent="Keyboard.IceCreamSandwich"
>
<item name="keyboardTopPadding">0dip</item>
@@ -276,16 +330,16 @@
<item name="horizontalGap">0dip</item>
</style>
<style
- name="MiniKeyboardView.IceCreamSandwich"
- parent="MiniKeyboardView"
+ name="MoreKeysKeyboardView.IceCreamSandwich"
+ parent="MoreKeysKeyboardView"
>
<item name="android:background">@null</item>
<item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
</style>
- <style name="MiniKeyboardPanelStyle.IceCreamSandwich">
+ <style name="MoreKeysKeyboardPanelStyle.IceCreamSandwich">
<item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
- <item name="android:paddingLeft">@dimen/mini_keyboard_horizontal_edges_padding_ics</item>
- <item name="android:paddingRight">@dimen/mini_keyboard_horizontal_edges_padding_ics</item>
+ <item name="android:paddingLeft">@dimen/more_keys_keyboard_horizontal_edges_padding_ics</item>
+ <item name="android:paddingRight">@dimen/more_keys_keyboard_horizontal_edges_padding_ics</item>
</style>
<style name="SuggestionsStripBackgroundStyle.IceCreamSandwich">
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
@@ -296,11 +350,12 @@
>
<item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
<!-- android:color/holo_blue_light=#FF33B5E5 -->
+ <item name="colorValidTypedWord">@android:color/holo_blue_light</item>
<item name="colorTypedWord">@android:color/holo_blue_light</item>
<item name="colorAutoCorrect">@android:color/holo_blue_light</item>
<item name="colorSuggested">@android:color/holo_blue_light</item>
+ <item name="alphaValidTypedWord">85</item>
<item name="alphaTypedWord">85</item>
- <item name="alphaAutoCorrect">100</item>
<item name="alphaSuggested">70</item>
<item name="alphaObsoleted">70</item>
<item name="suggestionsCountInStrip">@integer/suggestions_count_in_strip</item>
@@ -310,7 +365,7 @@
</style>
<style
name="MoreSuggestionsViewStyle.IceCreamSandwich"
- parent="MiniKeyboardView.IceCreamSandwich"
+ parent="MoreKeysKeyboardView.IceCreamSandwich"
>
</style>
<style name="SuggestionBackgroundStyle.IceCreamSandwich">
@@ -318,11 +373,11 @@
</style>
<style
name="SuggestionPreviewBackgroundStyle.IceCreamSandwich"
- parent="MiniKeyboardPanelStyle.IceCreamSandwich"
+ parent="MoreKeysKeyboardPanelStyle.IceCreamSandwich"
>
</style>
- <style name="MiniKeyboardAnimation">
- <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
- <item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item>
+ <style name="MoreKeysKeyboardAnimation">
+ <item name="android:windowEnterAnimation">@anim/more_keys_keyboard_fadein</item>
+ <item name="android:windowExitAnimation">@anim/more_keys_keyboard_fadeout</item>
</style>
</resources>
diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml
index abb7c8057..19df42ce1 100644
--- a/java/res/values/themes-basic-highcontrast.xml
+++ b/java/res/values/themes-basic-highcontrast.xml
@@ -17,11 +17,11 @@
<resources>
<style name="KeyboardTheme.HighContrast" parent="KeyboardIcons">
<item name="keyboardStyle">@style/Keyboard.HighContrast</item>
- <item name="latinKeyboardStyle">@style/LatinKeyboard</item>
<item name="keyboardViewStyle">@style/KeyboardView.HighContrast</item>
- <item name="miniKeyboardStyle">@style/MiniKeyboard</item>
- <item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item>
- <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
+ <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.HighContrast</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView</item>
+ <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
<item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item>
<item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml
index ff9fed55f..5d477206d 100644
--- a/java/res/values/themes-basic.xml
+++ b/java/res/values/themes-basic.xml
@@ -17,11 +17,11 @@
<resources>
<style name="KeyboardTheme" parent="KeyboardIcons">
<item name="keyboardStyle">@style/Keyboard</item>
- <item name="latinKeyboardStyle">@style/LatinKeyboard</item>
<item name="keyboardViewStyle">@style/KeyboardView</item>
- <item name="miniKeyboardStyle">@style/MiniKeyboard</item>
- <item name="miniKeyboardViewStyle">@style/MiniKeyboardView</item>
- <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
+ <item name="latinKeyboardViewStyle">@style/LatinKeyboardView</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView</item>
+ <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
<item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item>
<item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml
index be853eb0f..a13979818 100644
--- a/java/res/values/themes-gingerbread.xml
+++ b/java/res/values/themes-gingerbread.xml
@@ -17,11 +17,11 @@
<resources>
<style name="KeyboardTheme.Gingerbread" parent="KeyboardIcons">
<item name="keyboardStyle">@style/Keyboard.Gingerbread</item>
- <item name="latinKeyboardStyle">@style/LatinKeyboard</item>
<item name="keyboardViewStyle">@style/KeyboardView.Gingerbread</item>
- <item name="miniKeyboardStyle">@style/MiniKeyboard.Gingerbread</item>
- <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Gingerbread</item>
- <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
+ <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.Gingerbread</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Gingerbread</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Gingerbread</item>
+ <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
<item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item>
<item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 618aaed79..e6fd4f451 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -17,11 +17,11 @@
<resources>
<style name="KeyboardTheme.IceCreamSandwich" parent="KeyboardIcons.IceCreamSandwich">
<item name="keyboardStyle">@style/Keyboard.IceCreamSandwich</item>
- <item name="latinKeyboardStyle">@style/LatinKeyboard.IceCreamSandwich</item>
<item name="keyboardViewStyle">@style/KeyboardView.IceCreamSandwich</item>
- <item name="miniKeyboardStyle">@style/MiniKeyboard.IceCreamSandwich</item>
- <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.IceCreamSandwich</item>
- <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle.IceCreamSandwich</item>
+ <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.IceCreamSandwich</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.IceCreamSandwich</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.IceCreamSandwich</item>
+ <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle.IceCreamSandwich</item>
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle.IceCreamSandwich</item>
<item name="suggestionsViewStyle">@style/SuggestionsViewStyle.IceCreamSandwich</item>
<item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle.IceCreamSandwich</item>
diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml
index 532a2985e..47de99e47 100644
--- a/java/res/values/themes-stone-bold.xml
+++ b/java/res/values/themes-stone-bold.xml
@@ -17,11 +17,11 @@
<resources>
<style name="KeyboardTheme.Stone.Bold" parent="KeyboardIcons.Black">
<item name="keyboardStyle">@style/Keyboard.Stone.Bold</item>
- <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item>
<item name="keyboardViewStyle">@style/KeyboardView.Stone.Bold</item>
- <item name="miniKeyboardStyle">@style/MiniKeyboard.Stone</item>
- <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item>
- <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
+ <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.Stone.Bold</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Stone</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Stone</item>
+ <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
<item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item>
<item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml
index cb3edc58f..a0b39e3e6 100644
--- a/java/res/values/themes-stone.xml
+++ b/java/res/values/themes-stone.xml
@@ -17,11 +17,11 @@
<resources>
<style name="KeyboardTheme.Stone" parent="KeyboardIcons.Black">
<item name="keyboardStyle">@style/Keyboard.Stone</item>
- <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item>
<item name="keyboardViewStyle">@style/KeyboardView.Stone</item>
- <item name="miniKeyboardStyle">@style/MiniKeyboard.Stone</item>
- <item name="miniKeyboardViewStyle">@style/MiniKeyboardView.Stone</item>
- <item name="miniKeyboardPanelStyle">@style/MiniKeyboardPanelStyle</item>
+ <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.Stone</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Stone</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Stone</item>
+ <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
<item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
<item name="suggestionsViewStyle">@style/SuggestionsViewStyle</item>
<item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
diff --git a/java/res/xml-ar/keyboard_set.xml b/java/res/xml-ar/keyboard_set.xml
new file mode 100644
index 000000000..7b70f633c
--- /dev/null
+++ b/java/res/xml-ar/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="ar" >
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_arabic" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-be/keyboard_set.xml b/java/res/xml-be/keyboard_set.xml
new file mode 100644
index 000000000..042264aae
--- /dev/null
+++ b/java/res/xml-be/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="be">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_slavic" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-bg/keyboard_set.xml b/java/res/xml-bg/keyboard_set.xml
new file mode 100644
index 000000000..49914d54b
--- /dev/null
+++ b/java/res/xml-bg/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="bg">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_bulgarian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-cs/keyboard_set.xml b/java/res/xml-cs/keyboard_set.xml
new file mode 100644
index 000000000..b4535164b
--- /dev/null
+++ b/java/res/xml-cs/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="cs">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwertz" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-da/keyboard_set.xml b/java/res/xml-da/keyboard_set.xml
new file mode 100644
index 000000000..cf01ae6f5
--- /dev/null
+++ b/java/res/xml-da/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="da">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_scandinavian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-de-rZZ/keyboard_set.xml b/java/res/xml-de-rZZ/keyboard_set.xml
new file mode 100644
index 000000000..635884d1d
--- /dev/null
+++ b/java/res/xml-de-rZZ/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="de">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml
deleted file mode 100644
index 89e10b26d..000000000
--- a/java/res/xml-de/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="de"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_qwertz" />
-</Keyboard>
diff --git a/java/res/xml-de/keyboard_set.xml b/java/res/xml-de/keyboard_set.xml
new file mode 100644
index 000000000..485e63f06
--- /dev/null
+++ b/java/res/xml-de/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="de">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwertz" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-es/kbd_qwerty.xml b/java/res/xml-es/kbd_qwerty.xml
deleted file mode 100644
index 568f4d652..000000000
--- a/java/res/xml-es/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="es,es_US"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_spanish" />
-</Keyboard>
diff --git a/java/res/xml-es/keyboard_set.xml b/java/res/xml-es/keyboard_set.xml
new file mode 100644
index 000000000..2944a83ad
--- /dev/null
+++ b/java/res/xml-es/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="es,es_US">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_spanish" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-et/keyboard_set.xml b/java/res/xml-et/keyboard_set.xml
new file mode 100644
index 000000000..1c23db3d8
--- /dev/null
+++ b/java/res/xml-et/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="et">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_scandinavian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-fi/kbd_qwerty.xml b/java/res/xml-fi/kbd_qwerty.xml
deleted file mode 100644
index 75721e057..000000000
--- a/java/res/xml-fi/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="fi"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
-</Keyboard>
diff --git a/java/res/xml-fi/keyboard_set.xml b/java/res/xml-fi/keyboard_set.xml
new file mode 100644
index 000000000..e8e4e7d9a
--- /dev/null
+++ b/java/res/xml-fi/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="fi">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_scandinavian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml
deleted file mode 100644
index 7bdfbadf1..000000000
--- a/java/res/xml-fr-rCA/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="fr_CA"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_qwerty" />
-</Keyboard>
diff --git a/java/res/xml-fr-rCA/keyboard_set.xml b/java/res/xml-fr-rCA/keyboard_set.xml
new file mode 100644
index 000000000..ea6ac8f26
--- /dev/null
+++ b/java/res/xml-fr-rCA/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="fr_CA">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-fr-rCH/kbd_qwerty.xml b/java/res/xml-fr-rCH/kbd_qwerty.xml
deleted file mode 100644
index 41b701d83..000000000
--- a/java/res/xml-fr-rCH/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="fr_CH"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_qwertz" />
-</Keyboard>
diff --git a/java/res/xml-fr-rCH/keyboard_set.xml b/java/res/xml-fr-rCH/keyboard_set.xml
new file mode 100644
index 000000000..751900b88
--- /dev/null
+++ b/java/res/xml-fr-rCH/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="fr_CH">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwertz" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-fr/keyboard_set.xml b/java/res/xml-fr/keyboard_set.xml
new file mode 100644
index 000000000..42a20e5ea
--- /dev/null
+++ b/java/res/xml-fr/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="fr">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_azerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-hr/kbd_qwerty.xml b/java/res/xml-hr/kbd_qwerty.xml
deleted file mode 100644
index ca92e86a7..000000000
--- a/java/res/xml-hr/kbd_qwerty.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="hr"
->
- <!-- TODO: Dedicated Croatian layout especially for tablet. -->
- <include
- latin:keyboardLayout="@xml/kbd_rows_qwertz" />
-</Keyboard>
diff --git a/java/res/xml-hr/keyboard_set.xml b/java/res/xml-hr/keyboard_set.xml
new file mode 100644
index 000000000..e17aefdf6
--- /dev/null
+++ b/java/res/xml-hr/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="hr">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwertz" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-hu/keyboard_set.xml b/java/res/xml-hu/keyboard_set.xml
new file mode 100644
index 000000000..0f6e5759e
--- /dev/null
+++ b/java/res/xml-hu/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="hu">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwertz" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml
deleted file mode 100644
index 54cd4b5e9..000000000
--- a/java/res/xml-iw/kbd_qwerty.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2010, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="iw"
- latin:isRtlKeyboard="true"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_hebrew" />
-</Keyboard>
diff --git a/java/res/xml-iw/kbd_symbols.xml b/java/res/xml-iw/kbd_symbols.xml
deleted file mode 100644
index 9e5c255d0..000000000
--- a/java/res/xml-iw/kbd_symbols.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:isRtlKeyboard="true"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_symbols" />
-</Keyboard>
diff --git a/java/res/xml-iw/kbd_symbols_shift.xml b/java/res/xml-iw/kbd_symbols_shift.xml
deleted file mode 100644
index 934e6f849..000000000
--- a/java/res/xml-iw/kbd_symbols_shift.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:isRtlKeyboard="true"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_symbols_shift" />
-</Keyboard>
diff --git a/java/res/xml-iw/keyboard_set.xml b/java/res/xml-iw/keyboard_set.xml
new file mode 100644
index 000000000..501ba96ee
--- /dev/null
+++ b/java/res/xml-iw/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="iw">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_hebrew" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-ky/keyboard_set.xml b/java/res/xml-ky/keyboard_set.xml
new file mode 100644
index 000000000..abd5f1631
--- /dev/null
+++ b/java/res/xml-ky/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="ky">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_slavic" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-land/kbd_number.xml b/java/res/xml-land/kbd_number.xml
index f5930ef41..7cc0fb274 100644
--- a/java/res/xml-land/kbd_number.xml
+++ b/java/res/xml-land/kbd_number.xml
@@ -24,5 +24,5 @@
latin:keyWidth="26.67%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_number" />
+ latin:keyboardLayout="@xml/rows_number" />
</Keyboard>
diff --git a/java/res/xml-land/kbd_phone.xml b/java/res/xml-land/kbd_phone.xml
index 3b1fb36ff..aa54b8390 100644
--- a/java/res/xml-land/kbd_phone.xml
+++ b/java/res/xml-land/kbd_phone.xml
@@ -24,5 +24,5 @@
latin:keyWidth="26.67%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_phone" />
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml-land/kbd_phone_shift.xml b/java/res/xml-land/kbd_phone_symbols.xml
index e59664776..41ba6cf3b 100644
--- a/java/res/xml-land/kbd_phone_shift.xml
+++ b/java/res/xml-land/kbd_phone_symbols.xml
@@ -24,5 +24,5 @@
latin:keyWidth="26.67%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_phone_shift" />
+ latin:keyboardLayout="@xml/rows_phone_symbols" />
</Keyboard>
diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml
deleted file mode 100644
index 1f4e86e89..000000000
--- a/java/res/xml-nb/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2010, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="nb"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
-</Keyboard>
diff --git a/java/res/xml-nb/keyboard_set.xml b/java/res/xml-nb/keyboard_set.xml
new file mode 100644
index 000000000..d146beb71
--- /dev/null
+++ b/java/res/xml-nb/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="nb">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_scandinavian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-pl/keyboard_set.xml b/java/res/xml-pl/keyboard_set.xml
new file mode 100644
index 000000000..6d2737929
--- /dev/null
+++ b/java/res/xml-pl/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="pl">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-pt/kbd_qwerty.xml b/java/res/xml-pt/kbd_qwerty.xml
deleted file mode 100644
index f5dcbc61b..000000000
--- a/java/res/xml-pt/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="pt"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_qwerty" />
-</Keyboard>
diff --git a/java/res/xml-pt/keyboard_set.xml b/java/res/xml-pt/keyboard_set.xml
new file mode 100644
index 000000000..65f9634ce
--- /dev/null
+++ b/java/res/xml-pt/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="pt">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-ro/keyboard_set.xml b/java/res/xml-ro/keyboard_set.xml
new file mode 100644
index 000000000..6c34966d0
--- /dev/null
+++ b/java/res/xml-ro/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="ro">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml
deleted file mode 100644
index aee1b1bfc..000000000
--- a/java/res/xml-ru/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="ru"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_russian" />
-</Keyboard>
diff --git a/java/res/xml-ru/keyboard_set.xml b/java/res/xml-ru/keyboard_set.xml
new file mode 100644
index 000000000..b6a356891
--- /dev/null
+++ b/java/res/xml-ru/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="ru">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_slavic" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-sk/keyboard_set.xml b/java/res/xml-sk/keyboard_set.xml
new file mode 100644
index 000000000..b283d968a
--- /dev/null
+++ b/java/res/xml-sk/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="sk">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-sl/keyboard_set.xml b/java/res/xml-sl/keyboard_set.xml
new file mode 100644
index 000000000..dbb2782f0
--- /dev/null
+++ b/java/res/xml-sl/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="sl">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml
deleted file mode 100644
index 58fc187c2..000000000
--- a/java/res/xml-sr/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="sr"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_serbian" />
-</Keyboard>
diff --git a/java/res/xml-sr/keyboard_set.xml b/java/res/xml-sr/keyboard_set.xml
new file mode 100644
index 000000000..15471dbcd
--- /dev/null
+++ b/java/res/xml-sr/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="sr">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_serbian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml
deleted file mode 100644
index e29d9abce..000000000
--- a/java/res/xml-sv/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="sv"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
-</Keyboard>
diff --git a/java/res/xml-sv/keyboard_set.xml b/java/res/xml-sv/keyboard_set.xml
new file mode 100644
index 000000000..e5184d33f
--- /dev/null
+++ b/java/res/xml-sv/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="sv">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_scandinavian" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-sw600dp-land/kbd_mini_keyboard_template.xml b/java/res/xml-sw600dp-land/kbd_more_keys_keyboard_template.xml
index 8272e02f0..4d8b446a2 100644
--- a/java/res/xml-sw600dp-land/kbd_mini_keyboard_template.xml
+++ b/java/res/xml-sw600dp-land/kbd_more_keys_keyboard_template.xml
@@ -21,6 +21,6 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="5%p"
latin:rowHeight="@dimen/popup_key_height"
- style="?attr/miniKeyboardStyle"
+ style="?attr/moreKeysKeyboardStyle"
>
</Keyboard>
diff --git a/java/res/xml-ar/kbd_symbols.xml b/java/res/xml-sw600dp-land/kbd_number.xml
index 9e5c255d0..9d358b678 100644
--- a/java/res/xml-ar/kbd_symbols.xml
+++ b/java/res/xml-sw600dp-land/kbd_number.xml
@@ -20,8 +20,9 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:isRtlKeyboard="true"
+ latin:keyboardHorizontalEdgesPadding="10%p"
+ latin:keyWidth="15.00%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_symbols" />
+ latin:keyboardLayout="@xml/rows_number" />
</Keyboard>
diff --git a/java/res/xml-ar/kbd_qwerty.xml b/java/res/xml-sw600dp-land/kbd_phone.xml
index b26a938cc..abac6bd4f 100644
--- a/java/res/xml-ar/kbd_qwerty.xml
+++ b/java/res/xml-sw600dp-land/kbd_phone.xml
@@ -20,9 +20,9 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="ar"
- latin:isRtlKeyboard="true"
+ latin:keyboardHorizontalEdgesPadding="10%p"
+ latin:keyWidth="15.00%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_arabic" />
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml-sw600dp-land/kbd_phone_symbols.xml b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
new file mode 100644
index 000000000..e3f56bce7
--- /dev/null
+++ b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardHorizontalEdgesPadding="10%p"
+ latin:keyWidth="15.00%p"
+>
+ <!-- Tablet doesn't have phone symbols keyboard -->
+ <include
+ latin:keyboardLayout="@xml/rows_phone" />
+</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_mini_keyboard_template.xml b/java/res/xml-sw600dp/kbd_more_keys_keyboard_template.xml
index 0d5795f6a..d90a5884e 100644
--- a/java/res/xml-sw600dp/kbd_mini_keyboard_template.xml
+++ b/java/res/xml-sw600dp/kbd_more_keys_keyboard_template.xml
@@ -21,6 +21,6 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="8%p"
latin:rowHeight="@dimen/popup_key_height"
- style="?attr/miniKeyboardStyle"
+ style="?attr/moreKeysKeyboardStyle"
>
</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_number.xml b/java/res/xml-sw600dp/kbd_number.xml
index 46114dedf..70cf6a2ca 100644
--- a/java/res/xml-sw600dp/kbd_number.xml
+++ b/java/res/xml-sw600dp/kbd_number.xml
@@ -20,190 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="16.75%p"
+ latin:keyWidth="15.00%p"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
- <include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
- <switch>
- <case
- latin:passwordInput="true"
- >
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="24.875%p" />
- <Key
- latin:keyStyle="num1KeyStyle" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.00%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="24.875%p" />
- <Key
- latin:keyStyle="num4KeyStyle" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.00%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="24.875%p" />
- <Key
- latin:keyStyle="num7KeyStyle" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="11.00%p" />
- <Spacer
- latin:keyXPos="24.875%p" />
- <Key
- latin:keyStyle="num0KeyStyle" />
- <Spacer
- latin:keyXPos="-11.00%p"
- latin:keyWidth="0%p" />
- <include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
- </Row>
- </case>
- <!-- latin:passwordInput="false" -->
- <default>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="11.00%p" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="+"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="1"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="38.75%p" />
- <Key
- latin:keyLabel="2"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="3"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.00%p"
- latin:keyWidth="fillBoth" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="11.00%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="/"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel=","
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="4"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="38.75%p" />
- <Key
- latin:keyLabel="5"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="6"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.00%p"
- latin:keyWidth="fillBoth" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="11.00%p" />
- <Key
- latin:keyLabel="("
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel=")"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="="
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="7"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="38.75%p" />
- <Key
- latin:keyLabel="8"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="9"
- latin:keyStyle="numKeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="11.00%p" />
- <Key
- latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
- latin:keyWidth="27.75%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="38.75%p" />
- <Key
- latin:keyLabel="0"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="#"
- latin:keyStyle="numKeyStyle" />
- <Spacer
- latin:keyXPos="-11.00%p"
- latin:keyWidth="0%p" />
- <include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
- </Row>
- </default>
- </switch>
+ latin:keyboardLayout="@xml/rows_number" />
</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_phone.xml b/java/res/xml-sw600dp/kbd_phone.xml
index 303f8145b..72acef21c 100644
--- a/java/res/xml-sw600dp/kbd_phone.xml
+++ b/java/res/xml-sw600dp/kbd_phone.xml
@@ -20,104 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="16.75%p"
+ latin:keyWidth="15.00%p"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
- <include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="15.625%p" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="+"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyStyle="num1KeyStyle"
- latin:keyXPos="38.867%p" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.00%p"
- latin:keyWidth="fillBoth" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="15.625%p" />
- <Key
- latin:keyLabel=","
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyStyle="num4KeyStyle"
- latin:keyXPos="38.867%p" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.00%p"
- latin:keyWidth="fillBoth" />
- </Row>
- <Row>
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="11.0%p" />
- <Key
- latin:keyLabel="("
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="15.625%p"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyLabel=")"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
- <Key
- latin:keyStyle="num7KeyStyle"
- latin:keyXPos="38.867%p" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="11.00%p" />
- <Key
- latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
- latin:keyXPos="15.625%p"
- latin:keyWidth="18.50%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="38.867%p" />
- <Key
- latin:keyStyle="num0KeyStyle" />
- <Key
- latin:keyLabel="#"
- latin:keyStyle="numKeyStyle" />
- <Spacer
- latin:keyXPos="-11.00%p"
- latin:keyWidth="0%p" />
- <include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
- </Row>
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_phone_symbols.xml b/java/res/xml-sw600dp/kbd_phone_symbols.xml
new file mode 100644
index 000000000..9faeaf4e0
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_phone_symbols.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyWidth="15.00%p"
+>
+ <!-- Tablet doesn't have phone symbols keyboard -->
+ <include
+ latin:keyboardLayout="@xml/rows_phone" />
+</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_f2.xml b/java/res/xml-sw600dp/key_f2.xml
index b25afc12f..b25afc12f 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_f2.xml
+++ b/java/res/xml-sw600dp/key_f2.xml
diff --git a/java/res/xml-sw600dp/kbd_row3_smiley.xml b/java/res/xml-sw600dp/key_smiley.xml
index f9b647cdf..3430d7898 100644
--- a/java/res/xml-sw600dp/kbd_row3_smiley.xml
+++ b/java/res/xml-sw600dp/key_smiley.xml
@@ -26,37 +26,29 @@
latin:mode="email"
>
<Key
- latin:keyLabel="\@"
- latin:keyXPos="-8.9%p"
- latin:keyWidth="fillBoth" />
+ latin:keyLabel="\@" />
</case>
<case
latin:mode="url"
>
<Key
latin:keyLabel="-"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="_"
latin:moreKeys="_"
- latin:keyXPos="-8.9%p"
- latin:keyWidth="fillBoth" />
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</case>
<case
latin:imeAction="actionSearch"
>
<Key
latin:keyLabel=":"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="+"
latin:moreKeys="+"
- latin:keyXPos="-8.9%p"
- latin:keyWidth="fillBoth" />
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</case>
<default>
<Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyXPos="-8.9%p"
- latin:keyWidth="fillBoth" />
+ latin:keyStyle="smileyKeyStyle" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/key_styles_common.xml
index 25fa8b265..e524aa381 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -33,51 +33,92 @@
<default>
<key-style
latin:styleName="f2PopupStyle"
- latin:keyLabelOption="hasPopupHint"
- latin:moreKeys="\@icon/3|\@integer/key_settings"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="\@icon/settingsKey|\@integer/key_settings"
latin:backgroundType="functional" />
</default>
</switch>
+ <switch>
+ <case
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="hasShiftedLetterHintStyle"
+ latin:keyLabelFlags="hasShiftedLetterHint|shiftedLetterActivated" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="hasShiftedLetterHintStyle"
+ latin:keyLabelFlags="hasShiftedLetterHint" />
+ </default>
+ </switch>
<!-- Functional key styles -->
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="iconShiftKey"
- latin:keyIconShifted="iconShiftedShiftKey"
- latin:backgroundType="sticky" />
+ <switch>
+ <case
+ latin:keyboardSetElement="alphabetManualShifted|alphabetAutomaticShifted"
+ >
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKeyShifted"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOff" />
+ </case>
+ <case
+ latin:keyboardSetElement="alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKeyShifted"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOn" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKey"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOff" />
+ </default>
+ </switch>
<key-style
latin:styleName="deleteKeyStyle"
latin:code="@integer/key_delete"
latin:keyIcon="iconDeleteKey"
- latin:backgroundType="functional"
- latin:isRepeatable="true" />
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="iconReturnKey"
+ latin:keyActionFlags="isRepeatable|noKeyPreview"
latin:backgroundType="functional" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_enter_tablet" />
<key-style
latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space" />
+ latin:code="@integer/key_space"
+ latin:keyActionFlags="noKeyPreview" />
<key-style
latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
- latin:code="@integer/key_space" />
+ latin:code="@integer/key_space"
+ latin:keyActionFlags="noKeyPreview" />
<key-style
latin:styleName="smileyKeyStyle"
latin:keyLabel=":-)"
latin:keyOutputText=":-) "
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
latin:moreKeys="@string/more_keys_for_smiley"
latin:maxMoreKeysColumn="5" />
<key-style
latin:styleName="shortcutKeyStyle"
latin:code="@integer/key_shortcut"
latin:keyIcon="iconShortcutKey"
+ latin:keyIconDisabled="iconDisabledShortcutKey"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
latin:parentStyle="f2PopupStyle" />
<key-style
latin:styleName="settingsKeyStyle"
latin:code="@integer/key_settings"
latin:keyIcon="iconSettingsKey"
+ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
latin:backgroundType="functional" />
<key-style
latin:styleName="tabKeyStyle"
@@ -89,26 +130,34 @@
latin:styleName="toSymbolKeyStyle"
latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_symbol_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="toAlphaKeyStyle"
latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_alpha_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="toMoreSymbolKeyStyle"
latin:code="@integer/key_shift"
latin:keyLabel="@string/label_to_more_symbol_for_tablet_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="backFromMoreSymbolKeyStyle"
latin:code="@integer/key_shift"
latin:keyLabel="@string/label_to_symbol_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="comKeyStyle"
latin:keyLabel="@string/keylabel_for_popular_domain"
- latin:keyLabelOption="fontNormal|hasPopupHint"
+ latin:keyLabelFlags="fontNormal|hasPopupHint|preserveCase"
latin:keyOutputText="@string/keylabel_for_popular_domain"
latin:moreKeys="@string/more_keys_for_popular_domain" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_row4_apostrophe_dash.xml b/java/res/xml-sw600dp/keys_apostrophe_dash.xml
index 9536e81da..a53c1e4ab 100644
--- a/java/res/xml-sw768dp/kbd_row4_apostrophe_dash.xml
+++ b/java/res/xml-sw600dp/keys_apostrophe_dash.xml
@@ -33,16 +33,16 @@
>
<Key
latin:keyLabel="/"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel=":"
- latin:moreKeys=":" />
+ latin:moreKeys=":"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</case>
<default>
<Key
latin:keyLabel="@string/keylabel_for_apostrophe"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="@string/keyhintlabel_for_apostrophe"
- latin:moreKeys="@string/more_keys_for_apostrophe" />
+ latin:moreKeys="@string/more_keys_for_apostrophe"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
<switch>
@@ -55,9 +55,9 @@
<default>
<Key
latin:keyLabel="@string/keylabel_for_dash"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="@string/keyhintlabel_for_dash"
- latin:moreKeys="@string/more_keys_for_dash" />
+ latin:moreKeys="@string/more_keys_for_dash"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row1.xml b/java/res/xml-sw600dp/row_qwerty1.xml
index 07d8e2296..3d3a1a8ff 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row1.xml
+++ b/java/res/xml-sw600dp/row_qwerty1.xml
@@ -25,11 +25,9 @@
latin:keyWidth="9.0%p"
>
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="e"
latin:moreKeys="@string/more_keys_for_e" />
@@ -52,8 +50,7 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row2.xml b/java/res/xml-sw600dp/row_qwerty2.xml
index 52a948f20..cabb9cb4a 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row2.xml
+++ b/java/res/xml-sw600dp/row_qwerty2.xml
@@ -50,7 +50,7 @@
latin:keyLabel="l"
latin:moreKeys="@string/more_keys_for_l" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row3.xml b/java/res/xml-sw600dp/row_qwerty3.xml
index 4dabf633c..3d19904a1 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw600dp/row_qwerty3.xml
@@ -46,8 +46,10 @@
<Key
latin:keyLabel="m" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<include
- latin:keyboardLayout="@xml/kbd_row3_smiley" />
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillBoth" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row4.xml b/java/res/xml-sw600dp/row_qwerty4.xml
index ef0292279..b06508e37 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw600dp/row_qwerty4.xml
@@ -45,9 +45,9 @@
<default>
<Key
latin:keyLabel="/"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="\@"
- latin:moreKeys="\@" />
+ latin:moreKeys="\@"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
<Key
@@ -59,18 +59,18 @@
latin:languageCode="iw"
>
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
</case>
<!-- not languageCode="iw" -->
<default>
<include
- latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
+ latin:keyboardLayout="@xml/keys_apostrophe_dash" />
</default>
</switch>
<Spacer
latin:keyXPos="-10.00%p"
latin:keyWidth="0%p" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
+ latin:keyboardLayout="@xml/key_f2" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_arabic.xml b/java/res/xml-sw600dp/rows_arabic.xml
index c2d3cd4cc..1f03968ee 100644
--- a/java/res/xml-sw600dp/kbd_rows_arabic.xml
+++ b/java/res/xml-sw600dp/rows_arabic.xml
@@ -22,7 +22,7 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="8.0%p"
>
@@ -138,44 +138,15 @@
<Key
latin:keyLabel="ط" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
<Row
latin:keyWidth="8.0%p"
>
- <!-- kbd_row3_smiley -->
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="\@" />
- </case>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyLabel="-"
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="_"
- latin:moreKeys="_" />
- </case>
- <case
- latin:imeAction="actionSearch"
- >
- <Key
- latin:keyLabel=":"
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="+"
- latin:moreKeys="+" />
- </case>
- <default>
- <Key
- latin:keyStyle="smileyKeyStyle" />
- </default>
- </switch>
+ <include
+ latin:keyboardLayout="@xml/key_smiley" />
<!-- \u0626: ARABIC LETTER YEH WITH HAMZA ABOVE -->
<Key
latin:keyLabel="ئ" />
@@ -213,5 +184,5 @@
latin:keyLabel="د" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_azerty.xml b/java/res/xml-sw600dp/rows_azerty.xml
index 8ae74557c..5c799623d 100644
--- a/java/res/xml-sw600dp/kbd_rows_azerty.xml
+++ b/java/res/xml-sw600dp/rows_azerty.xml
@@ -22,7 +22,7 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="8.5%p"
>
@@ -54,8 +54,7 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
@@ -66,7 +65,6 @@
>
<Key
latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q"
latin:keyXPos="5.0%p" />
<Key
latin:keyLabel="s"
@@ -92,7 +90,7 @@
<Key
latin:keyLabel="m" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -103,8 +101,7 @@
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="10.0%p" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="x" />
<Key
@@ -119,32 +116,17 @@
latin:keyLabel="n"
latin:moreKeys="@string/more_keys_for_n" />
<Key
- latin:keyLabel="\'" />
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="!"
- latin:moreKeys="!" />
- <Key
- latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
- </default>
- </switch>
+ latin:keyLabel="\'"
+ latin:keyHintLabel=":"
+ latin:moreKeys=":"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<include
- latin:keyboardLayout="@xml/kbd_row3_smiley" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
+ <include
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/rows_bulgarian.xml b/java/res/xml-sw600dp/rows_bulgarian.xml
new file mode 100644
index 000000000..7a23ce9ff
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_bulgarian.xml
@@ -0,0 +1,117 @@
+<?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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="7.692%p"
+ >
+ <Key
+ latin:keyLabel="ч" />
+ <Key
+ latin:keyLabel="ш" />
+ <Key
+ latin:keyLabel="е" />
+ <Key
+ latin:keyLabel="р" />
+ <Key
+ latin:keyLabel="т" />
+ <Key
+ latin:keyLabel="ъ" />
+ <Key
+ latin:keyLabel="у" />
+ <Key
+ latin:keyLabel="и"
+ latin:moreKeys="ѝ" />
+ <Key
+ latin:keyLabel="о" />
+ <Key
+ latin:keyLabel="п" />
+ <Key
+ latin:keyLabel="я" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="7.692%p"
+ >
+ <Key
+ latin:keyLabel="а"
+ latin:keyXPos="4.000%p" />
+ <Key
+ latin:keyLabel="с" />
+ <Key
+ latin:keyLabel="д" />
+ <Key
+ latin:keyLabel="ф" />
+ <Key
+ latin:keyLabel="г" />
+ <Key
+ latin:keyLabel="х" />
+ <Key
+ latin:keyLabel="й" />
+ <Key
+ latin:keyLabel="к" />
+ <Key
+ latin:keyLabel="л" />
+ <Key
+ latin:keyLabel="щ" />
+ <Key
+ latin:keyLabel="ь" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="7.692%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.000%p" />
+ <Key
+ latin:keyLabel="з" />
+ <Key
+ latin:keyLabel="ж" />
+ <Key
+ latin:keyLabel="ц" />
+ <Key
+ latin:keyLabel="в" />
+ <Key
+ latin:keyLabel="б" />
+ <Key
+ latin:keyLabel="н" />
+ <Key
+ latin:keyLabel="м" />
+ <Key
+ latin:keyLabel="ю" />
+ <include
+ latin:keyboardLayout="@xml/keys_comma_period" />
+ <include
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_hebrew.xml b/java/res/xml-sw600dp/rows_hebrew.xml
index a8adbd34c..812e2d6e0 100644
--- a/java/res/xml-sw600dp/kbd_rows_hebrew.xml
+++ b/java/res/xml-sw600dp/rows_hebrew.xml
@@ -22,12 +22,12 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="9.0%p"
>
<include
- latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
+ latin:keyboardLayout="@xml/keys_apostrophe_dash" />
<Key
latin:keyLabel="ק" />
<Key
@@ -80,41 +80,9 @@
<Row
latin:keyWidth="8.9%p"
>
- <!-- kbd_row3_smiley -->
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="\@"
- latin:keyWidth="10.0%p" />
- </case>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyLabel="-"
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="_"
- latin:moreKeys="_"
- latin:keyWidth="10.0%p" />
- </case>
- <case
- latin:imeAction="actionSearch"
- >
- <Key
- latin:keyLabel=":"
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="+"
- latin:moreKeys="+"
- latin:keyWidth="10.0%p" />
- </case>
- <default>
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="10.0%p" />
- </default>
- </switch>
+ <include
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyWidth="10.0%p" />
<Key
latin:keyLabel="ז"
latin:moreKeys="ז׳" />
@@ -138,10 +106,10 @@
latin:keyLabel="ץ"
latin:moreKeys="ץ׳" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-10.400%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/rows_number_normal.xml b/java/res/xml-sw600dp/rows_number_normal.xml
new file mode 100644
index 000000000..3141bbdc7
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_number_normal.xml
@@ -0,0 +1,138 @@
+<?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"
+>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="12.75%p" />
+ <Key
+ latin:keyLabel="-"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="1"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="42.25%p" />
+ <Key
+ latin:keyLabel="2"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="3"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="12.75%p" />
+ <Key
+ latin:keyStyle="numStarKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="/"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="4"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="42.25%p" />
+ <Key
+ latin:keyLabel="5"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="6"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="12.75%p" />
+ <Key
+ latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="="
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="9.25%p" />
+ <Key
+ latin:keyLabel="7"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="42.25%p" />
+ <Key
+ latin:keyLabel="8"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="9"
+ latin:keyStyle="numKeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="0%p" />
+ </Row>
+ <Row>
+ <Key
+ latin:keyStyle="numTabKeyStyle"
+ latin:keyWidth="11.00%p" />
+ <Key
+ latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
+ latin:keyWidth="27.75%p"
+ latin:keyXPos="12.75%p" />
+ <Key
+ latin:keyStyle="numStarKeyStyle"
+ latin:keyXPos="42.25%p" />
+ <Key
+ latin:keyLabel="0"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
+ <Spacer
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="0%p" />
+ <include
+ latin:keyboardLayout="@xml/key_f2" />
+ </Row>
+</merge>
diff --git a/java/res/xml-sw600dp/rows_number_password.xml b/java/res/xml-sw600dp/rows_number_password.xml
new file mode 100644
index 000000000..0a71f74d7
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_number_password.xml
@@ -0,0 +1,81 @@
+<?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"
+>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="27.50%p" />
+ <Key
+ latin:keyStyle="num1KeyStyle" />
+ <Key
+ latin:keyStyle="num2KeyStyle" />
+ <Key
+ latin:keyStyle="num3KeyStyle" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="27.50%p" />
+ <Key
+ latin:keyStyle="num4KeyStyle" />
+ <Key
+ latin:keyStyle="num5KeyStyle" />
+ <Key
+ latin:keyStyle="num6KeyStyle" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="27.50%p" />
+ <Key
+ latin:keyStyle="num7KeyStyle" />
+ <Key
+ latin:keyStyle="num8KeyStyle" />
+ <Key
+ latin:keyStyle="num9KeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="0%p" />
+ </Row>
+ <Row>
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyWidth="11.00%p" />
+ <Key
+ latin:keyStyle="num0KeyStyle"
+ latin:keyXPos="42.50%p"/>
+ <Spacer
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="0%p" />
+ <include
+ latin:keyboardLayout="@xml/key_f2" />
+ </Row>
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_phone_shift.xml b/java/res/xml-sw600dp/rows_phone.xml
index 4c4f8ad12..d61b4b2ad 100644
--- a/java/res/xml-sw600dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw600dp/rows_phone.xml
@@ -18,18 +18,17 @@
*/
-->
-<Keyboard
+<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="16.75%p"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
+ latin:keyboardLayout="@xml/key_styles_number" />
<Row>
<!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
<Spacer
- latin:keyWidth="11.00%p" />
+ latin:keyWidth="12.75%p" />
<Key
latin:keyLabel="-"
latin:keyStyle="numKeyStyle"
@@ -39,13 +38,11 @@
latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
- latin:code="44"
- latin:keyLabel="@string/label_pause_key"
- latin:keyLabelOption="followKeyHintLabelRatio|autoXScale"
+ latin:keyStyle="numPauseKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num1KeyStyle"
- latin:keyXPos="38.867%p" />
+ latin:keyXPos="42.25%p" />
<Key
latin:keyStyle="num2KeyStyle" />
<Key
@@ -53,12 +50,12 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="fillBoth" />
+ latin:keyWidth="fillRight" />
</Row>
<Row>
<!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
<Spacer
- latin:keyWidth="11.00%p" />
+ latin:keyWidth="12.75%p" />
<Key
latin:keyLabel=","
latin:keyStyle="numKeyStyle"
@@ -68,30 +65,29 @@
latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
- latin:code="59"
- latin:keyLabel="@string/label_wait_key"
- latin:keyLabelOption="followKeyHintLabelRatio|autoXScale"
+ latin:keyStyle="numWaitKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num4KeyStyle"
- latin:keyXPos="38.867%p" />
+ latin:keyXPos="42.25%p" />
<Key
latin:keyStyle="num5KeyStyle" />
<Key
latin:keyStyle="num6KeyStyle" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="fillBoth" />
+ latin:keyWidth="fillRight" />
</Row>
<Row>
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="11.00%p" />
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="12.75%p" />
<Key
latin:keyLabel="("
latin:keyStyle="numKeyStyle"
- latin:keyWidth="9.25%p" />
+ latin:keyWidth="9.25%p"
+ latin:keyXPos="12.75%p" />
<Key
latin:keyLabel=")"
latin:keyStyle="numKeyStyle"
@@ -102,7 +98,7 @@
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num7KeyStyle"
- latin:keyXPos="38.867%p" />
+ latin:keyXPos="42.25%p" />
<Key
latin:keyStyle="num8KeyStyle" />
<Key
@@ -113,14 +109,15 @@
</Row>
<Row>
<Key
- latin:keyStyle="tabKeyStyle"
+ latin:keyStyle="numTabKeyStyle"
latin:keyWidth="11.00%p" />
<Key
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
- latin:keyWidth="27.75%p" />
+ latin:keyWidth="27.75%p"
+ latin:keyXPos="12.75%p" />
<Key
latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="38.867%p" />
+ latin:keyXPos="42.25%p" />
<Key
latin:keyStyle="num0KeyStyle" />
<Key
@@ -130,6 +127,6 @@
latin:keyXPos="-11.00%p"
latin:keyWidth="0%p" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
+ latin:keyboardLayout="@xml/key_f2" />
</Row>
-</Keyboard>
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_qwerty.xml b/java/res/xml-sw600dp/rows_qwerty.xml
index a2d26b3de..eb41c5087 100644
--- a/java/res/xml-sw600dp/kbd_rows_qwerty.xml
+++ b/java/res/xml-sw600dp/rows_qwerty.xml
@@ -22,13 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row1" />
+ latin:keyboardLayout="@xml/row_qwerty1" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row2" />
+ latin:keyboardLayout="@xml/row_qwerty2" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_qwertz.xml b/java/res/xml-sw600dp/rows_qwertz.xml
index 98667e09c..6912f1c6d 100644
--- a/java/res/xml-sw600dp/kbd_rows_qwertz.xml
+++ b/java/res/xml-sw600dp/rows_qwertz.xml
@@ -22,16 +22,14 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="9.0%p"
>
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="e"
latin:moreKeys="@string/more_keys_for_e" />
@@ -54,15 +52,14 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row2" />
+ latin:keyboardLayout="@xml/row_qwerty2" />
<Row
latin:keyWidth="8.9%p"
>
@@ -87,31 +84,13 @@
latin:moreKeys="@string/more_keys_for_n" />
<Key
latin:keyLabel="m" />
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="!"
- latin:moreKeys="!" />
- <Key
- latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
- </default>
- </switch>
<include
- latin:keyboardLayout="@xml/kbd_row3_smiley" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
+ <include
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_scandinavian.xml b/java/res/xml-sw600dp/rows_scandinavian.xml
index 19fb5212b..912c40658 100644
--- a/java/res/xml-sw600dp/kbd_rows_scandinavian.xml
+++ b/java/res/xml-sw600dp/rows_scandinavian.xml
@@ -22,16 +22,14 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="7.9%p"
>
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="e"
latin:moreKeys="@string/more_keys_for_e" />
@@ -54,10 +52,9 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
- latin:keyLabel="å" />
+ latin:keyLabel="@string/keylabel_for_scandinavia_row1_11" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
@@ -98,7 +95,7 @@
latin:keyLabel="@string/keylabel_for_scandinavia_row2_11"
latin:moreKeys="@string/more_keys_for_scandinavia_row2_11" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -129,12 +126,12 @@
<Key
latin:keyLabel="m" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
- <Spacer
- latin:keyWidth="4.35%p" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<include
- latin:keyboardLayout="@xml/kbd_row3_smiley" />
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_serbian.xml b/java/res/xml-sw600dp/rows_serbian.xml
index db7560cdc..ea4bb1466 100644
--- a/java/res/xml-sw600dp/kbd_rows_serbian.xml
+++ b/java/res/xml-sw600dp/rows_serbian.xml
@@ -22,7 +22,7 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="8.0%p"
>
@@ -80,7 +80,7 @@
<Key
latin:keyLabel="ћ" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -109,10 +109,12 @@
<Key
latin:keyLabel="ж" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<include
- latin:keyboardLayout="@xml/kbd_row3_smiley" />
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_russian.xml b/java/res/xml-sw600dp/rows_slavic.xml
index cc9ad3aa7..020ea16a2 100644
--- a/java/res/xml-sw600dp/kbd_rows_russian.xml
+++ b/java/res/xml-sw600dp/rows_slavic.xml
@@ -22,7 +22,7 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="7.60%p"
>
@@ -31,20 +31,22 @@
<Key
latin:keyLabel="ц" />
<Key
- latin:keyLabel="у" />
+ latin:keyLabel="у"
+ latin:moreKeys="@string/more_keys_for_slavic_u" />
<Key
latin:keyLabel="к" />
<Key
latin:keyLabel="е"
- latin:moreKeys="@string/more_keys_for_cyrillic_e" />
+ latin:moreKeys="@string/more_keys_for_slavic_ye" />
<Key
- latin:keyLabel="н" />
+ latin:keyLabel="н"
+ latin:moreKeys="@string/more_keys_for_slavic_en" />
<Key
latin:keyLabel="г" />
<Key
latin:keyLabel="ш" />
<Key
- latin:keyLabel="щ" />
+ latin:keyLabel="@string/keylabel_for_slavic_shcha" />
<Key
latin:keyLabel="з" />
<Key
@@ -63,7 +65,8 @@
latin:keyLabel="ф"
latin:keyXPos="2.25%p" />
<Key
- latin:keyLabel="ы" />
+ latin:keyLabel="@string/keylabel_for_slavic_yery"
+ latin:moreKeys="@string/more_keys_for_slavic_yery" />
<Key
latin:keyLabel="в" />
<Key
@@ -73,7 +76,8 @@
<Key
latin:keyLabel="р" />
<Key
- latin:keyLabel="о" />
+ latin:keyLabel="о"
+ latin:moreKeys="@string/more_keys_for_slavic_o" />
<Key
latin:keyLabel="л" />
<Key
@@ -83,7 +87,7 @@
<Key
latin:keyLabel="э" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -101,7 +105,7 @@
<Key
latin:keyLabel="м" />
<Key
- latin:keyLabel="и" />
+ latin:keyLabel="@string/keylabel_for_slavic_i" />
<Key
latin:keyLabel="т" />
<Key
@@ -110,31 +114,13 @@
latin:keyLabel="б" />
<Key
latin:keyLabel="ю" />
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="!"
- latin:moreKeys="!" />
- <Key
- latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
- </default>
- </switch>
<include
- latin:keyboardLayout="@xml/kbd_row3_smiley" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
+ <include
+ latin:keyboardLayout="@xml/key_smiley"
+ latin:keyXPos="-8.9%p"
+ latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_spanish.xml b/java/res/xml-sw600dp/rows_spanish.xml
index 8506af697..2ab94e8c5 100644
--- a/java/res/xml-sw600dp/kbd_rows_spanish.xml
+++ b/java/res/xml-sw600dp/rows_spanish.xml
@@ -22,9 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row1" />
+ latin:keyboardLayout="@xml/row_qwerty1" />
<Row
latin:keyWidth="8.5%p"
>
@@ -56,12 +56,12 @@
<Key
latin:keyLabel="ñ" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_symbols.xml b/java/res/xml-sw600dp/rows_symbols.xml
index bb48fe734..ce6e539a5 100644
--- a/java/res/xml-sw600dp/kbd_rows_symbols.xml
+++ b/java/res/xml-sw600dp/rows_symbols.xml
@@ -22,41 +22,51 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_currency_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency" />
<Row
latin:keyWidth="9.0%p"
>
<Key
latin:keyLabel="@string/keylabel_for_symbols_1"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_1"
latin:moreKeys="@string/more_keys_for_symbols_1" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_2"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_2"
latin:moreKeys="@string/more_keys_for_symbols_2" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_3"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_3"
latin:moreKeys="@string/more_keys_for_symbols_3" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_4"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_4"
latin:moreKeys="@string/more_keys_for_symbols_4" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_5"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_5"
latin:moreKeys="@string/more_keys_for_symbols_5" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_6"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_6"
latin:moreKeys="@string/more_keys_for_symbols_6" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_7"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_7"
latin:moreKeys="@string/more_keys_for_symbols_7" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_8"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_8"
latin:moreKeys="@string/more_keys_for_symbols_8" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_9"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_9"
latin:moreKeys="@string/more_keys_for_symbols_9" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_0"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_0"
latin:moreKeys="@string/more_keys_for_symbols_0" />
<Key
latin:keyStyle="deleteKeyStyle"
@@ -85,14 +95,10 @@
<Key
latin:keyLabel="+"
latin:moreKeys="@string/more_keys_for_plus" />
+ <include
+ latin:keyboardLayout="@xml/keys_parentheses" />
<Key
- latin:keyLabel="("
- latin:moreKeys="[,{,&lt;" />
- <Key
- latin:keyLabel=")"
- latin:moreKeys="],},&gt;" />
- <Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -102,12 +108,8 @@
<Key
latin:keyStyle="toMoreSymbolKeyStyle"
latin:keyWidth="10.0%p" />
- <Key
- latin:keyLabel="&lt;"
- latin:moreKeys="≤,«,‹" />
- <Key
- latin:keyLabel="&gt;"
- latin:moreKeys="≥,»,›" />
+ <include
+ latin:keyboardLayout="@xml/keys_less_greater" />
<Key
latin:keyLabel="="
latin:moreKeys="≠,≈" />
@@ -116,8 +118,7 @@
latin:mode="url"
>
<Key
- latin:keyLabel="\'"
- latin:moreKeys="‘,’,‚,‛" />
+ latin:keyLabel="\'" />
</case>
<default>
<Key
@@ -156,17 +157,16 @@
latin:keyStyle="spaceKeyStyle"
latin:keyXPos="30.750%p"
latin:keyWidth="39.750%p" />
- <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
- <!-- latin:moreKeys="“,”,„,‟,«,»,‘,’,‚,‛" -->
<Key
latin:keyLabel="&quot;"
- latin:moreKeys="“,”,«,»,‘,’,‚,‛" />
+ latin:moreKeys="@string/more_keys_for_tablet_double_quote"
+ latin:maxMoreKeysColumn="4" />
<Key
latin:keyLabel="_" />
<Spacer
latin:keyXPos="-10.00%p"
latin:keyWidth="0%p" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
+ latin:keyboardLayout="@xml/key_f2" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_symbols_shift.xml b/java/res/xml-sw600dp/rows_symbols_shift.xml
index 8e4751502..a10d1740c 100644
--- a/java/res/xml-sw600dp/kbd_rows_symbols_shift.xml
+++ b/java/res/xml-sw600dp/rows_symbols_shift.xml
@@ -22,9 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_currency_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency" />
<Row
latin:keyWidth="9.0%p"
>
@@ -77,12 +77,10 @@
<Key
latin:keyLabel="±"
latin:moreKeys="∞" />
+ <include
+ latin:keyboardLayout="@xml/keys_curly_brackets" />
<Key
- latin:keyLabel="{" />
- <Key
- latin:keyLabel="}" />
- <Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-14.6%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -102,10 +100,8 @@
latin:keyLabel="™" />
<Key
latin:keyLabel="℅" />
- <Key
- latin:keyLabel="[" />
- <Key
- latin:keyLabel="]" />
+ <include
+ latin:keyboardLayout="@xml/keys_square_brackets" />
<Key
latin:keyLabel="¡" />
<Key
@@ -127,6 +123,6 @@
latin:keyXPos="-10.00%p"
latin:keyWidth="0%p" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f2" />
+ latin:keyboardLayout="@xml/key_f2" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp-land/kbd_mini_keyboard_template.xml b/java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml
index 85e864a6c..f593fa944 100644
--- a/java/res/xml-sw768dp-land/kbd_mini_keyboard_template.xml
+++ b/java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml
@@ -21,6 +21,6 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="3.5%p"
latin:rowHeight="@dimen/popup_key_height"
- style="?attr/miniKeyboardStyle"
+ style="?attr/moreKeysKeyboardStyle"
>
</Keyboard>
diff --git a/java/res/xml-sw768dp-land/kbd_number.xml b/java/res/xml-sw768dp-land/kbd_number.xml
new file mode 100644
index 000000000..3ad25a392
--- /dev/null
+++ b/java/res/xml-sw768dp-land/kbd_number.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardHorizontalEdgesPadding="10%p"
+ latin:keyWidth="13.250%p"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_number" />
+</Keyboard>
diff --git a/java/res/xml-ar/kbd_symbols_shift.xml b/java/res/xml-sw768dp-land/kbd_phone.xml
index 934e6f849..abe7e7c41 100644
--- a/java/res/xml-ar/kbd_symbols_shift.xml
+++ b/java/res/xml-sw768dp-land/kbd_phone.xml
@@ -20,8 +20,9 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:isRtlKeyboard="true"
+ latin:keyboardHorizontalEdgesPadding="10%p"
+ latin:keyWidth="13.250%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_symbols_shift" />
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml-sw768dp-land/kbd_phone_symbols.xml b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
new file mode 100644
index 000000000..641464dbe
--- /dev/null
+++ b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardHorizontalEdgesPadding="10%p"
+ latin:keyWidth="13.250%p"
+>
+ <!-- Tablet doesn't have phone symbols keyboard -->
+ <include
+ latin:keyboardLayout="@xml/rows_phone" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_mini_keyboard_template.xml b/java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml
index 409c60556..f89a0a673 100644
--- a/java/res/xml-sw768dp/kbd_mini_keyboard_template.xml
+++ b/java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml
@@ -21,6 +21,6 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="5.0%p"
latin:rowHeight="@dimen/popup_key_height"
- style="?attr/miniKeyboardStyle"
+ style="?attr/moreKeysKeyboardStyle"
>
</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_number.xml b/java/res/xml-sw768dp/kbd_number.xml
index 369e91a77..b20123c80 100644
--- a/java/res/xml-sw768dp/kbd_number.xml
+++ b/java/res/xml-sw768dp/kbd_number.xml
@@ -23,206 +23,5 @@
latin:keyWidth="13.250%p"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
- <include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
- <switch>
- <case
- latin:passwordInput="true"
- >
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyStyle="num1KeyStyle"
- latin:keyXPos="32.076%p" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="32.076%p" />
- <Key
- latin:keyStyle="num4KeyStyle" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="32.076%p" />
- <Key
- latin:keyStyle="num7KeyStyle" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- <Row>
- <Spacer
- latin:keyXPos="32.076%p" />
- <Key
- latin:keyStyle="num0KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- </case>
- <!-- latin:passwordInput="false" -->
- <default>
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="+"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="1"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="2"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="3"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="/"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel=","
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="4"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="5"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="6"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyLabel="("
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel=")"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="="
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="7"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="8"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="9"
- latin:keyStyle="numKeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- <Row>
- <switch>
- <case latin:hasSettingsKey="true">
- <Key
- latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="8.047%p" />
- </case>
- <default>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
- </switch>
- <Key
- latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="24.140%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="0"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="#"
- latin:keyStyle="numKeyStyle" />
- <switch>
- <case
- latin:shortcutKeyEnabled="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle"
- latin:keyXPos="-8.047%p"
- latin:keyWidth="fillRight" />
- </case>
- <default>
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </default>
- </switch>
- </Row>
- </default>
- </switch>
+ latin:keyboardLayout="@xml/rows_number" />
</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_phone.xml b/java/res/xml-sw768dp/kbd_phone.xml
index e55b1841a..fa9bf1bf4 100644
--- a/java/res/xml-sw768dp/kbd_phone.xml
+++ b/java/res/xml-sw768dp/kbd_phone.xml
@@ -23,122 +23,5 @@
latin:keyWidth="13.250%p"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
- <include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="20.400%p"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="+"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyStyle="num1KeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyLabel=","
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="20.400%p"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyStyle="num4KeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="20.400%p" />
- <Key
- latin:keyLabel="("
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyLabel=")"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyStyle="num7KeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </Row>
- <Row>
- <switch>
- <case latin:hasSettingsKey="true">
- <Key
- latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="8.047%p" />
- </case>
- <default>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
- </switch>
- <Key
- latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
- latin:keyXPos="20.400%p"
- latin:keyWidth="16.084%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num0KeyStyle" />
- <Key
- latin:keyLabel="#"
- latin:keyStyle="numKeyStyle" />
- <switch>
- <case
- latin:shortcutKeyEnabled="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle"
- latin:keyXPos="-8.047%p"
- latin:keyWidth="fillRight" />
- </case>
- <default>
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="0%p" />
- </default>
- </switch>
- </Row>
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml
index 37a50fdfd..e1a359e84 100644
--- a/java/res/xml-da/kbd_qwerty.xml
+++ b/java/res/xml-sw768dp/kbd_phone_symbols.xml
@@ -20,8 +20,9 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="da"
+ latin:keyWidth="13.250%p"
>
+ <!-- Tablet doesn't have phone symbols keyboard -->
<include
- latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_row3_comma_period.xml b/java/res/xml-sw768dp/kbd_row3_comma_period.xml
deleted file mode 100644
index b84443078..000000000
--- a/java/res/xml-sw768dp/kbd_row3_comma_period.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="!"
- latin:moreKeys="!" />
- <Key
- latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml-sw768dp/kbd_key_styles.xml b/java/res/xml-sw768dp/key_styles_common.xml
index f16f5b6af..07bdd7b18 100644
--- a/java/res/xml-sw768dp/kbd_key_styles.xml
+++ b/java/res/xml-sw768dp/key_styles_common.xml
@@ -21,80 +21,125 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="iconShiftKey"
- latin:keyIconShifted="iconShiftedShiftKey"
- latin:backgroundType="sticky" />
+ <switch>
+ <case
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="hasShiftedLetterHintStyle"
+ latin:keyLabelFlags="hasShiftedLetterHint|shiftedLetterActivated" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="hasShiftedLetterHintStyle"
+ latin:keyLabelFlags="hasShiftedLetterHint" />
+ </default>
+ </switch>
+ <switch>
+ <case
+ latin:keyboardSetElement="alphabetManualShifted|alphabetAutomaticShifted"
+ >
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKeyShifted"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOff" />
+ </case>
+ <case
+ latin:keyboardSetElement="alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKeyShifted"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOn" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKey"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOff" />
+ </default>
+ </switch>
<key-style
latin:styleName="deleteKeyStyle"
latin:code="@integer/key_delete"
latin:keyIcon="iconDeleteKey"
- latin:backgroundType="functional"
- latin:isRepeatable="true" />
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="iconReturnKey"
+ latin:keyActionFlags="isRepeatable|noKeyPreview"
latin:backgroundType="functional" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_enter_tablet" />
<key-style
latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space" />
+ latin:code="@integer/key_space"
+ latin:keyActionFlags="noKeyPreview" />
<key-style
latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
- latin:code="@integer/key_space" />
+ latin:code="@integer/key_space"
+ latin:keyActionFlags="noKeyPreview" />
<key-style
latin:styleName="smileyKeyStyle"
latin:keyLabel=":-)"
latin:keyOutputText=":-) "
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
latin:moreKeys="@string/more_keys_for_smiley"
latin:maxMoreKeysColumn="5" />
<key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="iconSettingsKey"
- latin:backgroundType="functional" />
- <key-style
latin:styleName="shortcutKeyStyle"
latin:code="@integer/key_shortcut"
latin:keyIcon="iconShortcutKey"
+ latin:keyIconDisabled="iconDisabledShortcutKey"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
+ latin:backgroundType="functional" />
+ <key-style
+ latin:styleName="settingsKeyStyle"
+ latin:code="@integer/key_settings"
+ latin:keyIcon="iconSettingsKey"
+ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
latin:backgroundType="functional" />
<key-style
latin:styleName="tabKeyStyle"
latin:code="@integer/key_tab"
latin:keyLabel="@string/label_tab_key"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelFlags="fontNormal|preserveCase"
latin:backgroundType="functional" />
<key-style
latin:styleName="toSymbolKeyStyle"
latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_symbol_key"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelFlags="fontNormal|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="toAlphaKeyStyle"
latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_alpha_key"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelFlags="fontNormal|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="toMoreSymbolKeyStyle"
latin:code="@integer/key_shift"
latin:keyLabel="@string/label_to_more_symbol_for_tablet_key"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelFlags="fontNormal|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="backFromMoreSymbolKeyStyle"
latin:code="@integer/key_shift"
latin:keyLabel="@string/label_to_symbol_key"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelFlags="fontNormal|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="comKeyStyle"
latin:keyLabel="@string/keylabel_for_popular_domain"
- latin:keyLabelOption="fontNormal|hasPopupHint"
+ latin:keyLabelFlags="fontNormal|hasPopupHint|preserveCase"
latin:keyOutputText="@string/keylabel_for_popular_domain"
latin:moreKeys="@string/more_keys_for_popular_domain" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_row4_apostrophe_dash.xml b/java/res/xml-sw768dp/keys_apostrophe_dash.xml
index 9536e81da..a53c1e4ab 100644
--- a/java/res/xml-sw600dp/kbd_row4_apostrophe_dash.xml
+++ b/java/res/xml-sw768dp/keys_apostrophe_dash.xml
@@ -33,16 +33,16 @@
>
<Key
latin:keyLabel="/"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel=":"
- latin:moreKeys=":" />
+ latin:moreKeys=":"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</case>
<default>
<Key
latin:keyLabel="@string/keylabel_for_apostrophe"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="@string/keyhintlabel_for_apostrophe"
- latin:moreKeys="@string/more_keys_for_apostrophe" />
+ latin:moreKeys="@string/more_keys_for_apostrophe"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
<switch>
@@ -55,9 +55,9 @@
<default>
<Key
latin:keyLabel="@string/keylabel_for_dash"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="@string/keyhintlabel_for_dash"
- latin:moreKeys="@string/more_keys_for_dash" />
+ latin:moreKeys="@string/more_keys_for_dash"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row1.xml b/java/res/xml-sw768dp/row_qwerty1.xml
index 14b8bddfb..f6600ad03 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row1.xml
+++ b/java/res/xml-sw768dp/row_qwerty1.xml
@@ -26,14 +26,12 @@
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.969%p" />
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="e"
latin:moreKeys="@string/more_keys_for_e" />
@@ -56,8 +54,7 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row2.xml b/java/res/xml-sw768dp/row_qwerty2.xml
index 2c312a328..d348041fd 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row2.xml
+++ b/java/res/xml-sw768dp/row_qwerty2.xml
@@ -26,7 +26,7 @@
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="11.172%p"/>
<Key
latin:keyLabel="a"
@@ -53,7 +53,7 @@
latin:keyLabel="l"
latin:moreKeys="@string/more_keys_for_l" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-15.704%p"
latin:keyWidth="fillBoth" />
</Row>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row3.xml b/java/res/xml-sw768dp/row_qwerty3.xml
index f2f137ea9..e2bb2e546 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw768dp/row_qwerty3.xml
@@ -46,7 +46,7 @@
<Key
latin:keyLabel="m" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-13.750%p"
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row4.xml b/java/res/xml-sw768dp/row_qwerty4.xml
index e35e47d83..84c4a37f0 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw768dp/row_qwerty4.xml
@@ -57,9 +57,9 @@
>
<Key
latin:keyLabel=":"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="+"
- latin:moreKeys="+" />
+ latin:moreKeys="+"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</case>
<default>
<Key
@@ -76,9 +76,9 @@
<default>
<Key
latin:keyLabel="/"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="\@"
- latin:moreKeys="\@" />
+ latin:moreKeys="\@"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
</default>
@@ -92,11 +92,11 @@
latin:languageCode="iw"
>
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
</case>
<default>
<include
- latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
+ latin:keyboardLayout="@xml/keys_apostrophe_dash" />
</default>
</switch>
<switch>
diff --git a/java/res/xml-sw768dp/kbd_rows_arabic.xml b/java/res/xml-sw768dp/rows_arabic.xml
index 7ec36fd94..baced66c3 100644
--- a/java/res/xml-sw768dp/kbd_rows_arabic.xml
+++ b/java/res/xml-sw768dp/rows_arabic.xml
@@ -22,13 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="7.375%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.500%p" />
<!-- \u0636: ARABIC LETTER DAD -->
<Key
@@ -84,7 +84,7 @@
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="9.375%p" />
<!-- \u0634: ARABIC LETTER SHEEN
\u069c: ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE -->
@@ -144,7 +144,7 @@
<Key
latin:keyLabel="ط" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-9.375%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -189,5 +189,5 @@
latin:keyLabel="د" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_azerty.xml b/java/res/xml-sw768dp/rows_azerty.xml
index 4659d9924..6023e984b 100644
--- a/java/res/xml-sw768dp/kbd_rows_azerty.xml
+++ b/java/res/xml-sw768dp/rows_azerty.xml
@@ -22,13 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="8.282%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.969%p" />
<Key
latin:keyLabel="a"
@@ -58,8 +58,7 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
@@ -70,11 +69,10 @@
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="10.167%p" />
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
latin:keyLabel="s"
latin:moreKeys="@string/more_keys_for_s" />
@@ -99,7 +97,7 @@
<Key
latin:keyLabel="m" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-15.704%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -110,8 +108,7 @@
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="13.829%p" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="x" />
<Key
@@ -127,36 +124,16 @@
latin:moreKeys="@string/more_keys_for_n" />
<Key
latin:keyLabel="\'"
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel=":"
- latin:moreKeys=":" />
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="!"
- latin:moreKeys="!" />
- <Key
- latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
- </default>
- </switch>
+ latin:moreKeys=":"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ <include
+ latin:keyboardLayout="@xml/keys_comma_period" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-13.750%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_russian.xml b/java/res/xml-sw768dp/rows_bulgarian.xml
index e5f556958..d67a0d1fa 100644
--- a/java/res/xml-sw768dp/kbd_rows_russian.xml
+++ b/java/res/xml-sw768dp/rows_bulgarian.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -22,74 +22,71 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
- latin:keyWidth="7.125%p"
+ latin:keyWidth="7.333%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft" />
+ latin:keyLabelFlags="alignLeft" />
<Key
- latin:keyLabel="й" />
+ latin:keyLabel="ч" />
<Key
- latin:keyLabel="ц" />
+ latin:keyLabel="ш" />
<Key
- latin:keyLabel="у" />
+ latin:keyLabel="е" />
<Key
- latin:keyLabel="к" />
+ latin:keyLabel="р" />
<Key
- latin:keyLabel="е"
- latin:moreKeys="@string/more_keys_for_cyrillic_e" />
+ latin:keyLabel="т" />
<Key
- latin:keyLabel="н" />
+ latin:keyLabel="ъ" />
<Key
- latin:keyLabel="г" />
+ latin:keyLabel="у" />
<Key
- latin:keyLabel="ш" />
+ latin:keyLabel="и"
+ latin:moreKeys="ѝ" />
<Key
- latin:keyLabel="щ" />
- <Key
- latin:keyLabel="з" />
+ latin:keyLabel="о" />
<Key
- latin:keyLabel="х" />
+ latin:keyLabel="п" />
<Key
- latin:keyLabel="ъ" />
+ latin:keyLabel="я" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillBoth" />
</Row>
<Row
- latin:keyWidth="7.125%p"
+ latin:keyWidth="7.194%p"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="9.375%p" />
<Key
- latin:keyLabel="ф" />
+ latin:keyLabel="а" />
<Key
- latin:keyLabel="ы" />
+ latin:keyLabel="с" />
<Key
- latin:keyLabel="в" />
+ latin:keyLabel="д" />
<Key
- latin:keyLabel="а" />
+ latin:keyLabel="ф" />
<Key
- latin:keyLabel="п" />
+ latin:keyLabel="г" />
<Key
- latin:keyLabel="р" />
+ latin:keyLabel="х" />
<Key
- latin:keyLabel="о" />
+ latin:keyLabel="й" />
<Key
- latin:keyLabel="л" />
+ latin:keyLabel="к" />
<Key
- latin:keyLabel="д" />
+ latin:keyLabel="л" />
<Key
- latin:keyLabel="ж" />
+ latin:keyLabel="щ" />
<Key
- latin:keyLabel="э" />
+ latin:keyLabel="ь" />
<Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-9.375%p"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillBoth" />
</Row>
<Row
@@ -97,31 +94,29 @@
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="12.750%p" />
+ latin:keyWidth="14.375%p" />
<Key
- latin:keyLabel="я" />
- <Key
- latin:keyLabel="ч" />
+ latin:keyLabel="з" />
<Key
- latin:keyLabel="с" />
+ latin:keyLabel="ж" />
<Key
- latin:keyLabel="м" />
+ latin:keyLabel="ц" />
<Key
- latin:keyLabel="и" />
+ latin:keyLabel="в" />
<Key
- latin:keyLabel="т" />
+ latin:keyLabel="б" />
<Key
- latin:keyLabel="ь" />
+ latin:keyLabel="н" />
<Key
- latin:keyLabel="б" />
+ latin:keyLabel="м" />
<Key
latin:keyLabel="ю" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_hebrew.xml b/java/res/xml-sw768dp/rows_hebrew.xml
index 27b39d1ae..61c5eae90 100644
--- a/java/res/xml-sw768dp/kbd_rows_hebrew.xml
+++ b/java/res/xml-sw768dp/rows_hebrew.xml
@@ -22,16 +22,16 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="8.282%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.969%p" />
<include
- latin:keyboardLayout="@xml/kbd_row4_apostrophe_dash" />
+ latin:keyboardLayout="@xml/keys_apostrophe_dash" />
<Key
latin:keyLabel="ק" />
<Key
@@ -58,7 +58,7 @@
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="11.172%p" />
<Key
latin:keyLabel="ש" />
@@ -111,10 +111,10 @@
latin:keyLabel="ץ"
latin:moreKeys="ץ׳" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-10.400%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/rows_number_normal.xml b/java/res/xml-sw768dp/rows_number_normal.xml
new file mode 100644
index 000000000..cf947abd2
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_number_normal.xml
@@ -0,0 +1,159 @@
+<?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"
+>
+ <Row>
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="11.172%p" />
+ <Key
+ latin:keyLabel="-"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="13.829%p"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="1"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="43.125%p" />
+ <Key
+ latin:keyLabel="2"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="3"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-11.172%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="13.829%p" />
+ <Key
+ latin:keyStyle="numStarKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="/"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="4"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="43.125%p" />
+ <Key
+ latin:keyLabel="5"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="6"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-11.172%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="13.829%p" />
+ <Key
+ latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="="
+ latin:keyStyle="numKeyStyle"
+ latin:keyWidth="8.047%p" />
+ <Key
+ latin:keyLabel="7"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="43.125%p" />
+ <Key
+ latin:keyLabel="8"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="9"
+ latin:keyStyle="numKeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="0%p" />
+ </Row>
+ <Row>
+ <switch>
+ <case latin:hasSettingsKey="true">
+ <Key
+ latin:keyStyle="settingsKeyStyle"
+ latin:keyWidth="8.047%p" />
+ </case>
+ <default>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="8.047%p" />
+ </default>
+ </switch>
+ <Key
+ latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
+ latin:keyXPos="13.829%p"
+ latin:keyWidth="24.140%p" />
+ <Key
+ latin:keyStyle="numStarKeyStyle"
+ latin:keyXPos="43.125%p" />
+ <Key
+ latin:keyLabel="0"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
+ <switch>
+ <case
+ latin:shortcutKeyEnabled="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyXPos="-8.047%p"
+ latin:keyWidth="fillRight" />
+ </case>
+ <default>
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="0%p" />
+ </default>
+ </switch>
+ </Row>
+</merge>
diff --git a/java/res/xml-sw768dp/rows_number_password.xml b/java/res/xml-sw768dp/rows_number_password.xml
new file mode 100644
index 000000000..8acfac6ff
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_number_password.xml
@@ -0,0 +1,79 @@
+<?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"
+>
+ <Row>
+ <Key
+ latin:keyStyle="numTabKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="11.172%p" />
+ <Key
+ latin:keyStyle="num1KeyStyle"
+ latin:keyXPos="32.076%p" />
+ <Key
+ latin:keyStyle="num2KeyStyle" />
+ <Key
+ latin:keyStyle="num3KeyStyle" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-11.172%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="32.076%p" />
+ <Key
+ latin:keyStyle="num4KeyStyle" />
+ <Key
+ latin:keyStyle="num5KeyStyle" />
+ <Key
+ latin:keyStyle="num6KeyStyle" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-11.172%p"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="32.076%p" />
+ <Key
+ latin:keyStyle="num7KeyStyle" />
+ <Key
+ latin:keyStyle="num8KeyStyle" />
+ <Key
+ latin:keyStyle="num9KeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="0%p" />
+ </Row>
+ <Row>
+ <Spacer
+ latin:keyXPos="32.076%p" />
+ <Key
+ latin:keyStyle="num0KeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="0%p" />
+ </Row>
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_phone_shift.xml b/java/res/xml-sw768dp/rows_phone.xml
index 46f67d311..0404bb1fb 100644
--- a/java/res/xml-sw768dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw768dp/rows_phone.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2010, The Android Open Source Project
+** Copyright 2011, 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.
@@ -18,18 +18,17 @@
*/
-->
-<Keyboard
+<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="13.250%p"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
+ latin:keyboardLayout="@xml/key_styles_number" />
<Row>
<Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyStyle="numTabKeyStyle"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="11.172%p" />
<Key
latin:keyLabel="-"
@@ -41,9 +40,7 @@
latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
- latin:code="44"
- latin:keyLabel="@string/label_pause_key"
- latin:keyLabelOption="followKeyHintLabelRatio|autoXScale"
+ latin:keyStyle="numPauseKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:keyStyle="num1KeyStyle"
@@ -58,9 +55,9 @@
latin:keyWidth="fillRight" />
</Row>
<Row>
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="11.172%p" />
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="13.829%p" />
<Key
latin:keyLabel=","
latin:keyStyle="numKeyStyle"
@@ -71,9 +68,7 @@
latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
- latin:code="59"
- latin:keyLabel="@string/label_wait_key"
- latin:keyLabelOption="followKeyHintLabelRatio|autoXScale"
+ latin:keyStyle="numWaitKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:keyStyle="num4KeyStyle"
@@ -83,7 +78,7 @@
<Key
latin:keyStyle="num6KeyStyle" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-11.172%p"
latin:keyWidth="fillRight" />
</Row>
@@ -155,4 +150,4 @@
</default>
</switch>
</Row>
-</Keyboard>
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_qwerty.xml b/java/res/xml-sw768dp/rows_qwerty.xml
index 6237712f6..71be44e31 100644
--- a/java/res/xml-sw768dp/kbd_rows_qwerty.xml
+++ b/java/res/xml-sw768dp/rows_qwerty.xml
@@ -22,13 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row1" />
+ latin:keyboardLayout="@xml/row_qwerty1" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row2" />
+ latin:keyboardLayout="@xml/row_qwerty2" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_qwertz.xml b/java/res/xml-sw768dp/rows_qwertz.xml
index 82e0dd09c..7056a94ea 100644
--- a/java/res/xml-sw768dp/kbd_rows_qwertz.xml
+++ b/java/res/xml-sw768dp/rows_qwertz.xml
@@ -22,20 +22,18 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="8.282%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.969%p" />
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="e"
latin:moreKeys="@string/more_keys_for_e" />
@@ -58,15 +56,14 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row2" />
+ latin:keyboardLayout="@xml/row_qwerty2" />
<Row
latin:keyWidth="8.047%p"
>
@@ -91,33 +88,13 @@
latin:moreKeys="@string/more_keys_for_n" />
<Key
latin:keyLabel="m" />
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="!"
- latin:moreKeys="!" />
- <Key
- latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
- latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
- </default>
- </switch>
+ <include
+ latin:keyboardLayout="@xml/keys_comma_period" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-13.750%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_scandinavian.xml b/java/res/xml-sw768dp/rows_scandinavian.xml
index b9d168036..437316699 100644
--- a/java/res/xml-sw768dp/kbd_rows_scandinavian.xml
+++ b/java/res/xml-sw768dp/rows_scandinavian.xml
@@ -22,20 +22,18 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="7.375%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.500%p" />
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="e"
latin:moreKeys="@string/more_keys_for_e" />
@@ -58,10 +56,9 @@
latin:keyLabel="o"
latin:moreKeys="@string/more_keys_for_o" />
<Key
- latin:keyLabel="p"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:keyLabel="p" />
<Key
- latin:keyLabel="å" />
+ latin:keyLabel="@string/keylabel_for_scandinavia_row1_11" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.500%p"
@@ -72,7 +69,7 @@
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="9.375%p" />
<Key
latin:keyLabel="a"
@@ -105,7 +102,7 @@
latin:keyLabel="@string/keylabel_for_scandinavia_row2_11"
latin:moreKeys="@string/more_keys_for_scandinavia_row2_11" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-9.375%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -134,12 +131,12 @@
<Key
latin:keyLabel="m" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-12.750%p"
latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_serbian.xml b/java/res/xml-sw768dp/rows_serbian.xml
index c07176ef6..665975583 100644
--- a/java/res/xml-sw768dp/kbd_rows_serbian.xml
+++ b/java/res/xml-sw768dp/rows_serbian.xml
@@ -22,13 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="7.125%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft" />
+ latin:keyLabelFlags="alignLeft" />
<Key
latin:keyLabel="љ" />
<Key
@@ -62,7 +62,7 @@
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="11.172%p" />
<Key
latin:keyLabel="а" />
@@ -112,12 +112,12 @@
<Key
latin:keyLabel="м" />
<include
- latin:keyboardLayout="@xml/kbd_row3_comma_period" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-13.750%p"
latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/rows_slavic.xml b/java/res/xml-sw768dp/rows_slavic.xml
new file mode 100644
index 000000000..58d5a75fc
--- /dev/null
+++ b/java/res/xml-sw768dp/rows_slavic.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="7.125%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelFlags="alignLeft" />
+ <Key
+ latin:keyLabel="й" />
+ <Key
+ latin:keyLabel="ц" />
+ <Key
+ latin:keyLabel="у"
+ latin:moreKeys="@string/more_keys_for_slavic_u" />
+ <Key
+ latin:keyLabel="к" />
+ <Key
+ latin:keyLabel="е"
+ latin:moreKeys="@string/more_keys_for_slavic_ye" />
+ <Key
+ latin:keyLabel="н"
+ latin:moreKeys="@string/more_keys_for_slavic_en" />
+ <Key
+ latin:keyLabel="г" />
+ <Key
+ latin:keyLabel="ш" />
+ <Key
+ latin:keyLabel="@string/keylabel_for_slavic_shcha" />
+ <Key
+ latin:keyLabel="з" />
+ <Key
+ latin:keyLabel="х" />
+ <Key
+ latin:keyLabel="ъ" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="7.125%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelFlags="alignLeft"
+ latin:keyWidth="9.375%p" />
+ <Key
+ latin:keyLabel="ф" />
+ <Key
+ latin:keyLabel="@string/keylabel_for_slavic_yery"
+ latin:moreKeys="@string/more_keys_for_slavic_yery" />
+ <Key
+ latin:keyLabel="в" />
+ <Key
+ latin:keyLabel="а" />
+ <Key
+ latin:keyLabel="п" />
+ <Key
+ latin:keyLabel="р" />
+ <Key
+ latin:keyLabel="о"
+ latin:moreKeys="@string/more_keys_for_slavic_o" />
+ <Key
+ latin:keyLabel="л" />
+ <Key
+ latin:keyLabel="д" />
+ <Key
+ latin:keyLabel="ж" />
+ <Key
+ latin:keyLabel="э" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyXPos="-9.375%p"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <Row
+ latin:keyWidth="7.125%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="12.750%p" />
+ <Key
+ latin:keyLabel="я" />
+ <Key
+ latin:keyLabel="ч" />
+ <Key
+ latin:keyLabel="с" />
+ <Key
+ latin:keyLabel="м" />
+ <Key
+ latin:keyLabel="@string/keylabel_for_slavic_i" />
+ <Key
+ latin:keyLabel="т" />
+ <Key
+ latin:keyLabel="ь" />
+ <Key
+ latin:keyLabel="б" />
+ <Key
+ latin:keyLabel="ю" />
+ <include
+ latin:keyboardLayout="@xml/keys_comma_period" />
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="fillBoth" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_spanish.xml b/java/res/xml-sw768dp/rows_spanish.xml
index c737f400a..864c435a2 100644
--- a/java/res/xml-sw768dp/kbd_rows_spanish.xml
+++ b/java/res/xml-sw768dp/rows_spanish.xml
@@ -22,15 +22,15 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row1" />
+ latin:keyboardLayout="@xml/row_qwerty1" />
<Row
latin:keyWidth="8.125%p"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="10.167%p" />
<Key
latin:keyLabel="a"
@@ -59,12 +59,12 @@
<Key
latin:keyLabel="ñ" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-15.704%p"
latin:keyWidth="fillBoth" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_symbols.xml b/java/res/xml-sw768dp/rows_symbols.xml
index 987b10cdc..c199ae404 100644
--- a/java/res/xml-sw768dp/kbd_rows_symbols.xml
+++ b/java/res/xml-sw768dp/rows_symbols.xml
@@ -22,45 +22,55 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_currency_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency" />
<Row
latin:keyWidth="8.282%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.969%p" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_1"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_1"
latin:moreKeys="@string/more_keys_for_symbols_1" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_2"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_2"
latin:moreKeys="@string/more_keys_for_symbols_2" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_3"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_3"
latin:moreKeys="@string/more_keys_for_symbols_3" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_4"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_4"
latin:moreKeys="@string/more_keys_for_symbols_4" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_5"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_5"
latin:moreKeys="@string/more_keys_for_symbols_5" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_6"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_6"
latin:moreKeys="@string/more_keys_for_symbols_6" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_7"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_7"
latin:moreKeys="@string/more_keys_for_symbols_7" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_8"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_8"
latin:moreKeys="@string/more_keys_for_symbols_8" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_9"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_9"
latin:moreKeys="@string/more_keys_for_symbols_9" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_0"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_0"
latin:moreKeys="@string/more_keys_for_symbols_0" />
<Key
latin:keyStyle="deleteKeyStyle"
@@ -72,7 +82,7 @@
>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="11.172%p" />
<Key
latin:keyLabel="#" />
@@ -92,14 +102,10 @@
<Key
latin:keyLabel="+"
latin:moreKeys="@string/more_keys_for_plus" />
+ <include
+ latin:keyboardLayout="@xml/keys_parentheses" />
<Key
- latin:keyLabel="("
- latin:moreKeys="[,{,&lt;" />
- <Key
- latin:keyLabel=")"
- latin:moreKeys="],},&gt;" />
- <Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-15.704%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -109,12 +115,8 @@
<Key
latin:keyStyle="toMoreSymbolKeyStyle"
latin:keyWidth="13.829%p" />
- <Key
- latin:keyLabel="&lt;"
- latin:moreKeys="≤,«,‹" />
- <Key
- latin:keyLabel="&gt;"
- latin:moreKeys="≥,»,›" />
+ <include
+ latin:keyboardLayout="@xml/keys_less_greater" />
<Key
latin:keyLabel="="
latin:moreKeys="≠,≈" />
@@ -123,8 +125,7 @@
latin:mode="url"
>
<Key
- latin:keyLabel="\'"
- latin:moreKeys="‘,’,‚,‛" />
+ latin:keyLabel="\'" />
</case>
<default>
<Key
@@ -171,11 +172,10 @@
latin:keyStyle="spaceKeyStyle"
latin:keyXPos="31.250%p"
latin:keyWidth="37.500%p" />
- <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
- <!-- latin:moreKeys="“,”,„,‟,«,»,‘,’,‚,‛" -->
<Key
latin:keyLabel="&quot;"
- latin:moreKeys="“,”,«,»,‘,’,‚,‛" />
+ latin:moreKeys="@string/more_keys_for_tablet_double_quote"
+ latin:maxMoreKeysColumn="4" />
<Key
latin:keyLabel="_" />
<switch>
diff --git a/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml b/java/res/xml-sw768dp/rows_symbols_shift.xml
index 9a9c3a276..e88f78633 100644
--- a/java/res/xml-sw768dp/kbd_rows_symbols_shift.xml
+++ b/java/res/xml-sw768dp/rows_symbols_shift.xml
@@ -22,15 +22,15 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_currency_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency" />
<Row
latin:keyWidth="8.282%p"
>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="7.969%p" />
<Key
latin:keyLabel="~" />
@@ -65,7 +65,7 @@
>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelOption="alignLeft"
+ latin:keyLabelFlags="alignLeft"
latin:keyWidth="11.172%p" />
<Key
latin:keyStyle="moreCurrency1KeyStyle" />
@@ -84,12 +84,10 @@
<Key
latin:keyLabel="±"
latin:moreKeys="∞" />
+ <include
+ latin:keyboardLayout="@xml/keys_curly_brackets" />
<Key
- latin:keyLabel="{" />
- <Key
- latin:keyLabel="}" />
- <Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyXPos="-15.704%p"
latin:keyWidth="fillBoth" />
</Row>
@@ -109,10 +107,8 @@
latin:keyLabel="™" />
<Key
latin:keyLabel="℅" />
- <Key
- latin:keyLabel="[" />
- <Key
- latin:keyLabel="]" />
+ <include
+ latin:keyboardLayout="@xml/keys_square_brackets" />
<Key
latin:keyLabel="¡" />
<Key
diff --git a/java/res/xml-tr/kbd_qwerty.xml b/java/res/xml-tr/kbd_qwerty.xml
deleted file mode 100644
index d2c38f60a..000000000
--- a/java/res/xml-tr/kbd_qwerty.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="tr"
->
- <include
- latin:keyboardLayout="@xml/kbd_rows_qwerty" />
-</Keyboard>
diff --git a/java/res/xml-tr/keyboard_set.xml b/java/res/xml-tr/keyboard_set.xml
new file mode 100644
index 000000000..da79758ec
--- /dev/null
+++ b/java/res/xml-tr/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="tr">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-uk/keyboard_set.xml b/java/res/xml-uk/keyboard_set.xml
new file mode 100644
index 000000000..8eb9eccb7
--- /dev/null
+++ b/java/res/xml-uk/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="uk">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_slavic" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-vi/keyboard_set.xml b/java/res/xml-vi/keyboard_set.xml
new file mode 100644
index 000000000..6d38eb1b4
--- /dev/null
+++ b/java/res/xml-vi/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="vi">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-de-rZZ/kbd_qwerty.xml b/java/res/xml/kbd_arabic.xml
index d5fd8ef7a..ce5f30b2f 100644
--- a/java/res/xml-de-rZZ/kbd_qwerty.xml
+++ b/java/res/xml/kbd_arabic.xml
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="de"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_qwerty" />
+ latin:keyboardLayout="@xml/rows_arabic" />
</Keyboard>
diff --git a/java/res/xml-pl/kbd_qwerty.xml b/java/res/xml/kbd_azerty.xml
index 44312c52c..7bafe5bca 100644
--- a/java/res/xml-pl/kbd_qwerty.xml
+++ b/java/res/xml/kbd_azerty.xml
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="pl"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_qwerty" />
+ latin:keyboardLayout="@xml/rows_azerty" />
</Keyboard>
diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml/kbd_bulgarian.xml
index 8c730a24f..a651991c0 100644
--- a/java/res/xml-fr/kbd_qwerty.xml
+++ b/java/res/xml/kbd_bulgarian.xml
@@ -2,9 +2,9 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** Copyright 2012, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
+** 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
**
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="fr"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_azerty" />
+ latin:keyboardLayout="@xml/rows_bulgarian" />
</Keyboard>
diff --git a/java/res/xml-hu/kbd_qwerty.xml b/java/res/xml/kbd_hebrew.xml
index 3195d5b1f..74836f342 100644
--- a/java/res/xml-hu/kbd_qwerty.xml
+++ b/java/res/xml/kbd_hebrew.xml
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="hu"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_qwertz" />
+ latin:keyboardLayout="@xml/rows_hebrew" />
</Keyboard>
diff --git a/java/res/xml/kbd_mini_keyboard_template.xml b/java/res/xml/kbd_more_keys_keyboard_template.xml
index ad6cf51fe..8e977c5ad 100644
--- a/java/res/xml/kbd_mini_keyboard_template.xml
+++ b/java/res/xml/kbd_more_keys_keyboard_template.xml
@@ -21,6 +21,6 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="10%p"
latin:rowHeight="@dimen/popup_key_height"
- style="?attr/miniKeyboardStyle"
+ style="?attr/moreKeysKeyboardStyle"
>
</Keyboard>
diff --git a/java/res/xml/kbd_number.xml b/java/res/xml/kbd_number.xml
index 38dd6bf62..8b0deea97 100644
--- a/java/res/xml/kbd_number.xml
+++ b/java/res/xml/kbd_number.xml
@@ -23,5 +23,5 @@
latin:keyWidth="26.67%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_number" />
+ latin:keyboardLayout="@xml/rows_number" />
</Keyboard>
diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml
index b550f17c5..91637b62c 100644
--- a/java/res/xml/kbd_phone.xml
+++ b/java/res/xml/kbd_phone.xml
@@ -23,5 +23,5 @@
latin:keyWidth="26.67%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_phone" />
+ latin:keyboardLayout="@xml/rows_phone" />
</Keyboard>
diff --git a/java/res/xml/kbd_phone_shift.xml b/java/res/xml/kbd_phone_symbols.xml
index eea823fc0..7f59a855a 100644
--- a/java/res/xml/kbd_phone_shift.xml
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -23,5 +23,5 @@
latin:keyWidth="26.67%p"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_phone_shift" />
+ latin:keyboardLayout="@xml/rows_phone_symbols" />
</Keyboard>
diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml
index 40917b921..2f49b943a 100644
--- a/java/res/xml/kbd_qwerty.xml
+++ b/java/res/xml/kbd_qwerty.xml
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="en_GB,en_US"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_qwerty" />
+ latin:keyboardLayout="@xml/rows_qwerty" />
</Keyboard>
diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml/kbd_qwertz.xml
index 9991ea2d2..9f7e9019c 100644
--- a/java/res/xml-cs/kbd_qwerty.xml
+++ b/java/res/xml/kbd_qwertz.xml
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLocale="cs"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_qwertz" />
+ latin:keyboardLayout="@xml/rows_qwertz" />
</Keyboard>
diff --git a/java/res/xml/kbd_rows_number.xml b/java/res/xml/kbd_rows_number.xml
deleted file mode 100644
index 90ac5686b..000000000
--- a/java/res/xml/kbd_rows_number.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, 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"
->
- <include
- latin:keyboardLayout="@xml/kbd_key_styles" />
- <include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
- <switch>
- <case
- latin:passwordInput="true"
- >
- <Row>
- <Key
- latin:keyStyle="num1KeyStyle" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Spacer />
- </Row>
- <Row>
- <Key
- latin:keyStyle="num4KeyStyle" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Spacer />
- </Row>
- <Row>
- <Key
- latin:keyStyle="num7KeyStyle" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <Spacer />
- <Key
- latin:keyStyle="num0KeyStyle" />
- <Spacer />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- </case>
- <!-- latin:passwordInput="false" -->
- <default>
- <Row>
- <Key
- latin:keyLabel="1"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="2"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="3"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numFunctionalKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <Key
- latin:keyLabel="4"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="5"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="6"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel=","
- latin:keyStyle="numFunctionalKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <Key
- latin:keyLabel="7"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="8"
- latin:keyStyle="numKeyStyle"/>
- <Key
- latin:keyLabel="9"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <Key
- latin:keyStyle="numSpaceKeyStyle" />
- <Key
- latin:keyLabel="0"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml/kbd_scandinavian.xml b/java/res/xml/kbd_scandinavian.xml
new file mode 100644
index 000000000..46ddfcb8f
--- /dev/null
+++ b/java/res/xml/kbd_scandinavian.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_scandinavian" />
+</Keyboard>
diff --git a/java/res/xml/kbd_serbian.xml b/java/res/xml/kbd_serbian.xml
new file mode 100644
index 000000000..05597c4eb
--- /dev/null
+++ b/java/res/xml/kbd_serbian.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_serbian" />
+</Keyboard>
diff --git a/java/res/xml/kbd_slavic.xml b/java/res/xml/kbd_slavic.xml
new file mode 100644
index 000000000..ca891c000
--- /dev/null
+++ b/java/res/xml/kbd_slavic.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_slavic" />
+</Keyboard>
diff --git a/java/res/xml/kbd_spanish.xml b/java/res/xml/kbd_spanish.xml
new file mode 100644
index 000000000..6ce2b5d24
--- /dev/null
+++ b/java/res/xml/kbd_spanish.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_spanish" />
+</Keyboard>
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index 737f684a7..f6612a2f7 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -22,5 +22,5 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_symbols" />
+ latin:keyboardLayout="@xml/rows_symbols" />
</Keyboard>
diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml
index 9c163d694..41a5571ef 100644
--- a/java/res/xml/kbd_symbols_shift.xml
+++ b/java/res/xml/kbd_symbols_shift.xml
@@ -22,5 +22,5 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_rows_symbols_shift" />
+ latin:keyboardLayout="@xml/rows_symbols_shift" />
</Keyboard>
diff --git a/java/res/xml/kbd_qwerty_f1.xml b/java/res/xml/key_f1.xml
index 83b6ecc8d..83b6ecc8d 100644
--- a/java/res/xml/kbd_qwerty_f1.xml
+++ b/java/res/xml/key_f1.xml
diff --git a/java/res/xml/kbd_settings_or_tab.xml b/java/res/xml/key_settings_or_tab.xml
index 4a8bcc7a6..2d35e3b4a 100644
--- a/java/res/xml/kbd_settings_or_tab.xml
+++ b/java/res/xml/key_settings_or_tab.xml
@@ -25,8 +25,11 @@
<case
latin:hasSettingsKey="true"
>
+ <!-- Because this settings key is not adjacent to the space key, this key should be
+ just ignored while typing (altCode=CODE_UNSPECIFIED). -->
<Key
latin:keyStyle="settingsKeyStyle"
+ latin:altCode="@integer/key_unspecified"
latin:keyWidth="9.2%p" />
</case>
<!-- hasSettingsKey="false" -->
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/key_styles_common.xml
index 453b05dff..0e31bcb31 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -28,7 +28,7 @@
>
<key-style
latin:styleName="f1PopupStyle"
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="@string/more_keys_for_f1"
latin:backgroundType="functional" />
</case>
@@ -38,7 +38,7 @@
>
<key-style
latin:styleName="f1PopupStyle"
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="@string/more_keys_for_f1_settings"
latin:backgroundType="functional" />
</case>
@@ -48,7 +48,7 @@
>
<key-style
latin:styleName="f1PopupStyle"
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="@string/more_keys_for_f1_navigate"
latin:backgroundType="functional" />
</case>
@@ -56,109 +56,70 @@
<default>
<key-style
latin:styleName="f1PopupStyle"
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="@string/more_keys_for_f1"
latin:backgroundType="functional" />
</default>
</switch>
<!-- Functional key styles -->
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="iconShiftKey"
- latin:keyIconShifted="iconShiftedShiftKey"
- latin:backgroundType="sticky" />
- <key-style
- latin:styleName="deleteKeyStyle"
- latin:code="@integer/key_delete"
- latin:keyIcon="iconDeleteKey"
- latin:backgroundType="functional"
- latin:isRepeatable="true" />
- <!-- Return key style -->
<switch>
<case
- latin:mode="im"
- >
- <!-- Smiley key. -->
- <key-style
- latin:styleName="returnKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyLabelOption="hasPopupHint"
- latin:moreKeys="@string/more_keys_for_smiley"
- latin:maxMoreKeysColumn="5"
- latin:backgroundType="functional" />
- </case>
- <case
- latin:imeAction="actionGo"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyLabel="@string/label_go_key"
- latin:keyLabelOption="autoXScale"
- latin:backgroundType="action" />
- </case>
- <case
- latin:imeAction="actionNext"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetAutomaticShifted"
>
<key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyLabel="@string/label_next_key"
- latin:keyLabelOption="autoXScale"
- latin:backgroundType="action" />
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKeyShifted"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOff" />
</case>
<case
- latin:imeAction="actionDone"
+ latin:keyboardSetElement="alphabetShiftLocked|alphabetShiftLockShifted"
>
<key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyLabel="@string/label_done_key"
- latin:keyLabelOption="autoXScale"
- latin:backgroundType="action" />
- </case>
- <case
- latin:imeAction="actionSend"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyLabel="@string/label_send_key"
- latin:keyLabelOption="autoXScale"
- latin:backgroundType="action" />
- </case>
- <case
- latin:imeAction="actionSearch"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="iconSearchKey"
- latin:backgroundType="action" />
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKeyShifted"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOn" />
</case>
<default>
<key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="iconReturnKey"
- latin:backgroundType="functional" />
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKey"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="stickyOff" />
</default>
</switch>
<key-style
+ latin:styleName="deleteKeyStyle"
+ latin:code="@integer/key_delete"
+ latin:keyIcon="iconDeleteKey"
+ latin:keyActionFlags="isRepeatable|noKeyPreview"
+ latin:backgroundType="functional" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_enter_phone" />
+ <key-style
latin:styleName="spaceKeyStyle"
latin:code="@integer/key_space"
+ latin:keyActionFlags="noKeyPreview|enableLongPress"
latin:backgroundType="functional" />
<key-style
latin:styleName="shortcutKeyStyle"
latin:code="@integer/key_shortcut"
latin:keyIcon="iconShortcutKey"
+ latin:keyIconDisabled="iconDisabledShortcutKey"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
+ latin:altCode="@integer/key_space"
latin:parentStyle="f1PopupStyle" />
<key-style
latin:styleName="settingsKeyStyle"
latin:code="@integer/key_settings"
latin:keyIcon="iconSettingsKey"
+ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
+ latin:altCode="@integer/key_space"
latin:backgroundType="functional" />
<key-style
latin:styleName="tabKeyStyle"
@@ -186,7 +147,8 @@
latin:code="@integer/key_switch_alpha_symbol"
latin:keyIcon="iconShortcutForLabel"
latin:keyLabel="@string/label_to_symbol_with_microphone_key"
- latin:keyLabelOption="withIconRight"
+ latin:keyLabelFlags="withIconRight|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
</case>
<default>
@@ -194,6 +156,8 @@
latin:styleName="toSymbolKeyStyle"
latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_symbol_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
</default>
</switch>
@@ -201,23 +165,29 @@
latin:styleName="toAlphaKeyStyle"
latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_alpha_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="toMoreSymbolKeyStyle"
latin:code="@integer/key_shift"
latin:keyLabel="@string/label_to_more_symbol_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="backFromMoreSymbolKeyStyle"
latin:code="@integer/key_shift"
latin:keyLabel="@string/label_to_symbol_key"
+ latin:keyLabelFlags="preserveCase"
+ latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
latin:styleName="punctuationKeyStyle"
latin:keyLabel="."
latin:keyHintLabel="@string/keyhintlabel_for_punctuation"
- latin:keyLabelOption="hasPopupHint"
+ latin:keyLabelFlags="hasPopupHint|preserveCase"
latin:moreKeys="@string/more_keys_for_punctuation"
- latin:maxMoreKeysColumn="@integer/mini_keyboard_column_for_punctuation"
+ latin:maxMoreKeysColumn="@integer/more_keys_keyboard_column_for_punctuation"
latin:backgroundType="functional" />
</merge>
diff --git a/java/res/xml/kbd_currency_key_styles.xml b/java/res/xml/key_styles_currency.xml
index 225888337..3e4afdfb5 100644
--- a/java/res/xml/kbd_currency_key_styles.xml
+++ b/java/res/xml/key_styles_currency.xml
@@ -26,7 +26,7 @@
latin:passwordInput="true"
>
<include
- latin:keyboardLayout="@xml/kbd_currency_dollar_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency_dollar" />
</case>
<!-- Countries using Euro currency, 23 countries as for January 2011. -->
1. Andorra (ca_AD, ca_ES)
@@ -62,19 +62,19 @@
latin:localeCode="da|de|es|el|fi|fr|it|nl|sk|sl|pt_PT|tr"
>
<include
- latin:keyboardLayout="@xml/kbd_currency_euro_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency_euro" />
</case>
<case
latin:languageCode="ca|et|lb|mt|sla"
>
<include
- latin:keyboardLayout="@xml/kbd_currency_euro_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency_euro" />
</case>
<case
latin:countryCode="AD|AT|BE|CY|EE|FI|FR|DE|GR|IE|IT|XK|LU|MT|MO|ME|NL|PT|SM|SK|SI|ES|VA"
>
<include
- latin:keyboardLayout="@xml/kbd_currency_euro_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency_euro" />
</case>
<case
latin:languageCode="iw"
@@ -121,7 +121,7 @@
</case>
<default>
<include
- latin:keyboardLayout="@xml/kbd_currency_dollar_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency_dollar" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/kbd_currency_dollar_key_styles.xml b/java/res/xml/key_styles_currency_dollar.xml
index d5dca2afa..d5dca2afa 100644
--- a/java/res/xml/kbd_currency_dollar_key_styles.xml
+++ b/java/res/xml/key_styles_currency_dollar.xml
diff --git a/java/res/xml/kbd_currency_euro_key_styles.xml b/java/res/xml/key_styles_currency_euro.xml
index 6edddf074..6edddf074 100644
--- a/java/res/xml/kbd_currency_euro_key_styles.xml
+++ b/java/res/xml/key_styles_currency_euro.xml
diff --git a/java/res/xml/key_styles_enter_phone.xml b/java/res/xml/key_styles_enter_phone.xml
new file mode 100644
index 000000000..6af81fb7b
--- /dev/null
+++ b/java/res/xml/key_styles_enter_phone.xml
@@ -0,0 +1,124 @@
+<?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"
+>
+ <!-- Enter key style -->
+ <key-style
+ latin:styleName="defaultEnterKeyStyle"
+ latin:code="@integer/key_enter"
+ latin:keyIcon="iconReturnKey"
+ latin:keyLabelFlags="autoXScale|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="functional" />
+ <key-style
+ latin:styleName="defaultActionKeyStyle"
+ latin:code="@integer/key_action_enter"
+ latin:keyIcon="iconUndefined"
+ latin:backgroundType="action"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ <switch>
+ <!-- Shift + Enter in textMultiLine field. -->
+ <case
+ latin:isMultiLine="true"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <!-- Smiley in textShortMessage field. -->
+ <case
+ latin:mode="im"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel=":-)"
+ latin:keyOutputText=":-) "
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="@string/more_keys_for_smiley"
+ latin:maxMoreKeysColumn="5"
+ latin:backgroundType="functional" />
+ </case>
+ <case
+ latin:imeAction="actionGo"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_go_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionNext"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_next_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionPrevious"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_previous_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionDone"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_done_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionSend"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_send_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionSearch"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyIcon="iconSearchKey"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionCustomLabel"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabelFlags="fromCustomActionLabel"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <!-- imeAction is either actionNone or actionUnspecified. -->
+ <default>
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/key_styles_enter_tablet.xml b/java/res/xml/key_styles_enter_tablet.xml
new file mode 100644
index 000000000..702089181
--- /dev/null
+++ b/java/res/xml/key_styles_enter_tablet.xml
@@ -0,0 +1,111 @@
+<?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"
+>
+ <!-- Enter key style -->
+ <key-style
+ latin:styleName="defaultEnterKeyStyle"
+ latin:code="@integer/key_enter"
+ latin:keyIcon="iconReturnKey"
+ latin:keyLabelFlags="autoXScale|preserveCase"
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="functional" />
+ <key-style
+ latin:styleName="defaultActionKeyStyle"
+ latin:code="@integer/key_action_enter"
+ latin:keyIcon="iconUndefined"
+ latin:backgroundType="action"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ <switch>
+ <!-- Shift + Enter in textMultiLine field. -->
+ <case
+ latin:isMultiLine="true"
+ latin:keyboardSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionGo"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_go_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionNext"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_next_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionPrevious"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_previous_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionDone"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_done_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionSend"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabel="@string/label_send_key"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionSearch"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyIcon="iconSearchKey"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionCustomLabel"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keyLabelFlags="fromCustomActionLabel"
+ latin:parentStyle="defaultActionKeyStyle" />
+ </case>
+ <!-- imeAction is either actionNone or actionUnspecified. -->
+ <default>
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/kbd_numkey_styles.xml b/java/res/xml/key_styles_number.xml
index 5d5439906..7307a1a2b 100644
--- a/java/res/xml/kbd_numkey_styles.xml
+++ b/java/res/xml/key_styles_number.xml
@@ -22,23 +22,30 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<key-style
+ latin:styleName="numKeyBaseStyle"
+ latin:keyActionFlags="noKeyPreview" />
+ <key-style
latin:styleName="numKeyStyle"
- latin:keyLabelOption="largeLetter|followKeyLetterRatio" />
+ latin:keyLabelFlags="largeLetter|followKeyLetterRatio"
+ latin:parentStyle="numKeyBaseStyle" />
<key-style
latin:styleName="numModeKeyStyle"
- latin:keyLabelOption="fontNormal|followKeyLetterRatio" />
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio"
+ latin:parentStyle="numKeyBaseStyle" />
<key-style
latin:styleName="numFunctionalKeyStyle"
- latin:keyLabelOption="largeLetter|followKeyLetterRatio"
- latin:backgroundType="functional" />
+ latin:keyLabelFlags="largeLetter|followKeyLetterRatio"
+ latin:backgroundType="functional"
+ latin:parentStyle="numKeyBaseStyle" />
<key-style
latin:styleName="numberKeyStyle"
- latin:keyLabelOption="alignLeftOfCenter|hasHintLabel"
+ latin:keyLabelFlags="alignLeftOfCenter|hasHintLabel"
latin:parentStyle="numKeyStyle" />
<key-style
latin:styleName="num0KeyStyle"
latin:code="48"
latin:keyLabel="0 +"
+ latin:keyActionFlags="enableLongPress"
latin:parentStyle="numberKeyStyle" />
<key-style
latin:styleName="num1KeyStyle"
@@ -89,18 +96,37 @@
latin:code="42"
latin:keyLabel="\uff0a"
latin:parentStyle="numKeyStyle" />
+ <!-- Only for non-tablet device -->
<key-style
- latin:styleName="numSwitchToAltKeyStyle"
- latin:code="@integer/key_shift"
+ latin:styleName="numPhoneToSymbolKeyStyle"
+ latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_phone_symbols_key"
latin:parentStyle="numModeKeyStyle" />
<key-style
- latin:styleName="numSwitchToNumericKeyStyle"
- latin:code="@integer/key_shift"
+ latin:styleName="numPhoneToNumericKeyStyle"
+ latin:code="@integer/key_switch_alpha_symbol"
latin:keyLabel="@string/label_to_phone_numeric_key"
latin:parentStyle="numModeKeyStyle" />
<key-style
+ latin:styleName="numPauseKeyStyle"
+ latin:code="44"
+ latin:keyLabel="@string/label_pause_key"
+ latin:keyLabelFlags="followKeyHintLabelRatio|autoXScale"
+ latin:parentStyle="numKeyBaseStyle" />
+ <key-style
+ latin:styleName="numWaitKeyStyle"
+ latin:code="59"
+ latin:keyLabel="@string/label_wait_key"
+ latin:keyLabelFlags="followKeyHintLabelRatio|autoXScale"
+ latin:parentStyle="numKeyBaseStyle" />
+ <key-style
+ latin:styleName="numTabKeyStyle"
+ latin:keyActionFlags="noKeyPreview"
+ latin:parentStyle="tabKeyStyle" />
+ <key-style
latin:styleName="numSpaceKeyStyle"
latin:code="@integer/key_space"
- latin:keyIcon="iconSpaceKey" />
+ latin:keyIcon="iconSpaceKeyForNumberLayout"
+ latin:keyActionFlags="enableLongPress"
+ latin:parentStyle="numKeyBaseStyle" />
</merge>
diff --git a/java/res/xml/kbd_symbols_f1.xml b/java/res/xml/key_symbols_f1.xml
index 0dd3d9109..0dd3d9109 100644
--- a/java/res/xml/kbd_symbols_f1.xml
+++ b/java/res/xml/key_symbols_f1.xml
diff --git a/java/res/xml/keyboard_set.xml b/java/res/xml/keyboard_set.xml
new file mode 100644
index 000000000..1398b137c
--- /dev/null
+++ b/java/res/xml/keyboard_set.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<KeyboardSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyboardLocale="en_GB,en_US">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_qwerty" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardSet>
diff --git a/java/res/xml-sw600dp/kbd_row3_comma_period.xml b/java/res/xml/keys_comma_period.xml
index b84443078..6db02b61d 100644
--- a/java/res/xml-sw600dp/kbd_row3_comma_period.xml
+++ b/java/res/xml/keys_comma_period.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -33,14 +33,14 @@
<default>
<Key
latin:keyLabel=","
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="!"
- latin:moreKeys="!" />
+ latin:moreKeys="!"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<Key
latin:keyLabel="."
- latin:keyLabelOption="hasUppercaseLetter"
latin:keyHintLabel="\?"
- latin:moreKeys="\?" />
+ latin:moreKeys="\?"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/keys_curly_brackets.xml b/java/res/xml/keys_curly_brackets.xml
new file mode 100644
index 000000000..d21a09281
--- /dev/null
+++ b/java/res/xml/keys_curly_brackets.xml
@@ -0,0 +1,30 @@
+<?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"
+>
+ <Key
+ latin:keyLabel="{"
+ latin:code="@integer/keycode_for_left_curly_bracket" />
+ <Key
+ latin:keyLabel="}"
+ latin:code="@integer/keycode_for_right_curly_bracket" />
+</merge>
diff --git a/java/res/xml/keys_less_greater.xml b/java/res/xml/keys_less_greater.xml
new file mode 100644
index 000000000..8961d9ce6
--- /dev/null
+++ b/java/res/xml/keys_less_greater.xml
@@ -0,0 +1,32 @@
+<?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"
+>
+ <Key
+ latin:keyLabel="&lt;"
+ latin:code="@integer/keycode_for_less_than"
+ latin:moreKeys="@string/more_keys_for_less_than" />
+ <Key
+ latin:keyLabel="&gt;"
+ latin:code="@integer/keycode_for_greater_than"
+ latin:moreKeys="@string/more_keys_for_greater_than" />
+</merge>
diff --git a/java/res/xml/keys_parentheses.xml b/java/res/xml/keys_parentheses.xml
new file mode 100644
index 000000000..6853bf167
--- /dev/null
+++ b/java/res/xml/keys_parentheses.xml
@@ -0,0 +1,32 @@
+<?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"
+>
+ <Key
+ latin:keyLabel="("
+ latin:code="@integer/keycode_for_left_parenthesis"
+ latin:moreKeys="@string/more_keys_for_left_parenthesis" />
+ <Key
+ latin:keyLabel=")"
+ latin:code="@integer/keycode_for_right_parenthesis"
+ latin:moreKeys="@string/more_keys_for_right_parenthesis" />
+</merge>
diff --git a/java/res/xml/keys_square_brackets.xml b/java/res/xml/keys_square_brackets.xml
new file mode 100644
index 000000000..44387c3bf
--- /dev/null
+++ b/java/res/xml/keys_square_brackets.xml
@@ -0,0 +1,30 @@
+<?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"
+>
+ <Key
+ latin:keyLabel="["
+ latin:code="@integer/keycode_for_left_square_bracket" />
+ <Key
+ latin:keyLabel="]"
+ latin:code="@integer/keycode_for_right_square_bracket" />
+</merge>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 6184add4d..650f91b9b 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -20,7 +20,8 @@
<!-- The attributes in this XML file provide configuration information -->
<!-- for the Input Method Manager. -->
-<!-- Keyboard: en_US, en_GB, ar, cs, da, de, de(QWERTY), es, es_US, fi, fr, fr_CA, fr_CH, hr, hu, it, iw, nb, nl, pl, pt, ru, sr, sv, tr -->
+<!-- Keyboard: en_US, en_GB, ar, be, bg, cs, da, de, de(QWERTY), es, es_US, et, fi, fr, fr_CA,
+ fr_CH, hr, hu, it, iw, ky, lt, lv, nb, nl, pl, pt, ro, ru, sk, sl, sr, sv, tr, uk, vi -->
<!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. -->
<!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default
subtype.-->
@@ -31,7 +32,7 @@
android:label="@string/subtype_en_US"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EnabledWhenDefaultIsNotAsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_en_GB"
@@ -47,6 +48,18 @@
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="be"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="bg"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
android:imeSubtypeLocale="cs"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
@@ -64,7 +77,7 @@
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
- android:label="@string/subtype_de_qwerty"
+ android:label="@string/subtype_generic_qwerty"
android:imeSubtypeLocale="de"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,KeyboardLocale=de_ZZ,SupportTouchPositionCorrection"
@@ -77,6 +90,12 @@
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="et"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
android:imeSubtypeLocale="fi"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
@@ -126,6 +145,24 @@
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="ky"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="lt"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="lv"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
android:imeSubtypeLocale="nb"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
@@ -150,12 +187,30 @@
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="ro"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
android:imeSubtypeLocale="ru"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="sk"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="sl"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
android:imeSubtypeLocale="sr"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
@@ -172,4 +227,16 @@
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
/>
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="uk"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_generic"
+ android:imeSubtypeLocale="vi"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ />
</input-method>
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
index 80613a56f..f38b85f0b 100644
--- a/java/res/xml/prefs_for_debug.xml
+++ b/java/res/xml/prefs_for_debug.xml
@@ -42,4 +42,10 @@
android:defaultValue="false"
/>
+ <CheckBoxPreference
+ android:key="force_non_distinct_multitouch"
+ android:title="@string/prefs_force_non_distinct_multitouch"
+ android:persistent="true"
+ android:defaultValue="false"
+ />
</PreferenceScreen>
diff --git a/java/res/xml/kbd_qwerty_row1.xml b/java/res/xml/row_qwerty1.xml
index e8e8d1b46..cb1f4d297 100644
--- a/java/res/xml/kbd_qwerty_row1.xml
+++ b/java/res/xml/row_qwerty1.xml
@@ -27,43 +27,50 @@
<Key
latin:keyLabel="q"
latin:keyHintLabel="1"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:additionalMoreKeys="1" />
<Key
latin:keyLabel="w"
latin:keyHintLabel="2"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:additionalMoreKeys="2" />
<Key
latin:keyLabel="e"
latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
latin:moreKeys="@string/more_keys_for_e" />
<Key
latin:keyLabel="r"
latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
latin:moreKeys="@string/more_keys_for_r" />
<Key
latin:keyLabel="t"
latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
latin:moreKeys="@string/more_keys_for_t" />
<Key
latin:keyLabel="y"
latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
latin:moreKeys="@string/more_keys_for_y" />
<Key
latin:keyLabel="u"
latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
latin:moreKeys="@string/more_keys_for_u" />
<Key
latin:keyLabel="i"
latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
latin:moreKeys="@string/more_keys_for_i" />
<Key
latin:keyLabel="o"
latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
latin:moreKeys="@string/more_keys_for_o" />
<Key
latin:keyLabel="p"
latin:keyHintLabel="0"
- latin:moreKeys="@string/more_keys_for_p"
+ latin:additionalMoreKeys="0"
latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml/kbd_qwerty_row2.xml b/java/res/xml/row_qwerty2.xml
index 8986780b7..8986780b7 100644
--- a/java/res/xml/kbd_qwerty_row2.xml
+++ b/java/res/xml/row_qwerty2.xml
diff --git a/java/res/xml/kbd_qwerty_row3.xml b/java/res/xml/row_qwerty3.xml
index c2b45e752..c2b45e752 100644
--- a/java/res/xml/kbd_qwerty_row3.xml
+++ b/java/res/xml/row_qwerty3.xml
diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/row_qwerty4.xml
index eb1e9b8b3..8c20a72dc 100644
--- a/java/res/xml/kbd_qwerty_row4.xml
+++ b/java/res/xml/row_qwerty4.xml
@@ -33,14 +33,14 @@
latin:keyStyle="toSymbolKeyStyle"
latin:keyWidth="15%p" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f1" />
+ latin:keyboardLayout="@xml/key_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="50%p" />
<Key
latin:keyStyle="punctuationKeyStyle" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</case>
<!-- hasSettingsKey="true" or navigateAction="true" -->
@@ -49,9 +49,9 @@
latin:keyStyle="toSymbolKeyStyle"
latin:keyWidth="13.75%p" />
<include
- latin:keyboardLayout="@xml/kbd_settings_or_tab" />
+ latin:keyboardLayout="@xml/key_settings_or_tab" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f1" />
+ latin:keyboardLayout="@xml/key_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="35.83%p" />
@@ -59,7 +59,7 @@
latin:keyStyle="punctuationKeyStyle"
latin:keyWidth="9.2%p" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</default>
</switch>
diff --git a/java/res/xml/kbd_symbols_row4.xml b/java/res/xml/row_symbols4.xml
index 864cf2b8e..be0c94ffa 100644
--- a/java/res/xml/kbd_symbols_row4.xml
+++ b/java/res/xml/row_symbols4.xml
@@ -33,14 +33,14 @@
latin:keyStyle="toAlphaKeyStyle"
latin:keyWidth="15%p" />
<include
- latin:keyboardLayout="@xml/kbd_symbols_f1" />
+ latin:keyboardLayout="@xml/key_symbols_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="50%p" />
<Key
latin:keyStyle="punctuationKeyStyle" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</case>
<!-- hasSettingsKey="true" or navigateAction="true" -->
@@ -49,9 +49,9 @@
latin:keyStyle="toAlphaKeyStyle"
latin:keyWidth="13.75%p" />
<include
- latin:keyboardLayout="@xml/kbd_settings_or_tab" />
+ latin:keyboardLayout="@xml/key_settings_or_tab" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_f1" />
+ latin:keyboardLayout="@xml/key_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="35.83%p" />
@@ -59,7 +59,7 @@
latin:keyStyle="punctuationKeyStyle"
latin:keyWidth="9.2%p" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</default>
</switch>
diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/row_symbols_shift4.xml
index 89e80e5f7..dd13b7175 100644
--- a/java/res/xml/kbd_symbols_shift_row4.xml
+++ b/java/res/xml/row_symbols_shift4.xml
@@ -33,7 +33,7 @@
latin:keyStyle="toAlphaKeyStyle"
latin:keyWidth="15%p" />
<!-- Note: Neither DroidSans nor Roboto have a glyph for ‟ Double high-reversed-9 quotation mark U+201F. -->
- <!-- latin:keyLabelOption="hasPopupHint" -->
+ <!-- latin:keyLabelFlags="hasPopupHint" -->
<!-- latin:moreKeys="‟" -->
<Key
latin:keyLabel="„"
@@ -45,7 +45,7 @@
latin:keyLabel="…"
latin:backgroundType="functional" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</case>
<!-- hasSettingsKey="true" or navigateAction="true" -->
@@ -54,9 +54,9 @@
latin:keyStyle="toAlphaKeyStyle"
latin:keyWidth="13.75%p" />
<include
- latin:keyboardLayout="@xml/kbd_settings_or_tab" />
+ latin:keyboardLayout="@xml/key_settings_or_tab" />
<!-- Note: Neither DroidSans nor Roboto have a glyph for ‟ Double high-reversed-9 quotation mark U+201F. -->
- <!-- latin:keyLabelOption="hasPopupHint" -->
+ <!-- latin:keyLabelFlags="hasPopupHint" -->
<!-- latin:moreKeys="‟" -->
<Key
latin:keyLabel="„"
@@ -70,7 +70,7 @@
latin:keyWidth="9.2%p"
latin:backgroundType="functional" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</default>
</switch>
diff --git a/java/res/xml/kbd_rows_arabic.xml b/java/res/xml/rows_arabic.xml
index dd5123e4c..2dcd831c2 100644
--- a/java/res/xml/kbd_rows_arabic.xml
+++ b/java/res/xml/rows_arabic.xml
@@ -22,7 +22,7 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="10%p"
>
@@ -30,18 +30,19 @@
<Key
latin:keyLabel="ض"
latin:keyHintLabel="1"
- latin:moreKeys="1,١" />
+ latin:additionalMoreKeys="1,١" />
<!-- \u0635: ARABIC LETTER SAD -->
<Key
latin:keyLabel="ص"
latin:keyHintLabel="2"
- latin:moreKeys="2,٢" />
+ latin:additionalMoreKeys="2,٢" />
<!-- \u0642: ARABIC LETTER QAF
\u06a8: ARABIC LETTER QAF WITH THREE DOTS ABOVE -->
<Key
latin:keyLabel="ق"
latin:keyHintLabel="3"
- latin:moreKeys="3,٣,\u06a8" />
+ latin:additionalMoreKeys="3,٣"
+ latin:moreKeys="\u06a8" />
<!-- \u0641: ARABIC LETTER FEH
\u06a4: ARABIC LETTER VEH
\u06a2: ARABIC LETTER FEH WITH DOT MOVED BELOW
@@ -49,40 +50,43 @@
<Key
latin:keyLabel="ف"
latin:keyHintLabel="4"
- latin:moreKeys="4,٤,\u06a4,\u06a2,\u06a5" />
+ latin:additionalMoreKeys="4,٤"
+ latin:moreKeys="\u06a4,\u06a2,\u06a5" />
<!-- \u063a: ARABIC LETTER GHAIN -->
<Key
latin:keyLabel="غ"
latin:keyHintLabel="5"
- latin:moreKeys="5,٥" />
+ latin:additionalMoreKeys="5,٥" />
<!-- \u0639: ARABIC LETTER AIN -->
<Key
latin:keyLabel="ع"
latin:keyHintLabel="6"
- latin:moreKeys="6,٦" />
+ latin:additionalMoreKeys="6,٦" />
<!-- \u0647: ARABIC LETTER HEH
\ufeeb: ARABIC LETTER HEH INITIAL FORM
\u0647\u0640: ARABIC LETTER HEH + Zero width joiner -->
<Key
latin:keyLabel="ه"
latin:keyHintLabel="7"
- latin:moreKeys="7,٧,\ufeeb|\u0647\u200D" />
+ latin:additionalMoreKeys="7,٧"
+ latin:moreKeys="\ufeeb|\u0647\u200D" />
<!-- \u062e: ARABIC LETTER KHAH -->
<Key
latin:keyLabel="خ"
latin:keyHintLabel="8"
- latin:moreKeys="8,٨" />
+ latin:additionalMoreKeys="8,٨" />
<!-- \u062d: ARABIC LETTER HAH -->
<Key
latin:keyLabel="ح"
latin:keyHintLabel="9"
- latin:moreKeys="9,٩" />
+ latin:additionalMoreKeys="9,٩" />
<!-- \u062c: ARABIC LETTER JEEM
\u0686: ARABIC LETTER TCHEH -->
<Key
latin:keyLabel="ج"
latin:keyHintLabel="0"
- latin:moreKeys="0,٠,\u0686"
+ latin:additionalMoreKeys="0,٠"
+ latin:moreKeys="\u0686"
latin:keyWidth="fillRight" />
</Row>
<Row
@@ -185,5 +189,5 @@
latin:visualInsetsLeft="1%p" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_azerty.xml b/java/res/xml/rows_azerty.xml
index 54fe546e3..533c683d6 100644
--- a/java/res/xml/kbd_rows_azerty.xml
+++ b/java/res/xml/rows_azerty.xml
@@ -22,58 +22,66 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="10%p"
>
<Key
latin:keyLabel="a"
latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1"
latin:moreKeys="@string/more_keys_for_a" />
<Key
latin:keyLabel="z"
latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2"
latin:moreKeys="@string/more_keys_for_z" />
<Key
latin:keyLabel="e"
latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
latin:moreKeys="@string/more_keys_for_e" />
<Key
latin:keyLabel="r"
latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
latin:moreKeys="@string/more_keys_for_r" />
<Key
latin:keyLabel="t"
latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
latin:moreKeys="@string/more_keys_for_t" />
<Key
latin:keyLabel="y"
latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
latin:moreKeys="@string/more_keys_for_y" />
<Key
latin:keyLabel="u"
latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
latin:moreKeys="@string/more_keys_for_u" />
<Key
latin:keyLabel="i"
latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
latin:moreKeys="@string/more_keys_for_i" />
<Key
latin:keyLabel="o"
latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
latin:moreKeys="@string/more_keys_for_o" />
<Key
latin:keyLabel="p"
latin:keyHintLabel="0"
- latin:moreKeys="@string/more_keys_for_p"
+ latin:additionalMoreKeys="0"
latin:keyWidth="fillRight" />
</Row>
<Row
latin:keyWidth="10%p"
>
<Key
- latin:keyLabel="q"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:keyLabel="q" />
<Key
latin:keyLabel="s"
latin:moreKeys="@string/more_keys_for_s" />
@@ -107,8 +115,7 @@
latin:keyWidth="15%p"
latin:visualInsetsRight="1%p" />
<Key
- latin:keyLabel="w"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:keyLabel="w" />
<Key
latin:keyLabel="x" />
<Key
@@ -123,14 +130,18 @@
<Key
latin:keyLabel="n"
latin:moreKeys="@string/more_keys_for_n" />
+ <!-- TODO: Introduce a flag, such as strinctMoreKeysOrder, to control moreKeys display
+ order more precisely. -->
+ <!-- This key is close enough to right edge, so that the 4-more keys will be displayed in
+ order of "4,3,1,2". See @string/more_keys_for_single_quote -->
<Key
latin:keyLabel="\'"
- latin:moreKeys="‘,’,‚,‛" />
+ latin:moreKeys="\u2018,\u2019,\u201b,\u201a" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight"
latin:visualInsetsLeft="1%p" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/rows_bulgarian.xml b/java/res/xml/rows_bulgarian.xml
new file mode 100644
index 000000000..2eac93a7e
--- /dev/null
+++ b/java/res/xml/rows_bulgarian.xml
@@ -0,0 +1,129 @@
+<?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"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="9.091%p"
+ >
+ <Key
+ latin:keyLabel="ч"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1" />
+ <Key
+ latin:keyLabel="ш"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2" />
+ <Key
+ latin:keyLabel="е"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3" />
+ <Key
+ latin:keyLabel="р"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4" />
+ <Key
+ latin:keyLabel="т"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5" />
+ <Key
+ latin:keyLabel="ъ"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6" />
+ <Key
+ latin:keyLabel="у"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7" />
+ <Key
+ latin:keyLabel="и"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
+ latin:moreKeys="ѝ" />
+ <Key
+ latin:keyLabel="о"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9" />
+ <Key
+ latin:keyLabel="п"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0" />
+ <Key
+ latin:keyLabel="я"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="9.091%p"
+ >
+ <Key
+ latin:keyLabel="а" />
+ <Key
+ latin:keyLabel="с" />
+ <Key
+ latin:keyLabel="д" />
+ <Key
+ latin:keyLabel="ф" />
+ <Key
+ latin:keyLabel="г" />
+ <Key
+ latin:keyLabel="х" />
+ <Key
+ latin:keyLabel="й" />
+ <Key
+ latin:keyLabel="к" />
+ <Key
+ latin:keyLabel="л" />
+ <Key
+ latin:keyLabel="щ" />
+ <Key
+ latin:keyLabel="ь"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="9.091%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="13.636%p" />
+ <Key
+ latin:keyLabel="з" />
+ <Key
+ latin:keyLabel="ж" />
+ <Key
+ latin:keyLabel="ц" />
+ <Key
+ latin:keyLabel="в" />
+ <Key
+ latin:keyLabel="б" />
+ <Key
+ latin:keyLabel="н" />
+ <Key
+ latin:keyLabel="м" />
+ <Key
+ latin:keyLabel="ю" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml/kbd_rows_hebrew.xml b/java/res/xml/rows_hebrew.xml
index 6be8174c5..a64a09dbc 100644
--- a/java/res/xml/kbd_rows_hebrew.xml
+++ b/java/res/xml/rows_hebrew.xml
@@ -22,7 +22,7 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="10%p"
>
@@ -105,5 +105,5 @@
<!-- Here is 5%p space -->
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/rows_number.xml b/java/res/xml/rows_number.xml
new file mode 100644
index 000000000..8da83be80
--- /dev/null
+++ b/java/res/xml/rows_number.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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"
+ latin:keyWidth="26.67%p"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_number" />
+ <switch>
+ <case
+ latin:passwordInput="true"
+ >
+ <include
+ latin:keyboardLayout="@xml/rows_number_password" />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/rows_number_normal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rows_number_normal.xml b/java/res/xml/rows_number_normal.xml
new file mode 100644
index 000000000..b581fb5cd
--- /dev/null
+++ b/java/res/xml/rows_number_normal.xml
@@ -0,0 +1,81 @@
+<?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"
+>
+ <Row>
+<Key
+ latin:keyLabel="1"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="2"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="3"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="-"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <Key
+ latin:keyLabel="4"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="5"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="6"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel=","
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <Key
+ latin:keyLabel="7"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="8"
+ latin:keyStyle="numKeyStyle"/>
+ <Key
+ latin:keyLabel="9"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <Key
+ latin:keyStyle="numSpaceKeyStyle" />
+ <Key
+ latin:keyLabel="0"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+</merge>
diff --git a/java/res/xml/rows_number_password.xml b/java/res/xml/rows_number_password.xml
new file mode 100644
index 000000000..e4272ed3f
--- /dev/null
+++ b/java/res/xml/rows_number_password.xml
@@ -0,0 +1,62 @@
+<?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"
+>
+ <Row>
+ <Key
+ latin:keyStyle="num1KeyStyle" />
+ <Key
+ latin:keyStyle="num2KeyStyle" />
+ <Key
+ latin:keyStyle="num3KeyStyle" />
+ <Spacer />
+ </Row>
+ <Row>
+ <Key
+ latin:keyStyle="num4KeyStyle" />
+ <Key
+ latin:keyStyle="num5KeyStyle" />
+ <Key
+ latin:keyStyle="num6KeyStyle" />
+ <Spacer />
+ </Row>
+ <Row>
+ <Key
+ latin:keyStyle="num7KeyStyle" />
+ <Key
+ latin:keyStyle="num8KeyStyle" />
+ <Key
+ latin:keyStyle="num9KeyStyle" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row>
+ <Spacer />
+ <Key
+ latin:keyStyle="num0KeyStyle" />
+ <Spacer />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+</merge>
diff --git a/java/res/xml/kbd_rows_phone.xml b/java/res/xml/rows_phone.xml
index 5500a6078..60296d061 100644
--- a/java/res/xml/kbd_rows_phone.xml
+++ b/java/res/xml/rows_phone.xml
@@ -22,9 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
+ latin:keyboardLayout="@xml/key_styles_number" />
<Row>
<Key
latin:keyStyle="num1KeyStyle" />
@@ -62,13 +62,13 @@
</Row>
<Row>
<Key
- latin:keyStyle="numSwitchToAltKeyStyle" />
+ latin:keyStyle="numPhoneToSymbolKeyStyle" />
<Key
latin:keyStyle="num0KeyStyle" />
<Key
latin:keyStyle="numSpaceKeyStyle" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml/kbd_rows_phone_shift.xml b/java/res/xml/rows_phone_symbols.xml
index 3c283d3e6..7841c56e5 100644
--- a/java/res/xml/kbd_rows_phone_shift.xml
+++ b/java/res/xml/rows_phone_symbols.xml
@@ -22,9 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_numkey_styles" />
+ latin:keyboardLayout="@xml/key_styles_number" />
<Row>
<Key
latin:keyLabel="("
@@ -42,13 +42,12 @@
</Row>
<Row>
<Key
- latin:keyLabel="N" />
+ latin:keyLabel="N"
+ latin:keyStyle="numKeyBaseStyle" />
<!-- Pause is a comma. Check PhoneNumberUtils.java to see if this
has changed. -->
<Key
- latin:code="44"
- latin:keyLabel="@string/label_pause_key"
- latin:keyLabelOption="followKeyHintLabelRatio|autoXScale" />
+ latin:keyStyle="numPauseKeyStyle" />
<Key
latin:keyLabel=","
latin:keyStyle="numKeyStyle" />
@@ -62,9 +61,7 @@
latin:keyStyle="numStarKeyStyle" />
<!-- Wait is a semicolon. -->
<Key
- latin:code="59"
- latin:keyLabel="@string/label_wait_key"
- latin:keyLabelOption="followKeyHintLabelRatio|autoXScale" />
+ latin:keyStyle="numWaitKeyStyle" />
<Key
latin:keyLabel="#"
latin:keyStyle="numKeyStyle" />
@@ -74,14 +71,14 @@
</Row>
<Row>
<Key
- latin:keyStyle="numSwitchToNumericKeyStyle" />
+ latin:keyStyle="numPhoneToNumericKeyStyle" />
<Key
latin:keyLabel="+"
latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="numSpaceKeyStyle" />
<Key
- latin:keyStyle="returnKeyStyle"
+ latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml/kbd_rows_qwerty.xml b/java/res/xml/rows_qwerty.xml
index 6237712f6..71be44e31 100644
--- a/java/res/xml/kbd_rows_qwerty.xml
+++ b/java/res/xml/rows_qwerty.xml
@@ -22,13 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row1" />
+ latin:keyboardLayout="@xml/row_qwerty1" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row2" />
+ latin:keyboardLayout="@xml/row_qwerty2" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_qwertz.xml b/java/res/xml/rows_qwertz.xml
index 71bb601e6..11fd9332c 100644
--- a/java/res/xml/kbd_rows_qwertz.xml
+++ b/java/res/xml/rows_qwertz.xml
@@ -22,54 +22,61 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="10%p"
>
<Key
latin:keyLabel="q"
latin:keyHintLabel="1"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:additionalMoreKeys="1" />
<Key
latin:keyLabel="w"
latin:keyHintLabel="2"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:additionalMoreKeys="2" />
<Key
latin:keyLabel="e"
latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
latin:moreKeys="@string/more_keys_for_e" />
<Key
latin:keyLabel="r"
latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
latin:moreKeys="@string/more_keys_for_r" />
<Key
latin:keyLabel="t"
latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
latin:moreKeys="@string/more_keys_for_t" />
<Key
latin:keyLabel="z"
latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
latin:moreKeys="@string/more_keys_for_z" />
<Key
latin:keyLabel="u"
latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
latin:moreKeys="@string/more_keys_for_u" />
<Key
latin:keyLabel="i"
latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
latin:moreKeys="@string/more_keys_for_i" />
<Key
latin:keyLabel="o"
latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
latin:moreKeys="@string/more_keys_for_o" />
<Key
latin:keyLabel="p"
latin:keyHintLabel="0"
- latin:moreKeys="@string/more_keys_for_p"
+ latin:additionalMoreKeys="0"
latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row2" />
+ latin:keyboardLayout="@xml/row_qwerty2" />
<Row
latin:keyWidth="10%p"
>
@@ -101,5 +108,5 @@
latin:visualInsetsLeft="1%p" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_scandinavian.xml b/java/res/xml/rows_scandinavian.xml
index 4f138c514..f5ba96c27 100644
--- a/java/res/xml/kbd_rows_scandinavian.xml
+++ b/java/res/xml/rows_scandinavian.xml
@@ -22,52 +22,59 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="9.091%p"
>
<Key
latin:keyLabel="q"
latin:keyHintLabel="1"
- latin:moreKeys="@string/more_keys_for_q" />
+ latin:additionalMoreKeys="1" />
<Key
latin:keyLabel="w"
latin:keyHintLabel="2"
- latin:moreKeys="@string/more_keys_for_w" />
+ latin:additionalMoreKeys="2" />
<Key
latin:keyLabel="e"
latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
latin:moreKeys="@string/more_keys_for_e" />
<Key
latin:keyLabel="r"
latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
latin:moreKeys="@string/more_keys_for_r" />
<Key
latin:keyLabel="t"
latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
latin:moreKeys="@string/more_keys_for_t" />
<Key
latin:keyLabel="y"
latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
latin:moreKeys="@string/more_keys_for_y" />
<Key
latin:keyLabel="u"
latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
latin:moreKeys="@string/more_keys_for_u" />
<Key
latin:keyLabel="i"
latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
latin:moreKeys="@string/more_keys_for_i" />
<Key
latin:keyLabel="o"
latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
latin:moreKeys="@string/more_keys_for_o" />
<Key
latin:keyLabel="p"
latin:keyHintLabel="0"
- latin:moreKeys="@string/more_keys_for_p" />
+ latin:additionalMoreKeys="0" />
<Key
- latin:keyLabel="å"
+ latin:keyLabel="@string/keylabel_for_scandinavia_row1_11"
latin:keyWidth="fillRight" />
</Row>
<Row
@@ -75,8 +82,7 @@
>
<Key
latin:keyLabel="a"
- latin:moreKeys="@string/more_keys_for_a"
- latin:keyWidth="8.75%p" />
+ latin:moreKeys="@string/more_keys_for_a" />
<Key
latin:keyLabel="s"
latin:moreKeys="@string/more_keys_for_s" />
@@ -107,7 +113,7 @@
latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_serbian.xml b/java/res/xml/rows_serbian.xml
index da4d69521..d2203ce9c 100644
--- a/java/res/xml/kbd_rows_serbian.xml
+++ b/java/res/xml/rows_serbian.xml
@@ -22,50 +22,50 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="9.091%p"
>
<Key
latin:keyLabel="љ"
latin:keyHintLabel="1"
- latin:moreKeys="1" />
+ latin:additionalMoreKeys="1" />
<Key
latin:keyLabel="њ"
latin:keyHintLabel="2"
- latin:moreKeys="2" />
+ latin:additionalMoreKeys="2" />
<Key
latin:keyLabel="е"
latin:keyHintLabel="3"
- latin:moreKeys="3" />
+ latin:additionalMoreKeys="3" />
<Key
latin:keyLabel="р"
latin:keyHintLabel="4"
- latin:moreKeys="4" />
+ latin:additionalMoreKeys="4" />
<Key
latin:keyLabel="т"
latin:keyHintLabel="5"
- latin:moreKeys="5" />
+ latin:additionalMoreKeys="5" />
<Key
latin:keyLabel="з"
latin:keyHintLabel="6"
- latin:moreKeys="6" />
+ latin:additionalMoreKeys="6" />
<Key
latin:keyLabel="у"
latin:keyHintLabel="7"
- latin:moreKeys="7" />
+ latin:additionalMoreKeys="7" />
<Key
latin:keyLabel="и"
latin:keyHintLabel="8"
- latin:moreKeys="8" />
+ latin:additionalMoreKeys="8" />
<Key
latin:keyLabel="о"
latin:keyHintLabel="9"
- latin:moreKeys="9" />
+ latin:additionalMoreKeys="9" />
<Key
latin:keyLabel="п"
latin:keyHintLabel="0"
- latin:moreKeys="0" />
+ latin:additionalMoreKeys="0" />
<Key
latin:keyLabel="ш"
latin:keyWidth="fillRight" />
@@ -126,5 +126,5 @@
latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_russian.xml b/java/res/xml/rows_slavic.xml
index f1794e750..71e442c7c 100644
--- a/java/res/xml/kbd_rows_russian.xml
+++ b/java/res/xml/rows_slavic.xml
@@ -22,63 +22,66 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<Row
latin:keyWidth="9.091%p"
>
<Key
latin:keyLabel="й"
latin:keyHintLabel="1"
- latin:moreKeys="1" />
+ latin:additionalMoreKeys="1" />
<Key
latin:keyLabel="ц"
latin:keyHintLabel="2"
- latin:moreKeys="2" />
+ latin:additionalMoreKeys="2" />
<Key
latin:keyLabel="у"
latin:keyHintLabel="3"
- latin:moreKeys="3" />
+ latin:additionalMoreKeys="3"
+ latin:moreKeys="@string/more_keys_for_slavic_u" />
<Key
latin:keyLabel="к"
latin:keyHintLabel="4"
- latin:moreKeys="4" />
+ latin:additionalMoreKeys="4" />
<Key
latin:keyLabel="е"
latin:keyHintLabel="5"
- latin:moreKeys="@string/more_keys_for_cyrillic_e" />
+ latin:additionalMoreKeys="5"
+ latin:moreKeys="@string/more_keys_for_slavic_ye" />
<Key
latin:keyLabel="н"
latin:keyHintLabel="6"
- latin:moreKeys="6" />
+ latin:additionalMoreKeys="6"
+ latin:moreKeys="@string/more_keys_for_slavic_en" />
<Key
latin:keyLabel="г"
latin:keyHintLabel="7"
- latin:moreKeys="7" />
+ latin:additionalMoreKeys="7" />
<Key
latin:keyLabel="ш"
latin:keyHintLabel="8"
- latin:moreKeys="8" />
+ latin:additionalMoreKeys="8" />
<Key
- latin:keyLabel="щ"
+ latin:keyLabel="@string/keylabel_for_slavic_shcha"
latin:keyHintLabel="9"
- latin:moreKeys="9" />
+ latin:additionalMoreKeys="9" />
<Key
latin:keyLabel="з"
latin:keyHintLabel="0"
- latin:moreKeys="0" />
+ latin:additionalMoreKeys="0" />
<Key
latin:keyLabel="х"
- latin:moreKeys="@string/more_keys_for_cyrillic_ha"
+ latin:moreKeys="@string/more_keys_for_slavic_ha"
latin:keyWidth="fillRight" />
</Row>
<Row
latin:keyWidth="9.091%p"
>
<Key
- latin:keyLabel="ф"
- latin:keyWidth="8.75%p" />
+ latin:keyLabel="ф" />
<Key
- latin:keyLabel="ы" />
+ latin:keyLabel="@string/keylabel_for_slavic_yery"
+ latin:moreKeys="@string/more_keys_for_slavic_yery" />
<Key
latin:keyLabel="в" />
<Key
@@ -88,7 +91,8 @@
<Key
latin:keyLabel="р" />
<Key
- latin:keyLabel="о" />
+ latin:keyLabel="о"
+ latin:moreKeys="@string/more_keys_for_slavic_o" />
<Key
latin:keyLabel="л" />
<Key
@@ -114,12 +118,12 @@
<Key
latin:keyLabel="м" />
<Key
- latin:keyLabel="и" />
+ latin:keyLabel="@string/keylabel_for_slavic_i" />
<Key
latin:keyLabel="т" />
<Key
latin:keyLabel="ь"
- latin:moreKeys="@string/more_keys_for_cyrillic_soft_sign" />
+ latin:moreKeys="@string/more_keys_for_slavic_soft_sign" />
<Key
latin:keyLabel="б" />
<Key
@@ -129,5 +133,5 @@
latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_spanish.xml b/java/res/xml/rows_spanish.xml
index 03d631ee0..4b4cb9d1f 100644
--- a/java/res/xml/kbd_rows_spanish.xml
+++ b/java/res/xml/rows_spanish.xml
@@ -22,9 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row1" />
+ latin:keyboardLayout="@xml/row_qwerty1" />
<Row
latin:keyWidth="10%p"
>
@@ -56,7 +56,7 @@
latin:keyLabel="ñ" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ latin:keyboardLayout="@xml/row_qwerty3" />
<include
- latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/kbd_rows_symbols.xml b/java/res/xml/rows_symbols.xml
index c5bcb14c3..81a9a4602 100644
--- a/java/res/xml/kbd_rows_symbols.xml
+++ b/java/res/xml/rows_symbols.xml
@@ -22,41 +22,51 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_currency_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency" />
<Row
latin:keyWidth="10%p"
>
<Key
latin:keyLabel="@string/keylabel_for_symbols_1"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_1"
latin:moreKeys="@string/more_keys_for_symbols_1" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_2"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_2"
latin:moreKeys="@string/more_keys_for_symbols_2" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_3"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_3"
latin:moreKeys="@string/more_keys_for_symbols_3" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_4"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_4"
latin:moreKeys="@string/more_keys_for_symbols_4" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_5"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_5"
latin:moreKeys="@string/more_keys_for_symbols_5" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_6"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_6"
latin:moreKeys="@string/more_keys_for_symbols_6" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_7"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_7"
latin:moreKeys="@string/more_keys_for_symbols_7" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_8"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_8"
latin:moreKeys="@string/more_keys_for_symbols_8" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_9"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_9"
latin:moreKeys="@string/more_keys_for_symbols_9" />
<Key
latin:keyLabel="@string/keylabel_for_symbols_0"
+ latin:additionalMoreKeys="@string/additional_more_keys_for_symbols_0"
latin:moreKeys="@string/more_keys_for_symbols_0"
latin:keyWidth="fillRight" />
</Row>
@@ -83,13 +93,8 @@
<Key
latin:keyLabel="+"
latin:moreKeys="@string/more_keys_for_plus" />
- <Key
- latin:keyLabel="("
- latin:moreKeys="@string/more_keys_for_left_parenthesis" />
- <Key
- latin:keyLabel=")"
- latin:moreKeys="@string/more_keys_for_right_parenthesis"
- latin:keyWidth="fillRight" />
+ <include
+ latin:keyboardLayout="@xml/keys_parentheses" />
</Row>
<Row
latin:keyWidth="10%p"
@@ -101,15 +106,13 @@
<Key
latin:keyLabel="!"
latin:moreKeys="¡" />
- <!-- Note: Neither DroidSans nor Roboto have a glyph for ‟ Double high-reversed-9 quotation mark U+201F. -->
- <!-- latin:moreKeys="“,”,„,‟,«,»" -->
<Key
latin:keyLabel="&quot;"
- latin:moreKeys="“,”,«,»"
- latin:maxMoreKeysColumn="6" />
+ latin:moreKeys="@string/more_keys_for_double_quote"
+ latin:maxMoreKeysColumn="4" />
<Key
latin:keyLabel="\'"
- latin:moreKeys="‘,’,‚,‛" />
+ latin:moreKeys="@string/more_keys_for_single_quote" />
<Key
latin:keyLabel=":" />
<Key
@@ -126,5 +129,5 @@
latin:visualInsetsLeft="1%p" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_symbols_row4" />
+ latin:keyboardLayout="@xml/row_symbols4" />
</merge>
diff --git a/java/res/xml/kbd_rows_symbols_shift.xml b/java/res/xml/rows_symbols_shift.xml
index 91654b04b..828bd0624 100644
--- a/java/res/xml/kbd_rows_symbols_shift.xml
+++ b/java/res/xml/rows_symbols_shift.xml
@@ -22,9 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_common" />
<include
- latin:keyboardLayout="@xml/kbd_currency_key_styles" />
+ latin:keyboardLayout="@xml/key_styles_currency" />
<Row
latin:keyWidth="10%p"
>
@@ -46,11 +46,8 @@
latin:keyLabel="÷" />
<Key
latin:keyLabel="×" />
- <Key
- latin:keyLabel="{" />
- <Key
- latin:keyLabel="}"
- latin:keyWidth="fillRight" />
+ <include
+ latin:keyboardLayout="@xml/keys_curly_brackets" />
</Row>
<Row
latin:keyWidth="10%p"
@@ -74,11 +71,8 @@
<Key
latin:keyLabel="="
latin:moreKeys="≠,≈,∞" />
- <Key
- latin:keyLabel="[" />
- <Key
- latin:keyLabel="]"
- latin:keyWidth="fillRight" />
+ <include
+ latin:keyboardLayout="@xml/keys_square_brackets" />
</Row>
<Row
latin:keyWidth="10%p"
@@ -98,17 +92,13 @@
latin:moreKeys="§" />
<Key
latin:keyLabel="\\" />
- <Key
- latin:keyLabel="&lt;"
- latin:moreKeys="≤,«,‹" />
- <Key
- latin:keyLabel="&gt;"
- latin:moreKeys="≥,»,›" />
+ <include
+ latin:keyboardLayout="@xml/keys_less_greater" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight"
latin:visualInsetsLeft="1%p" />
</Row>
<include
- latin:keyboardLayout="@xml/kbd_symbols_shift_row4" />
+ latin:keyboardLayout="@xml/row_symbols_shift4" />
</merge>
diff --git a/java/res/xml/spell_checker_settings.xml b/java/res/xml/spell_checker_settings.xml
index f402555c9..222b98b6b 100644
--- a/java/res/xml/spell_checker_settings.xml
+++ b/java/res/xml/spell_checker_settings.xml
@@ -18,9 +18,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/android_spell_checker_settings">
<CheckBoxPreference
- android:key="use_proximity"
- android:title="@string/use_proximity_option_title"
- android:summary="@string/use_proximity_option_summary"
+ android:key="pref_spellcheck_use_contacts"
+ android:title="@string/use_contacts_for_spellchecking_option_title"
+ android:summary="@string/use_contacts_for_spellchecking_option_summary"
android:persistent="true"
android:defaultValue="true" />
</PreferenceScreen>
diff --git a/java/res/xml/spellchecker.xml b/java/res/xml/spellchecker.xml
index 30fac5b20..b48dc52cd 100644
--- a/java/res/xml/spellchecker.xml
+++ b/java/res/xml/spellchecker.xml
@@ -21,7 +21,8 @@
<!-- for the spell checker -->
<spell-checker xmlns:android="http://schemas.android.com/apk/res/android"
- android:label="@string/spell_checker_service_name">
+ android:label="@string/spell_checker_service_name"
+ android:settingsActivity="com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsActivity">
<subtype
android:label="@string/subtype_generic"
android:subtypeLocale="en"
@@ -42,4 +43,16 @@
android:label="@string/subtype_generic"
android:subtypeLocale="es"
/>
+ <subtype
+ android:label="@string/subtype_generic"
+ android:subtypeLocale="ru"
+ />
+ <subtype
+ android:label="@string/subtype_generic"
+ android:subtypeLocale="cs"
+ />
+ <subtype
+ android:label="@string/subtype_generic"
+ android:subtypeLocale="nl"
+ />
</spell-checker>
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index 46663327d..9caed00c9 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.accessibility;
import android.content.Context;
-import android.content.SharedPreferences;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.os.SystemClock;
@@ -55,15 +54,15 @@ public class AccessibilityUtils {
*/
private static final boolean ENABLE_ACCESSIBILITY = true;
- public static void init(InputMethodService inputMethod, SharedPreferences prefs) {
+ public static void init(InputMethodService inputMethod) {
if (!ENABLE_ACCESSIBILITY)
return;
// These only need to be initialized if the kill switch is off.
- sInstance.initInternal(inputMethod, prefs);
- KeyCodeDescriptionMapper.init(inputMethod, prefs);
- AccessibleInputMethodServiceProxy.init(inputMethod, prefs);
- AccessibleKeyboardViewProxy.init(inputMethod, prefs);
+ sInstance.initInternal(inputMethod);
+ KeyCodeDescriptionMapper.init();
+ AccessibleInputMethodServiceProxy.init(inputMethod);
+ AccessibleKeyboardViewProxy.init(inputMethod);
}
public static AccessibilityUtils getInstance() {
@@ -74,7 +73,7 @@ public class AccessibilityUtils {
// This class is not publicly instantiable.
}
- private void initInternal(Context context, SharedPreferences prefs) {
+ private void initInternal(Context context) {
mContext = context;
mAccessibilityManager = (AccessibilityManager) context
.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -120,8 +119,8 @@ public class AccessibilityUtils {
*
* @return {@code true} if the device should obscure password characters.
*/
- public boolean shouldObscureInput(EditorInfo attribute) {
- if (attribute == null)
+ public boolean shouldObscureInput(EditorInfo editorInfo) {
+ if (editorInfo == null)
return false;
// The user can optionally force speaking passwords.
@@ -137,7 +136,7 @@ public class AccessibilityUtils {
return false;
// Don't speak if the IME is connected to a password field.
- return InputTypeCompatUtils.isPasswordInputType(attribute.inputType);
+ return InputTypeCompatUtils.isPasswordInputType(editorInfo.inputType);
}
/**
@@ -171,11 +170,11 @@ public class AccessibilityUtils {
* Handles speaking the "connect a headset to hear passwords" notification
* when connecting to a password field.
*
- * @param attribute The input connection's editor info attribute.
+ * @param editorInfo The input connection's editor info attribute.
* @param restarting Whether the connection is being restarted.
*/
- public void onStartInputViewInternal(EditorInfo attribute, boolean restarting) {
- if (shouldObscureInput(attribute)) {
+ public void onStartInputViewInternal(EditorInfo editorInfo, boolean restarting) {
+ if (shouldObscureInput(editorInfo)) {
final CharSequence text = mContext.getText(R.string.spoken_use_headphones);
speak(text);
}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java
index 4ab9cb898..961176bb8 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java
@@ -17,31 +17,15 @@
package com.android.inputmethod.accessibility;
import android.content.Context;
-import android.content.SharedPreferences;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
-import android.os.Looper;
-import android.os.Message;
import android.os.Vibrator;
-import android.text.TextUtils;
import android.view.KeyEvent;
-import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
-
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActionListener {
private static final AccessibleInputMethodServiceProxy sInstance =
new AccessibleInputMethodServiceProxy();
- /*
- * Delay for the handler event that's fired when Accessibility is on and the
- * user hovers outside of any valid keys. This is used to let the user know
- * that if they lift their finger, nothing will be typed.
- */
- private static final long DELAY_NO_HOVER_SELECTION = 250;
-
/**
* Duration of the key click vibration in milliseconds.
*/
@@ -52,38 +36,9 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi
private InputMethodService mInputMethod;
private Vibrator mVibrator;
private AudioManager mAudioManager;
- private AccessibilityHandler mAccessibilityHandler;
- private static class AccessibilityHandler
- extends StaticInnerHandlerWrapper<AccessibleInputMethodServiceProxy> {
- private static final int MSG_NO_HOVER_SELECTION = 0;
-
- public AccessibilityHandler(AccessibleInputMethodServiceProxy outerInstance,
- Looper looper) {
- super(outerInstance, looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_NO_HOVER_SELECTION:
- getOuterInstance().notifyNoHoverSelection();
- break;
- }
- }
-
- public void postNoHoverSelection() {
- removeMessages(MSG_NO_HOVER_SELECTION);
- sendEmptyMessageDelayed(MSG_NO_HOVER_SELECTION, DELAY_NO_HOVER_SELECTION);
- }
-
- public void cancelNoHoverSelection() {
- removeMessages(MSG_NO_HOVER_SELECTION);
- }
- }
-
- public static void init(InputMethodService inputMethod, SharedPreferences prefs) {
- sInstance.initInternal(inputMethod, prefs);
+ public static void init(InputMethodService inputMethod) {
+ sInstance.initInternal(inputMethod);
}
public static AccessibleInputMethodServiceProxy getInstance() {
@@ -94,30 +49,10 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi
// Not publicly instantiable.
}
- private void initInternal(InputMethodService inputMethod, SharedPreferences prefs) {
+ private void initInternal(InputMethodService inputMethod) {
mInputMethod = inputMethod;
mVibrator = (Vibrator) inputMethod.getSystemService(Context.VIBRATOR_SERVICE);
mAudioManager = (AudioManager) inputMethod.getSystemService(Context.AUDIO_SERVICE);
- mAccessibilityHandler = new AccessibilityHandler(this, inputMethod.getMainLooper());
- }
-
- /**
- * If touch exploration is enabled, cancels the event sent by
- * {@link AccessibleInputMethodServiceProxy#onHoverExit(int)} because the
- * user is currently hovering above a key.
- */
- @Override
- public void onHoverEnter(int primaryCode) {
- mAccessibilityHandler.cancelNoHoverSelection();
- }
-
- /**
- * If touch exploration is enabled, sends a delayed event to notify the user
- * that they are not currently hovering above a key.
- */
- @Override
- public void onHoverExit(int primaryCode) {
- mAccessibilityHandler.postNoHoverSelection();
}
/**
@@ -125,8 +60,6 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi
*/
@Override
public void onFlickGesture(int direction) {
- final int keyEventCode;
-
switch (direction) {
case FlickGestureDetector.FLICK_LEFT:
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
@@ -148,27 +81,4 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi
mAudioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD, FX_VOLUME);
mInputMethod.sendDownUpKeyEvents(keyCode);
}
-
- /**
- * When Accessibility is turned on, notifies the user that they are not
- * currently hovering above a key. By default this will speak the currently
- * entered text.
- */
- private void notifyNoHoverSelection() {
- final ExtractedText extracted = mInputMethod.getCurrentInputConnection().getExtractedText(
- new ExtractedTextRequest(), 0);
-
- if (extracted == null)
- return;
-
- final CharSequence text;
-
- if (TextUtils.isEmpty(extracted.text)) {
- text = mInputMethod.getString(R.string.spoken_no_text_entered);
- } else {
- text = mInputMethod.getString(R.string.spoken_current_text_is, extracted.text);
- }
-
- AccessibilityUtils.getInstance().speak(text);
- }
}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java
index c1e92bec8..31d17d09f 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java
@@ -18,24 +18,6 @@ package com.android.inputmethod.accessibility;
public interface AccessibleKeyboardActionListener {
/**
- * Called when the user hovers inside a key. This is sent only when
- * Accessibility is turned on. For keys that repeat, this is only called
- * once.
- *
- * @param primaryCode the code of the key that was hovered over
- */
- public void onHoverEnter(int primaryCode);
-
- /**
- * Called when the user hovers outside a key. This is sent only when
- * Accessibility is turned on. For keys that repeat, this is only called
- * once.
- *
- * @param primaryCode the code of the key that was hovered over
- */
- public void onHoverExit(int primaryCode);
-
- /**
* @param direction the direction of the flick gesture, one of
* <ul>
* <li>{@link FlickGestureDetector#FLICK_UP}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index cef82267f..2294a18a0 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.accessibility;
import android.content.Context;
-import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Paint;
import android.inputmethodservice.InputMethodService;
@@ -29,9 +28,11 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.AccessibilityEventCompatUtils;
import com.android.inputmethod.compat.MotionEventCompatUtils;
import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.LatinKeyboardView;
import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.latin.R;
public class AccessibleKeyboardViewProxy {
private static final String TAG = AccessibleKeyboardViewProxy.class.getSimpleName();
@@ -42,10 +43,10 @@ public class AccessibleKeyboardViewProxy {
private LatinKeyboardView mView;
private AccessibleKeyboardActionListener mListener;
- private int mLastHoverKeyIndex = KeyDetector.NOT_A_KEY;
+ private Key mLastHoverKey = null;
- public static void init(InputMethodService inputMethod, SharedPreferences prefs) {
- sInstance.initInternal(inputMethod, prefs);
+ public static void init(InputMethodService inputMethod) {
+ sInstance.initInternal(inputMethod);
sInstance.mListener = AccessibleInputMethodServiceProxy.getInstance();
}
@@ -61,7 +62,7 @@ public class AccessibleKeyboardViewProxy {
// Not publicly instantiable.
}
- private void initInternal(InputMethodService inputMethod, SharedPreferences prefs) {
+ private void initInternal(InputMethodService inputMethod) {
final Paint paint = new Paint();
paint.setTextAlign(Paint.Align.LEFT);
paint.setTextSize(14.0f);
@@ -72,8 +73,7 @@ public class AccessibleKeyboardViewProxy {
mGestureDetector = new KeyboardFlickGestureDetector(inputMethod);
}
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event,
- PointerTracker tracker) {
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
if (mView == null) {
Log.e(TAG, "No keyboard view set!");
return false;
@@ -81,7 +81,7 @@ public class AccessibleKeyboardViewProxy {
switch (event.getEventType()) {
case AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER:
- final Key key = tracker.getKey(mLastHoverKeyIndex);
+ final Key key = mLastHoverKey;
if (key == null)
break;
@@ -130,12 +130,12 @@ public class AccessibleKeyboardViewProxy {
switch (event.getAction()) {
case MotionEventCompatUtils.ACTION_HOVER_ENTER:
case MotionEventCompatUtils.ACTION_HOVER_MOVE:
- final int keyIndex = tracker.getKeyIndexOn(x, y);
+ final Key key = tracker.getKeyOn(x, y);
- if (keyIndex != mLastHoverKeyIndex) {
- fireKeyHoverEvent(tracker, mLastHoverKeyIndex, false);
- mLastHoverKeyIndex = keyIndex;
- fireKeyHoverEvent(tracker, mLastHoverKeyIndex, true);
+ if (key != mLastHoverKey) {
+ fireKeyHoverEvent(mLastHoverKey, false);
+ mLastHoverKey = key;
+ fireKeyHoverEvent(mLastHoverKey, true);
}
return true;
@@ -144,7 +144,7 @@ public class AccessibleKeyboardViewProxy {
return false;
}
- private void fireKeyHoverEvent(PointerTracker tracker, int keyIndex, boolean entering) {
+ private void fireKeyHoverEvent(Key key, boolean entering) {
if (mListener == null) {
Log.e(TAG, "No accessible keyboard action listener set!");
return;
@@ -155,19 +155,12 @@ public class AccessibleKeyboardViewProxy {
return;
}
- if (keyIndex == KeyDetector.NOT_A_KEY)
- return;
-
- final Key key = tracker.getKey(keyIndex);
-
if (key == null)
return;
if (entering) {
- mListener.onHoverEnter(key.mCode);
mView.sendAccessibilityEvent(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER);
} else {
- mListener.onHoverExit(key.mCode);
mView.sendAccessibilityEvent(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_EXIT);
}
}
@@ -185,4 +178,71 @@ public class AccessibleKeyboardViewProxy {
return true;
}
}
+
+ /**
+ * Notifies the user of changes in the keyboard shift state.
+ */
+ public void notifyShiftState() {
+ final Keyboard keyboard = mView.getKeyboard();
+ final KeyboardId keyboardId = keyboard.mId;
+ final int elementId = keyboardId.mElementId;
+ final Context context = mView.getContext();
+ final CharSequence text;
+
+ switch (elementId) {
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
+ text = context.getText(R.string.spoken_description_shiftmode_locked);
+ break;
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
+ case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
+ text = context.getText(R.string.spoken_description_shiftmode_on);
+ break;
+ default:
+ text = context.getText(R.string.spoken_description_shiftmode_off);
+ }
+
+ AccessibilityUtils.getInstance().speak(text);
+ }
+
+ /**
+ * Notifies the user of changes in the keyboard symbols state.
+ */
+ public void notifySymbolsState() {
+ final Keyboard keyboard = mView.getKeyboard();
+ final Context context = mView.getContext();
+ final KeyboardId keyboardId = keyboard.mId;
+ final int elementId = keyboardId.mElementId;
+ final int resId;
+
+ switch (elementId) {
+ case KeyboardId.ELEMENT_ALPHABET:
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
+ resId = R.string.spoken_description_mode_alpha;
+ break;
+ case KeyboardId.ELEMENT_SYMBOLS:
+ case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
+ resId = R.string.spoken_description_mode_symbol;
+ break;
+ case KeyboardId.ELEMENT_PHONE:
+ resId = R.string.spoken_description_mode_phone;
+ break;
+ case KeyboardId.ELEMENT_PHONE_SYMBOLS:
+ resId = R.string.spoken_description_mode_phone_shift;
+ break;
+ default:
+ resId = -1;
+ }
+
+ if (resId < 0) {
+ return;
+ }
+
+ final String text = context.getString(resId);
+ AccessibilityUtils.getInstance().speak(text);
+ }
}
diff --git a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java
index 9d99e3131..db12f76ad 100644
--- a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java
+++ b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java
@@ -126,7 +126,6 @@ public abstract class FlickGestureDetector {
}
final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event);
- final long timeout = event.getEventTime() - mCachedHoverEnter.getEventTime();
switch (event.getAction()) {
case MotionEventCompatUtils.ACTION_HOVER_MOVE:
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 7302830d4..f0dba4a02 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.accessibility;
import android.content.Context;
-import android.content.SharedPreferences;
import android.text.TextUtils;
import com.android.inputmethod.keyboard.Key;
@@ -39,14 +38,8 @@ public class KeyCodeDescriptionMapper {
// Map of key codes to spoken description resource IDs
private final HashMap<Integer, Integer> mKeyCodeMap;
- // Map of shifted key codes to spoken description resource IDs
- private final HashMap<Integer, Integer> mShiftedKeyCodeMap;
-
- // Map of shift-locked key codes to spoken description resource IDs
- private final HashMap<Integer, Integer> mShiftLockedKeyCodeMap;
-
- public static void init(Context context, SharedPreferences prefs) {
- sInstance.initInternal(context, prefs);
+ public static void init() {
+ sInstance.initInternal();
}
public static KeyCodeDescriptionMapper getInstance() {
@@ -56,40 +49,15 @@ public class KeyCodeDescriptionMapper {
private KeyCodeDescriptionMapper() {
mKeyLabelMap = new HashMap<CharSequence, Integer>();
mKeyCodeMap = new HashMap<Integer, Integer>();
- mShiftedKeyCodeMap = new HashMap<Integer, Integer>();
- mShiftLockedKeyCodeMap = new HashMap<Integer, Integer>();
}
- private void initInternal(Context context, SharedPreferences prefs) {
+ private void initInternal() {
// Manual label substitutions for key labels with no string resource
mKeyLabelMap.put(":-)", R.string.spoken_description_smiley);
// Symbols that most TTS engines can't speak
- mKeyCodeMap.put((int) '.', R.string.spoken_description_period);
- mKeyCodeMap.put((int) ',', R.string.spoken_description_comma);
- mKeyCodeMap.put((int) '(', R.string.spoken_description_left_parenthesis);
- mKeyCodeMap.put((int) ')', R.string.spoken_description_right_parenthesis);
- mKeyCodeMap.put((int) ':', R.string.spoken_description_colon);
- mKeyCodeMap.put((int) ';', R.string.spoken_description_semicolon);
- mKeyCodeMap.put((int) '!', R.string.spoken_description_exclamation_mark);
- mKeyCodeMap.put((int) '?', R.string.spoken_description_question_mark);
- mKeyCodeMap.put((int) '\"', R.string.spoken_description_double_quote);
- mKeyCodeMap.put((int) '\'', R.string.spoken_description_single_quote);
- mKeyCodeMap.put((int) '*', R.string.spoken_description_star);
- mKeyCodeMap.put((int) '#', R.string.spoken_description_pound);
mKeyCodeMap.put((int) ' ', R.string.spoken_description_space);
- // Non-ASCII symbols (must use escape codes!)
- mKeyCodeMap.put((int) '\u2022', R.string.spoken_description_dot);
- mKeyCodeMap.put((int) '\u221A', R.string.spoken_description_square_root);
- mKeyCodeMap.put((int) '\u03C0', R.string.spoken_description_pi);
- mKeyCodeMap.put((int) '\u0394', R.string.spoken_description_delta);
- mKeyCodeMap.put((int) '\u2122', R.string.spoken_description_trademark);
- mKeyCodeMap.put((int) '\u2105', R.string.spoken_description_care_of);
- mKeyCodeMap.put((int) '\u2026', R.string.spoken_description_ellipsis);
- mKeyCodeMap.put((int) '\u201E', R.string.spoken_description_low_double_quote);
- mKeyCodeMap.put((int) '\uFF0A', R.string.spoken_description_star);
-
// Special non-character codes defined in Keyboard
mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete);
mKeyCodeMap.put(Keyboard.CODE_ENTER, R.string.spoken_description_return);
@@ -98,12 +66,6 @@ public class KeyCodeDescriptionMapper {
mKeyCodeMap.put(Keyboard.CODE_SHORTCUT, R.string.spoken_description_mic);
mKeyCodeMap.put(Keyboard.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol);
mKeyCodeMap.put(Keyboard.CODE_TAB, R.string.spoken_description_tab);
-
- // Shifted versions of non-character codes defined in Keyboard
- mShiftedKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift_shifted);
-
- // Shift-locked versions of non-character codes defined in Keyboard
- mShiftLockedKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_caps_lock);
}
/**
@@ -127,25 +89,29 @@ public class KeyCodeDescriptionMapper {
*/
public CharSequence getDescriptionForKey(Context context, Keyboard keyboard, Key key,
boolean shouldObscure) {
- if (key.mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ final int code = key.mCode;
+
+ if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
final CharSequence description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
if (description != null)
return description;
}
+ if (code == Keyboard.CODE_SHIFT) {
+ return getDescriptionForShiftKey(context, keyboard);
+ }
+
if (!TextUtils.isEmpty(key.mLabel)) {
final String label = key.mLabel.toString().trim();
+ // First, attempt to map the label to a pre-defined description.
if (mKeyLabelMap.containsKey(label)) {
return context.getString(mKeyLabelMap.get(label));
- } else if (label.length() == 1
- || (keyboard.isManualTemporaryUpperCase() && !TextUtils
- .isEmpty(key.mHintLabel))) {
- return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
- } else {
- return label;
}
- } else if (key.mCode != Keyboard.CODE_DUMMY) {
+ }
+
+ // Just attempt to speak the description.
+ if (key.mCode != Keyboard.CODE_UNSPECIFIED) {
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
}
@@ -163,35 +129,66 @@ public class KeyCodeDescriptionMapper {
* the key
*/
private CharSequence getDescriptionForSwitchAlphaSymbol(Context context, Keyboard keyboard) {
- final KeyboardId id = keyboard.mId;
-
- if (id.isAlphabetKeyboard()) {
- return context.getString(R.string.spoken_description_to_symbol);
- } else if (id.isSymbolsKeyboard()) {
- return context.getString(R.string.spoken_description_to_alpha);
- } else if (id.isPhoneShiftKeyboard()) {
- return context.getString(R.string.spoken_description_to_numeric);
- } else if (id.isPhoneKeyboard()) {
- return context.getString(R.string.spoken_description_to_symbol);
- } else {
+ final KeyboardId keyboardId = keyboard.mId;
+ final int elementId = keyboardId.mElementId;
+ final int resId;
+
+ switch (elementId) {
+ case KeyboardId.ELEMENT_ALPHABET:
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
+ resId = R.string.spoken_description_to_symbol;
+ break;
+ case KeyboardId.ELEMENT_SYMBOLS:
+ case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
+ resId = R.string.spoken_description_to_alpha;
+ break;
+ case KeyboardId.ELEMENT_PHONE:
+ resId = R.string.spoken_description_to_symbol;
+ break;
+ case KeyboardId.ELEMENT_PHONE_SYMBOLS:
+ resId = R.string.spoken_description_to_numeric;
+ break;
+ default:
+ resId = -1;
+ }
+
+ if (resId < 0) {
return null;
}
+
+ return context.getString(resId);
}
/**
- * Returns the keycode for the specified key given the current keyboard
- * state.
+ * Returns a context-sensitive description of the "Shift" key.
*
+ * @param context The package's context.
* @param keyboard The keyboard on which the key resides.
- * @param key The key from which to obtain a key code.
- * @return the key code for the specified key
+ * @return A context-sensitive description of the "Shift" key.
*/
- private int getCorrectKeyCode(Keyboard keyboard, Key key) {
- if (keyboard.isManualTemporaryUpperCase() && !TextUtils.isEmpty(key.mHintLabel)) {
- return key.mHintLabel.charAt(0);
- } else {
- return key.mCode;
+ private CharSequence getDescriptionForShiftKey(Context context, Keyboard keyboard) {
+ final KeyboardId keyboardId = keyboard.mId;
+ final int elementId = keyboardId.mElementId;
+ final int resId;
+
+ switch (elementId) {
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
+ resId = R.string.spoken_description_caps_lock;
+ break;
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
+ case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
+ resId = R.string.spoken_description_shift_shifted;
+ break;
+ default:
+ resId = R.string.spoken_description_shift;
}
+
+ return context.getString(resId);
}
/**
@@ -217,13 +214,7 @@ public class KeyCodeDescriptionMapper {
*/
private CharSequence getDescriptionForKeyCode(Context context, Keyboard keyboard, Key key,
boolean shouldObscure) {
- final int code = getCorrectKeyCode(keyboard, key);
-
- if (keyboard.isShiftLocked() && mShiftLockedKeyCodeMap.containsKey(code)) {
- return context.getString(mShiftLockedKeyCodeMap.get(code));
- } else if (keyboard.isShiftedOrShiftLocked() && mShiftedKeyCodeMap.containsKey(code)) {
- return context.getString(mShiftedKeyCodeMap.get(code));
- }
+ final int code = key.mCode;
// If the key description should be obscured, now is the time to do it.
final boolean isDefinedNonCtrl = Character.isDefined(code) && !Character.isISOControl(code);
diff --git a/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java b/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java
index f6afbcfe2..011473bef 100644
--- a/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java
@@ -16,10 +16,14 @@
package com.android.inputmethod.compat;
+import android.util.Log;
+
import java.lang.reflect.Method;
import java.util.Arrays;
public class ArraysCompatUtils {
+ private static final String TAG = ArraysCompatUtils.class.getSimpleName();
+
private static final Method METHOD_Arrays_binarySearch = CompatUtils
.getMethod(Arrays.class, "binarySearch", int[].class, int.class, int.class, int.class);
@@ -33,8 +37,15 @@ public class ArraysCompatUtils {
}
}
- /* package */ static int compatBinarySearch(int[] array, int startIndex, int endIndex,
- int value) {
+ // TODO: Implement fast binary search
+ /* package for testing */
+ static int compatBinarySearch(int[] array, int startIndex, int endIndex, int value) {
+ // Output error log because this method has strict performance penalty.
+ // Note that this method has been called only from spell checker and spell checker exists
+ // only from IceCreamSandwich and after, so that there is no chance on pre-ICS device to
+ // invoke this method.
+ Log.e(TAG, "Invoked expensive binarySearch");
+
if (startIndex > endIndex) throw new IllegalArgumentException();
if (startIndex < 0 || endIndex > array.length) throw new ArrayIndexOutOfBoundsException();
diff --git a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
index bcdcef7dc..3247997f6 100644
--- a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
@@ -26,12 +26,16 @@ public class EditorInfoCompatUtils {
EditorInfo.class, "IME_FLAG_NAVIGATE_NEXT");
private static final Field FIELD_IME_FLAG_NAVIGATE_PREVIOUS = CompatUtils.getField(
EditorInfo.class, "IME_FLAG_NAVIGATE_PREVIOUS");
+ private static final Field FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField(
+ EditorInfo.class, "IME_FLAG_FORCE_ASCII");
private static final Field FIELD_IME_ACTION_PREVIOUS = CompatUtils.getField(
EditorInfo.class, "IME_ACTION_PREVIOUS");
private static final Integer OBJ_IME_FLAG_NAVIGATE_NEXT = (Integer) CompatUtils
.getFieldValue(null, null, FIELD_IME_FLAG_NAVIGATE_NEXT);
private static final Integer OBJ_IME_FLAG_NAVIGATE_PREVIOUS = (Integer) CompatUtils
.getFieldValue(null, null, FIELD_IME_FLAG_NAVIGATE_PREVIOUS);
+ private static final Integer OBJ_IME_FLAG_FORCE_ASCII = (Integer) CompatUtils
+ .getFieldValue(null, null, FIELD_IME_FLAG_FORCE_ASCII);
private static final Integer OBJ_IME_ACTION_PREVIOUS = (Integer) CompatUtils
.getFieldValue(null, null, FIELD_IME_ACTION_PREVIOUS);
@@ -47,6 +51,12 @@ public class EditorInfoCompatUtils {
return (imeOptions & OBJ_IME_FLAG_NAVIGATE_PREVIOUS) != 0;
}
+ public static boolean hasFlagForceAscii(int imeOptions) {
+ if (OBJ_IME_FLAG_FORCE_ASCII == null)
+ return false;
+ return (imeOptions & OBJ_IME_FLAG_FORCE_ASCII) != 0;
+ }
+
public static void performEditorActionNext(InputConnection ic) {
ic.performEditorAction(EditorInfo.IME_ACTION_NEXT);
}
@@ -57,46 +67,47 @@ public class EditorInfoCompatUtils {
ic.performEditorAction(OBJ_IME_ACTION_PREVIOUS);
}
- public static String imeOptionsName(int imeOptions) {
- if (imeOptions == -1)
- return null;
+ public static String imeActionName(int imeOptions) {
final int actionId = imeOptions & EditorInfo.IME_MASK_ACTION;
- final String action;
switch (actionId) {
- case EditorInfo.IME_ACTION_UNSPECIFIED:
- action = "actionUnspecified";
- break;
- case EditorInfo.IME_ACTION_NONE:
- action = "actionNone";
- break;
- case EditorInfo.IME_ACTION_GO:
- action = "actionGo";
- break;
- case EditorInfo.IME_ACTION_SEARCH:
- action = "actionSearch";
- break;
- case EditorInfo.IME_ACTION_SEND:
- action = "actionSend";
- break;
- case EditorInfo.IME_ACTION_NEXT:
- action = "actionNext";
- break;
- case EditorInfo.IME_ACTION_DONE:
- action = "actionDone";
- break;
- default: {
- if (OBJ_IME_ACTION_PREVIOUS != null && actionId == OBJ_IME_ACTION_PREVIOUS) {
- action = "actionPrevious";
- } else {
- action = "actionUnknown(" + actionId + ")";
- }
- break;
+ case EditorInfo.IME_ACTION_UNSPECIFIED:
+ return "actionUnspecified";
+ case EditorInfo.IME_ACTION_NONE:
+ return "actionNone";
+ case EditorInfo.IME_ACTION_GO:
+ return "actionGo";
+ case EditorInfo.IME_ACTION_SEARCH:
+ return "actionSearch";
+ case EditorInfo.IME_ACTION_SEND:
+ return "actionSend";
+ case EditorInfo.IME_ACTION_NEXT:
+ return "actionNext";
+ case EditorInfo.IME_ACTION_DONE:
+ return "actionDone";
+ default:
+ if (OBJ_IME_ACTION_PREVIOUS != null && actionId == OBJ_IME_ACTION_PREVIOUS) {
+ return "actionPrevious";
+ } else {
+ return "actionUnknown(" + actionId + ")";
}
}
+ }
+
+ public static String imeOptionsName(int imeOptions) {
+ final String action = imeActionName(imeOptions);
+ final StringBuilder flags = new StringBuilder();
if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
- return "flagNoEnterAction|" + action;
- } else {
- return action;
+ flags.append("flagNoEnterAction|");
+ }
+ if (hasFlagNavigateNext(imeOptions)) {
+ flags.append("flagNavigateNext|");
+ }
+ if (hasFlagNavigatePrevious(imeOptions)) {
+ flags.append("flagNavigatePrevious|");
+ }
+ if (hasFlagForceAscii(imeOptions)) {
+ flags.append("flagForceAscii|");
}
+ return (action != null) ? flags + action : flags.toString();
}
}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
index 51dc4cd37..0e5f8c80a 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
@@ -153,8 +153,7 @@ public class InputMethodManagerCompatWrapper {
return Utils.getInputMethodInfo(this, mLatinImePackageName);
}
- @SuppressWarnings("unused")
- private InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) {
+ private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) {
if (VOICE_MODE.equals(mode) && !FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES)
return null;
Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale();
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index 161ef09b8..f476d83b4 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -50,19 +50,19 @@ public class SuggestionSpanUtils {
.getConstructor(CLASS_SuggestionSpan, INPUT_TYPE_SuggestionSpan);
public static final Field FIELD_FLAG_AUTO_CORRECTION
= CompatUtils.getField(CLASS_SuggestionSpan, "FLAG_AUTO_CORRECTION");
- public static final Field FIELD_SUGGESTION_MAX_SIZE
+ public static final Field FIELD_SUGGESTIONS_MAX_SIZE
= CompatUtils.getField(CLASS_SuggestionSpan, "SUGGESTIONS_MAX_SIZE");
public static final Integer OBJ_FLAG_AUTO_CORRECTION = (Integer) CompatUtils
.getFieldValue(null, null, FIELD_FLAG_AUTO_CORRECTION);;
- public static final Integer OBJ_SUGGESTION_MAX_SIZE = (Integer) CompatUtils
- .getFieldValue(null, null, FIELD_SUGGESTION_MAX_SIZE);;
+ public static final Integer OBJ_SUGGESTIONS_MAX_SIZE = (Integer) CompatUtils
+ .getFieldValue(null, null, FIELD_SUGGESTIONS_MAX_SIZE);;
static {
SUGGESTION_SPAN_IS_SUPPORTED =
CLASS_SuggestionSpan != null && CONSTRUCTOR_SuggestionSpan != null;
if (LatinImeLogger.sDBG) {
if (SUGGESTION_SPAN_IS_SUPPORTED
- && (OBJ_FLAG_AUTO_CORRECTION == null || OBJ_SUGGESTION_MAX_SIZE == null)) {
+ && (OBJ_FLAG_AUTO_CORRECTION == null || OBJ_SUGGESTIONS_MAX_SIZE == null)) {
throw new RuntimeException("Field is accidentially null.");
}
}
@@ -71,7 +71,7 @@ public class SuggestionSpanUtils {
public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
Context context, CharSequence text) {
if (TextUtils.isEmpty(text) || CONSTRUCTOR_SuggestionSpan == null
- || OBJ_FLAG_AUTO_CORRECTION == null || OBJ_SUGGESTION_MAX_SIZE == null) {
+ || OBJ_FLAG_AUTO_CORRECTION == null || OBJ_SUGGESTIONS_MAX_SIZE == null) {
return text;
}
final Spannable spannable = text instanceof Spannable
@@ -94,7 +94,7 @@ public class SuggestionSpanUtils {
if (TextUtils.isEmpty(pickedWord) || CONSTRUCTOR_SuggestionSpan == null
|| suggestedWords == null || suggestedWords.size() == 0
|| suggestedWords.getInfo(0).isObsoleteSuggestedWord()
- || OBJ_SUGGESTION_MAX_SIZE == null) {
+ || OBJ_SUGGESTIONS_MAX_SIZE == null) {
return pickedWord;
}
@@ -106,7 +106,7 @@ public class SuggestionSpanUtils {
}
final ArrayList<String> suggestionsList = new ArrayList<String>();
for (int i = 0; i < suggestedWords.size(); ++i) {
- if (suggestionsList.size() >= OBJ_SUGGESTION_MAX_SIZE) {
+ if (suggestionsList.size() >= OBJ_SUGGESTIONS_MAX_SIZE) {
break;
}
final CharSequence word = suggestedWords.getWord(i);
diff --git a/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java
new file mode 100644
index 000000000..6a0d4dd9e
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.compat;
+
+import android.view.textservice.SuggestionsInfo;
+
+import java.lang.reflect.Field;
+
+public class SuggestionsInfoCompatUtils {
+ private static final Field FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = CompatUtils.getField(
+ SuggestionsInfo.class, "RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS");
+ private static final Integer OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = (Integer) CompatUtils
+ .getFieldValue(null, null, FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS);;
+ private static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS =
+ OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS != null
+ ? OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS : 0;
+
+ private SuggestionsInfoCompatUtils() {
+ }
+
+ /**
+ * Returns the flag value of the attributes of the suggestions that can be obtained by
+ * {@link #getSuggestionsAttributes}: this tells that the text service thinks
+ * the result suggestions include highly recommended ones.
+ */
+ public static int getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() {
+ return RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS;
+ }
+}
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index 3f8c2ef8f..f632b0e02 100644
--- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -16,23 +16,6 @@
package com.android.inputmethod.deprecated;
-import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
-import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
-import com.android.inputmethod.compat.SharedPreferencesCompat;
-import com.android.inputmethod.deprecated.voice.FieldContext;
-import com.android.inputmethod.deprecated.voice.Hints;
-import com.android.inputmethod.deprecated.voice.SettingsUtil;
-import com.android.inputmethod.deprecated.voice.VoiceInput;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.latin.EditingUtils;
-import com.android.inputmethod.latin.LatinIME;
-import com.android.inputmethod.latin.LatinIME.UIHandler;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.Utils;
-
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
@@ -63,6 +46,24 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.widget.TextView;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
+import com.android.inputmethod.compat.SharedPreferencesCompat;
+import com.android.inputmethod.deprecated.voice.FieldContext;
+import com.android.inputmethod.deprecated.voice.Hints;
+import com.android.inputmethod.deprecated.voice.SettingsUtil;
+import com.android.inputmethod.deprecated.voice.VoiceInput;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.keyboard.LatinKeyboardView;
+import com.android.inputmethod.latin.EditingUtils;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinIME.UIHandler;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.Utils;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -695,12 +696,12 @@ public class VoiceProxy implements VoiceInput.UiListener {
&& !mVoiceInput.isBlacklistedField(fieldContext);
}
- private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) {
+ private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo editorInfo) {
@SuppressWarnings("deprecation")
final boolean noMic = Utils.inPrivateImeOptions(null,
- LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, attribute)
+ LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo)
|| Utils.inPrivateImeOptions(mService.getPackageName(),
- LatinIME.IME_OPTION_NO_MICROPHONE, attribute);
+ LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo);
return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext) && !noMic
&& SpeechRecognizer.isRecognitionAvailable(mService);
}
@@ -709,7 +710,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
return SpeechRecognizer.isRecognitionAvailable(context);
}
- public void loadSettings(EditorInfo attribute, SharedPreferences sp) {
+ public void loadSettings(EditorInfo editorInfo, SharedPreferences sp) {
if (!VOICE_INSTALLED) {
return;
}
@@ -723,7 +724,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
final String voiceMode = sp.getString(PREF_VOICE_MODE,
mService.getString(R.string.voice_mode_main));
mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off))
- && shouldShowVoiceButton(makeFieldContext(), attribute);
+ && shouldShowVoiceButton(makeFieldContext(), editorInfo);
mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main));
}
@@ -747,8 +748,9 @@ public class VoiceProxy implements VoiceInput.UiListener {
// keep showing the warning.
if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) {
// Close keyboard view if it is been shown.
- if (KeyboardSwitcher.getInstance().isInputViewShown())
- KeyboardSwitcher.getInstance().getKeyboardView().purgeKeyboardAndClosing();
+ final LatinKeyboardView keyboardView = KeyboardSwitcher.getInstance().getKeyboardView();
+ if (keyboardView != null && keyboardView.isShown())
+ keyboardView.purgeKeyboardAndClosing();
startListening(false, windowToken);
}
// If we have no token, onAttachedToWindow will take care of showing dialog and start
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
index dbe7aec6a..e75e14861 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -17,7 +17,7 @@
package com.android.inputmethod.deprecated.languageswitcher;
import com.android.inputmethod.compat.SharedPreferencesCompat;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
+import com.android.inputmethod.keyboard.KeyboardSet;
import com.android.inputmethod.latin.DictionaryFactory;
import com.android.inputmethod.latin.LocaleUtils;
import com.android.inputmethod.latin.R;
@@ -162,8 +162,8 @@ public class InputLanguageSelection extends PreferenceActivity {
try {
final String localeStr = locale.toString();
- final String[] layoutCountryCodes = KeyboardBuilder.parseKeyboardLocale(
- this, R.xml.kbd_qwerty).split(",", -1);
+ final String[] layoutCountryCodes = KeyboardSet.parseKeyboardLocale(
+ getResources(), R.xml.keyboard_set).split(",", -1);
if (!TextUtils.isEmpty(localeStr) && layoutCountryCodes.length > 0) {
for (String s : layoutCountryCodes) {
if (s.equals(localeStr)) {
diff --git a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
index 3c79cc218..fd2cf3d25 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
@@ -43,10 +43,10 @@ public class FieldContext {
Bundle mFieldInfo;
- public FieldContext(InputConnection conn, EditorInfo info,
+ public FieldContext(InputConnection conn, EditorInfo editorInfo,
String selectedLanguage, String[] enabledLanguages) {
mFieldInfo = new Bundle();
- addEditorInfoToBundle(info, mFieldInfo);
+ addEditorInfoToBundle(editorInfo, mFieldInfo);
addInputConnectionToBundle(conn, mFieldInfo);
addLanguageInfoToBundle(selectedLanguage, enabledLanguages, mFieldInfo);
if (DBG) Log.i("FieldContext", "Bundle = " + mFieldInfo.toString());
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index f1ae0b313..cf3a437cf 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -22,56 +22,64 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Xml;
+import com.android.inputmethod.keyboard.internal.KeySpecParser;
import com.android.inputmethod.keyboard.internal.KeyStyles;
import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder.ParseException;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
-import com.android.inputmethod.keyboard.internal.KeyboardParams;
-import com.android.inputmethod.keyboard.internal.MoreKeySpecParser;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.XmlParseUtils;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Arrays;
/**
* Class for describing the position and characteristics of a single key in the keyboard.
*/
public class Key {
+ private static final String TAG = Key.class.getSimpleName();
+
/**
* The key code (unicode or custom code) that this key generates.
*/
public final int mCode;
+ public final int mAltCode;
/** Label to display */
- public final CharSequence mLabel;
+ public final String mLabel;
/** Hint label to display on the key in conjunction with the label */
- public final CharSequence mHintLabel;
- /** Option of the label */
- private final int mLabelOption;
- private static final int LABEL_OPTION_ALIGN_LEFT = 0x01;
- private static final int LABEL_OPTION_ALIGN_RIGHT = 0x02;
- private static final int LABEL_OPTION_ALIGN_LEFT_OF_CENTER = 0x08;
- private static final int LABEL_OPTION_LARGE_LETTER = 0x10;
- private static final int LABEL_OPTION_FONT_NORMAL = 0x20;
- private static final int LABEL_OPTION_FONT_MONO_SPACE = 0x40;
- private static final int LABEL_OPTION_FOLLOW_KEY_LETTER_RATIO = 0x80;
- private static final int LABEL_OPTION_FOLLOW_KEY_HINT_LABEL_RATIO = 0x100;
- private static final int LABEL_OPTION_HAS_POPUP_HINT = 0x200;
- private static final int LABEL_OPTION_HAS_UPPERCASE_LETTER = 0x400;
- private static final int LABEL_OPTION_HAS_HINT_LABEL = 0x800;
- private static final int LABEL_OPTION_WITH_ICON_LEFT = 0x1000;
- private static final int LABEL_OPTION_WITH_ICON_RIGHT = 0x2000;
- private static final int LABEL_OPTION_AUTO_X_SCALE = 0x4000;
+ public final String mHintLabel;
+ /** Flags of the label */
+ private final int mLabelFlags;
+ private static final int LABEL_FLAGS_ALIGN_LEFT = 0x01;
+ private static final int LABEL_FLAGS_ALIGN_RIGHT = 0x02;
+ private static final int LABEL_FLAGS_ALIGN_LEFT_OF_CENTER = 0x08;
+ private static final int LABEL_FLAGS_LARGE_LETTER = 0x10;
+ private static final int LABEL_FLAGS_FONT_NORMAL = 0x20;
+ private static final int LABEL_FLAGS_FONT_MONO_SPACE = 0x40;
+ private static final int LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO = 0x80;
+ private static final int LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO = 0x100;
+ private static final int LABEL_FLAGS_HAS_POPUP_HINT = 0x200;
+ private static final int LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT = 0x400;
+ private static final int LABEL_FLAGS_HAS_HINT_LABEL = 0x800;
+ private static final int LABEL_FLAGS_WITH_ICON_LEFT = 0x1000;
+ private static final int LABEL_FLAGS_WITH_ICON_RIGHT = 0x2000;
+ private static final int LABEL_FLAGS_AUTO_X_SCALE = 0x4000;
+ private static final int LABEL_FLAGS_PRESERVE_CASE = 0x8000;
+ private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x10000;
+ private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x20000;
/** Icon to display instead of a label. Icon takes precedence over a label */
- private Drawable mIcon;
+ private final int mIconId;
+ /** Icon for disabled state */
+ private final int mDisabledIconId;
/** Preview version of the icon, for the preview popup */
- private Drawable mPreviewIcon;
+ private final int mPreviewIconId;
/** Width of the key, not including the gap */
public final int mWidth;
@@ -94,7 +102,7 @@ public class Key {
/** Text to output when pressed. This can be multiple characters, like ".com" */
public final CharSequence mOutputText;
/** More keys */
- public final CharSequence[] mMoreKeys;
+ public final String[] mMoreKeys;
/** More keys maximum column number */
public final int mMaxMoreKeysColumn;
@@ -103,77 +111,38 @@ public class Key {
public static final int BACKGROUND_TYPE_NORMAL = 0;
public static final int BACKGROUND_TYPE_FUNCTIONAL = 1;
public static final int BACKGROUND_TYPE_ACTION = 2;
- public static final int BACKGROUND_TYPE_STICKY = 3;
+ public static final int BACKGROUND_TYPE_STICKY_OFF = 3;
+ public static final int BACKGROUND_TYPE_STICKY_ON = 4;
+
+ private final int mActionFlags;
+ private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
+ private static final int ACTION_FLAGS_NO_KEY_PREVIEW = 0x02;
+ private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
+ private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
- /** Whether this key repeats itself when held down */
- public final boolean mRepeatable;
+ private final int mHashCode;
/** The current pressed state of this key */
private boolean mPressed;
- /** If this is a sticky key, is its highlight on? */
- private boolean mHighlightOn;
/** Key is enabled and responds on press */
private boolean mEnabled = true;
- /** Whether this key needs to show the "..." popup hint for special purposes */
- private boolean mNeedsSpecialPopupHint;
-
- // RTL parenthesis character swapping map.
- private static final Map<Integer, Integer> sRtlParenthesisMap = new HashMap<Integer, Integer>();
-
- static {
- // The all letters need to be mirrored are found at
- // http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt
- addRtlParenthesisPair('(', ')');
- addRtlParenthesisPair('[', ']');
- addRtlParenthesisPair('{', '}');
- addRtlParenthesisPair('<', '>');
- // \u00ab: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
- // \u00bb: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
- addRtlParenthesisPair('\u00ab', '\u00bb');
- // \u2039: SINGLE LEFT-POINTING ANGLE QUOTATION MARK
- // \u203a: SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
- addRtlParenthesisPair('\u2039', '\u203a');
- // \u2264: LESS-THAN OR EQUAL TO
- // \u2265: GREATER-THAN OR EQUAL TO
- addRtlParenthesisPair('\u2264', '\u2265');
- }
-
- private static void addRtlParenthesisPair(int left, int right) {
- sRtlParenthesisMap.put(left, right);
- sRtlParenthesisMap.put(right, left);
- }
-
- public static int getRtlParenthesisCode(int code, boolean isRtl) {
- if (isRtl && sRtlParenthesisMap.containsKey(code)) {
- return sRtlParenthesisMap.get(code);
- } else {
- return code;
- }
- }
-
- private static int getCode(Resources res, KeyboardParams params, String moreKeySpec) {
- return getRtlParenthesisCode(
- MoreKeySpecParser.getCode(res, moreKeySpec), params.mIsRtlKeyboard);
- }
-
- private static Drawable getIcon(KeyboardParams params, String moreKeySpec) {
- return params.mIconsSet.getIcon(MoreKeySpecParser.getIconId(moreKeySpec));
- }
/**
* This constructor is being used only for key in more keys keyboard.
*/
- public Key(Resources res, KeyboardParams params, String moreKeySpec,
+ public Key(Resources res, Keyboard.Params params, String moreKeySpec,
int x, int y, int width, int height) {
- this(params, MoreKeySpecParser.getLabel(moreKeySpec), null, getIcon(params, moreKeySpec),
- getCode(res, params, moreKeySpec), MoreKeySpecParser.getOutputText(moreKeySpec),
+ this(params, KeySpecParser.getLabel(moreKeySpec), null,
+ KeySpecParser.getIconId(moreKeySpec),
+ KeySpecParser.getCode(res, moreKeySpec),
+ KeySpecParser.getOutputText(moreKeySpec),
x, y, width, height);
}
/**
* This constructor is being used only for key in popup suggestions pane.
*/
- public Key(KeyboardParams params, CharSequence label, CharSequence hintLabel, Drawable icon,
+ public Key(Keyboard.Params params, String label, String hintLabel, int iconId,
int code, CharSequence outputText, int x, int y, int width, int height) {
mHeight = height - params.mVerticalGap;
mHorizontalGap = params.mHorizontalGap;
@@ -181,19 +150,24 @@ public class Key {
mVisualInsetsLeft = mVisualInsetsRight = 0;
mWidth = width - mHorizontalGap;
mHintLabel = hintLabel;
- mLabelOption = 0;
+ mLabelFlags = 0;
mBackgroundType = BACKGROUND_TYPE_NORMAL;
- mRepeatable = false;
+ mActionFlags = 0;
mMoreKeys = null;
mMaxMoreKeysColumn = 0;
mLabel = label;
mOutputText = outputText;
mCode = code;
- mIcon = icon;
+ mAltCode = Keyboard.CODE_UNSPECIFIED;
+ mIconId = iconId;
+ mDisabledIconId = KeyboardIconsSet.ICON_UNDEFINED;
+ mPreviewIconId = KeyboardIconsSet.ICON_UNDEFINED;
// Horizontal gap is divided equally to both sides of the key.
mX = x + mHorizontalGap / 2;
mY = y;
mHitBox.set(x, y, x + width + 1, y + height);
+
+ mHashCode = hashCode(this);
}
/**
@@ -205,9 +179,10 @@ public class Key {
* this key.
* @param parser the XML parser containing the attributes for this key
* @param keyStyles active key styles set
+ * @throws XmlPullParserException
*/
- public Key(Resources res, KeyboardParams params, KeyboardBuilder.Row row,
- XmlPullParser parser, KeyStyles keyStyles) {
+ public Key(Resources res, Keyboard.Params params, Keyboard.Builder.Row row,
+ XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException {
final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
final int keyHeight = row.mRowHeight;
mVerticalGap = params.mVerticalGap;
@@ -221,9 +196,10 @@ public class Key {
String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
style = keyStyles.getKeyStyle(styleName);
if (style == null)
- throw new ParseException("Unknown key style: " + styleName, parser);
+ throw new XmlParseUtils.ParseException(
+ "Unknown key style: " + styleName, parser);
} else {
- style = keyStyles.getEmptyKeyStyle();
+ style = KeyStyles.getEmptyKeyStyle();
}
final float keyXPos = row.getKeyX(keyAttr);
@@ -239,89 +215,238 @@ public class Key {
// Update row to have current x coordinate.
row.setXPos(keyXPos + keyWidth);
- final CharSequence[] moreKeys = style.getTextArray(keyAttr,
- R.styleable.Keyboard_Key_moreKeys);
- // In Arabic symbol layouts, we'd like to keep digits in more keys regardless of
- // config_digit_more_keys_enabled.
- if (params.mId.isAlphabetKeyboard()
- && !res.getBoolean(R.bool.config_digit_more_keys_enabled)) {
- mMoreKeys = MoreKeySpecParser.filterOut(res, moreKeys, MoreKeySpecParser.DIGIT_FILTER);
- } else {
- mMoreKeys = moreKeys;
- }
- mMaxMoreKeysColumn = style.getInt(keyAttr,
- R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn);
-
mBackgroundType = style.getInt(keyAttr,
R.styleable.Keyboard_Key_backgroundType, BACKGROUND_TYPE_NORMAL);
- mRepeatable = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable, false);
- mEnabled = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_enabled, true);
- final KeyboardIconsSet iconsSet = params.mIconsSet;
- mVisualInsetsLeft = (int) KeyboardBuilder.getDimensionOrFraction(keyAttr,
+ mVisualInsetsLeft = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr,
R.styleable.Keyboard_Key_visualInsetsLeft, params.mBaseWidth, 0);
- mVisualInsetsRight = (int) KeyboardBuilder.getDimensionOrFraction(keyAttr,
+ mVisualInsetsRight = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr,
R.styleable.Keyboard_Key_visualInsetsRight, params.mBaseWidth, 0);
- mPreviewIcon = iconsSet.getIcon(style.getInt(keyAttr,
- R.styleable.Keyboard_Key_keyIconPreview, KeyboardIconsSet.ICON_UNDEFINED));
- mIcon = iconsSet.getIcon(style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIcon,
- KeyboardIconsSet.ICON_UNDEFINED));
- final int shiftedIconId = style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIconShifted,
- KeyboardIconsSet.ICON_UNDEFINED);
- if (shiftedIconId != KeyboardIconsSet.ICON_UNDEFINED) {
- final Drawable shiftedIcon = iconsSet.getIcon(shiftedIconId);
- params.addShiftedIcon(this, shiftedIcon);
+ mPreviewIconId = style.getInt(keyAttr,
+ R.styleable.Keyboard_Key_keyIconPreview, KeyboardIconsSet.ICON_UNDEFINED);
+ mIconId = style.getInt(keyAttr,
+ R.styleable.Keyboard_Key_keyIcon, KeyboardIconsSet.ICON_UNDEFINED);
+ mDisabledIconId = style.getInt(keyAttr,
+ R.styleable.Keyboard_Key_keyIconDisabled, KeyboardIconsSet.ICON_UNDEFINED);
+
+ mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
+ final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
+ int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
+ final String[] additionalMoreKeys = style.getStringArray(
+ keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
+ final String[] moreKeys = KeySpecParser.insertAddtionalMoreKeys(style.getStringArray(
+ keyAttr, R.styleable.Keyboard_Key_moreKeys), additionalMoreKeys);
+ if (moreKeys != null) {
+ actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
+ for (int i = 0; i < moreKeys.length; i++) {
+ moreKeys[i] = adjustCaseOfStringForKeyboardId(
+ moreKeys[i], preserveCase, params.mId);
+ }
}
- mHintLabel = style.getText(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
-
- mLabel = style.getText(keyAttr, R.styleable.Keyboard_Key_keyLabel);
- mLabelOption = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelOption, 0);
- mOutputText = style.getText(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
- // Choose the first letter of the label as primary code if not
- // specified.
- final int code = style.getInt(keyAttr, R.styleable.Keyboard_Key_code,
- Keyboard.CODE_UNSPECIFIED);
- if (code == Keyboard.CODE_UNSPECIFIED && !TextUtils.isEmpty(mLabel)) {
- final int firstChar = mLabel.charAt(0);
- mCode = getRtlParenthesisCode(firstChar, params.mIsRtlKeyboard);
- } else if (code != Keyboard.CODE_UNSPECIFIED) {
- mCode = code;
+ mActionFlags = actionFlags;
+ mMoreKeys = moreKeys;
+ mMaxMoreKeysColumn = style.getInt(keyAttr,
+ R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
+
+ if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
+ mLabel = params.mId.mCustomActionLabel;
} else {
- mCode = Keyboard.CODE_DUMMY;
+ mLabel = adjustCaseOfStringForKeyboardId(style.getString(
+ keyAttr, R.styleable.Keyboard_Key_keyLabel), preserveCase, params.mId);
}
+ mHintLabel = adjustCaseOfStringForKeyboardId(style.getString(
+ keyAttr, R.styleable.Keyboard_Key_keyHintLabel), preserveCase, params.mId);
+ 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);
+ // Choose the first letter of the label as primary code if not specified.
+ if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
+ && !TextUtils.isEmpty(mLabel)) {
+ if (Utils.codePointCount(mLabel) == 1) {
+ // Use the first letter of the hint label if shiftedLetterActivated flag is
+ // specified.
+ if (hasShiftedLetterHint() && isShiftedLetterActivated()
+ && !TextUtils.isEmpty(mHintLabel)) {
+ mCode = mHintLabel.codePointAt(0);
+ } else {
+ mCode = mLabel.codePointAt(0);
+ }
+ } else {
+ // In some locale and case, the character might be represented by multiple code
+ // points, such as upper case Eszett of German alphabet.
+ outputText = mLabel;
+ mCode = Keyboard.CODE_OUTPUT_TEXT;
+ }
+ } else if (code == Keyboard.CODE_UNSPECIFIED && outputText != null) {
+ if (Utils.codePointCount(outputText) == 1) {
+ mCode = outputText.codePointAt(0);
+ outputText = null;
+ } else {
+ mCode = Keyboard.CODE_OUTPUT_TEXT;
+ }
+ } else {
+ mCode = adjustCaseOfCodeForKeyboardId(code, preserveCase, params.mId);
+ }
+ mOutputText = outputText;
+ mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr,
+ R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase,
+ params.mId);
+ mHashCode = hashCode(this);
keyAttr.recycle();
+
+ if (hasShiftedLetterHint() && TextUtils.isEmpty(mHintLabel)) {
+ Log.w(TAG, "hasShiftedLetterHint specified without keyHintLabel: " + this);
+ }
}
- public void markAsLeftEdge(KeyboardParams params) {
+ private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase,
+ KeyboardId id) {
+ if (!Keyboard.isLetterCode(code) || preserveCase) return code;
+ final String text = new String(new int[] { code } , 0, 1);
+ final String casedText = adjustCaseOfStringForKeyboardId(text, preserveCase, id);
+ return Utils.codePointCount(casedText) == 1
+ ? casedText.codePointAt(0) : Keyboard.CODE_UNSPECIFIED;
+ }
+
+ private static String adjustCaseOfStringForKeyboardId(String text, boolean preserveCase,
+ KeyboardId id) {
+ if (text == null || preserveCase) return text;
+ switch (id.mElementId) {
+ case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
+ return text.toUpperCase(id.mLocale);
+ default:
+ return text;
+ }
+ }
+
+ private static int hashCode(Key key) {
+ return Arrays.hashCode(new Object[] {
+ key.mX,
+ key.mY,
+ key.mWidth,
+ key.mHeight,
+ key.mCode,
+ key.mLabel,
+ key.mHintLabel,
+ key.mIconId,
+ key.mBackgroundType,
+ Arrays.hashCode(key.mMoreKeys),
+ key.mOutputText,
+ key.mActionFlags,
+ key.mLabelFlags,
+ // Key can be distinguishable without the following members.
+ // key.mAltCode,
+ // key.mDisabledIconId,
+ // key.mPreviewIconId,
+ // key.mHorizontalGap,
+ // key.mVerticalGap,
+ // key.mVisualInsetLeft,
+ // key.mVisualInsetRight,
+ // key.mMaxMoreKeysColumn,
+ });
+ }
+
+ private boolean equals(Key o) {
+ if (this == o) return true;
+ return o.mX == mX
+ && o.mY == mY
+ && o.mWidth == mWidth
+ && o.mHeight == mHeight
+ && o.mCode == mCode
+ && TextUtils.equals(o.mLabel, mLabel)
+ && TextUtils.equals(o.mHintLabel, mHintLabel)
+ && o.mIconId == mIconId
+ && o.mBackgroundType == mBackgroundType
+ && Arrays.equals(o.mMoreKeys, mMoreKeys)
+ && TextUtils.equals(o.mOutputText, mOutputText)
+ && o.mActionFlags == mActionFlags
+ && o.mLabelFlags == mLabelFlags;
+ }
+
+ @Override
+ public int hashCode() {
+ return mHashCode;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof Key && equals((Key)o);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s/%s %d,%d %dx%d %s/%s/%s",
+ Keyboard.printableCode(mCode), mLabel, mX, mY, mWidth, mHeight, mHintLabel,
+ KeyboardIconsSet.getIconName(mIconId), backgroundName(mBackgroundType));
+ }
+
+ private static String backgroundName(int backgroundType) {
+ switch (backgroundType) {
+ case BACKGROUND_TYPE_NORMAL: return "normal";
+ case BACKGROUND_TYPE_FUNCTIONAL: return "functional";
+ case BACKGROUND_TYPE_ACTION: return "action";
+ case BACKGROUND_TYPE_STICKY_OFF: return "stickyOff";
+ case BACKGROUND_TYPE_STICKY_ON: return "stickyOn";
+ default: return null;
+ }
+ }
+
+ public void markAsLeftEdge(Keyboard.Params params) {
mHitBox.left = params.mHorizontalEdgesPadding;
}
- public void markAsRightEdge(KeyboardParams params) {
+ public void markAsRightEdge(Keyboard.Params params) {
mHitBox.right = params.mOccupiedWidth - params.mHorizontalEdgesPadding;
}
- public void markAsTopEdge(KeyboardParams params) {
+ public void markAsTopEdge(Keyboard.Params params) {
mHitBox.top = params.mTopPadding;
}
- public void markAsBottomEdge(KeyboardParams params) {
+ public void markAsBottomEdge(Keyboard.Params params) {
mHitBox.bottom = params.mOccupiedHeight + params.mBottomPadding;
}
- public boolean isSticky() {
- return mBackgroundType == BACKGROUND_TYPE_STICKY;
+ public final boolean isSpacer() {
+ return this instanceof Spacer;
+ }
+
+ public boolean isShift() {
+ return mCode == Keyboard.CODE_SHIFT;
+ }
+
+ public boolean isModifier() {
+ return mCode == Keyboard.CODE_SHIFT || mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
+ }
+
+ public boolean isRepeatable() {
+ return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0;
+ }
+
+ public boolean noKeyPreview() {
+ return (mActionFlags & ACTION_FLAGS_NO_KEY_PREVIEW) != 0;
}
- public boolean isSpacer() {
- return false;
+ public boolean altCodeWhileTyping() {
+ return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0;
+ }
+
+ public boolean isLongPressEnabled() {
+ // We need not start long press timer on the key which has activated shifted letter.
+ return (mActionFlags & ACTION_FLAGS_ENABLE_LONG_PRESS) != 0
+ && (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0;
}
public Typeface selectTypeface(Typeface defaultTypeface) {
// TODO: Handle "bold" here too?
- if ((mLabelOption & LABEL_OPTION_FONT_NORMAL) != 0) {
+ if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
return Typeface.DEFAULT;
- } else if ((mLabelOption & LABEL_OPTION_FONT_MONO_SPACE) != 0) {
+ } else if ((mLabelFlags & LABEL_FLAGS_FONT_MONO_SPACE) != 0) {
return Typeface.MONOSPACE;
} else {
return defaultTypeface;
@@ -330,12 +455,12 @@ public class Key {
public int selectTextSize(int letter, int largeLetter, int label, int hintLabel) {
if (mLabel.length() > 1
- && (mLabelOption & (LABEL_OPTION_FOLLOW_KEY_LETTER_RATIO
- | LABEL_OPTION_FOLLOW_KEY_HINT_LABEL_RATIO)) == 0) {
+ && (mLabelFlags & (LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO
+ | LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO)) == 0) {
return label;
- } else if ((mLabelOption & LABEL_OPTION_FOLLOW_KEY_HINT_LABEL_RATIO) != 0) {
+ } else if ((mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO) != 0) {
return hintLabel;
- } else if ((mLabelOption & LABEL_OPTION_LARGE_LETTER) != 0) {
+ } else if ((mLabelFlags & LABEL_FLAGS_LARGE_LETTER) != 0) {
return largeLetter;
} else {
return letter;
@@ -343,63 +468,57 @@ public class Key {
}
public boolean isAlignLeft() {
- return (mLabelOption & LABEL_OPTION_ALIGN_LEFT) != 0;
+ return (mLabelFlags & LABEL_FLAGS_ALIGN_LEFT) != 0;
}
public boolean isAlignRight() {
- return (mLabelOption & LABEL_OPTION_ALIGN_RIGHT) != 0;
+ return (mLabelFlags & LABEL_FLAGS_ALIGN_RIGHT) != 0;
}
public boolean isAlignLeftOfCenter() {
- return (mLabelOption & LABEL_OPTION_ALIGN_LEFT_OF_CENTER) != 0;
+ return (mLabelFlags & LABEL_FLAGS_ALIGN_LEFT_OF_CENTER) != 0;
}
public boolean hasPopupHint() {
- return (mLabelOption & LABEL_OPTION_HAS_POPUP_HINT) != 0;
- }
-
- public void setNeedsSpecialPopupHint(boolean needsSpecialPopupHint) {
- mNeedsSpecialPopupHint = needsSpecialPopupHint;
+ return (mLabelFlags & LABEL_FLAGS_HAS_POPUP_HINT) != 0;
}
- public boolean needsSpecialPopupHint() {
- return mNeedsSpecialPopupHint;
- }
-
- public boolean hasUppercaseLetter() {
- return (mLabelOption & LABEL_OPTION_HAS_UPPERCASE_LETTER) != 0;
+ public boolean hasShiftedLetterHint() {
+ return (mLabelFlags & LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0;
}
public boolean hasHintLabel() {
- return (mLabelOption & LABEL_OPTION_HAS_HINT_LABEL) != 0;
+ return (mLabelFlags & LABEL_FLAGS_HAS_HINT_LABEL) != 0;
}
public boolean hasLabelWithIconLeft() {
- return (mLabelOption & LABEL_OPTION_WITH_ICON_LEFT) != 0;
+ return (mLabelFlags & LABEL_FLAGS_WITH_ICON_LEFT) != 0;
}
public boolean hasLabelWithIconRight() {
- return (mLabelOption & LABEL_OPTION_WITH_ICON_RIGHT) != 0;
+ return (mLabelFlags & LABEL_FLAGS_WITH_ICON_RIGHT) != 0;
}
public boolean needsXScale() {
- return (mLabelOption & LABEL_OPTION_AUTO_X_SCALE) != 0;
+ return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0;
}
- public Drawable getIcon() {
- return mIcon;
+ public boolean isShiftedLetterActivated() {
+ return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0;
}
- public Drawable getPreviewIcon() {
- return mPreviewIcon;
+ public Drawable getIcon(KeyboardIconsSet iconSet) {
+ return iconSet.getIconDrawable(mIconId);
}
- public void setIcon(Drawable icon) {
- mIcon = icon;
+ public Drawable getDisabledIcon(KeyboardIconsSet iconSet) {
+ return iconSet.getIconDrawable(mDisabledIconId);
}
- public void setPreviewIcon(Drawable icon) {
- mPreviewIcon = icon;
+ public Drawable getPreviewIcon(KeyboardIconsSet iconSet) {
+ return mPreviewIconId != KeyboardIconsSet.ICON_UNDEFINED
+ ? iconSet.getIconDrawable(mPreviewIconId)
+ : iconSet.getIconDrawable(mIconId);
}
/**
@@ -420,10 +539,6 @@ public class Key {
mPressed = false;
}
- public void setHighlightOn(boolean highlightOn) {
- mHighlightOn = highlightOn;
- }
-
public boolean isEnabled() {
return mEnabled;
}
@@ -436,9 +551,9 @@ public class Key {
* Detects if a point falls on this key.
* @param x the x-coordinate of the point
* @param y the y-coordinate of the point
- * @return whether or not the point falls on the key. If the key is attached to an edge, it will
- * assume that all points between the key and the edge are considered to be on the key.
- * @see {@link #markAsLeftEdge(KeyboardParams)} etc.
+ * @return whether or not the point falls on the key. If the key is attached to an edge, it
+ * will assume that all points between the key and the edge are considered to be on the key.
+ * @see #markAsLeftEdge(Keyboard.Params) etc.
*/
public boolean isOnKey(int x, int y) {
return mHitBox.contains(x, y);
@@ -517,40 +632,32 @@ public class Key {
* @see android.graphics.drawable.StateListDrawable#setState(int[])
*/
public int[] getCurrentDrawableState() {
- final boolean pressed = mPressed;
-
switch (mBackgroundType) {
case BACKGROUND_TYPE_FUNCTIONAL:
- return pressed ? KEY_STATE_FUNCTIONAL_PRESSED : KEY_STATE_FUNCTIONAL_NORMAL;
+ return mPressed ? KEY_STATE_FUNCTIONAL_PRESSED : KEY_STATE_FUNCTIONAL_NORMAL;
case BACKGROUND_TYPE_ACTION:
- return pressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL;
- case BACKGROUND_TYPE_STICKY:
- if (mHighlightOn) {
- return pressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
- } else {
- return pressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
- }
+ return mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL;
+ case BACKGROUND_TYPE_STICKY_OFF:
+ return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
+ case BACKGROUND_TYPE_STICKY_ON:
+ return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
default: /* BACKGROUND_TYPE_NORMAL */
- return pressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
+ return mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
}
}
public static class Spacer extends Key {
- public Spacer(Resources res, KeyboardParams params, KeyboardBuilder.Row row,
- XmlPullParser parser, KeyStyles keyStyles) {
+ public Spacer(Resources res, Keyboard.Params params, Keyboard.Builder.Row row,
+ XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException {
super(res, params, row, parser, keyStyles);
}
/**
* This constructor is being used only for divider in more keys keyboard.
*/
- public Spacer(KeyboardParams params, Drawable icon, int x, int y, int width, int height) {
- super(params, null, null, icon, Keyboard.CODE_DUMMY, null, x, y, width, height);
- }
-
- @Override
- public boolean isSpacer() {
- return true;
+ protected Spacer(Keyboard.Params params, int x, int y, int width, int height) {
+ super(params, null, null, KeyboardIconsSet.ICON_UNDEFINED, Keyboard.CODE_UNSPECIFIED,
+ null, x, y, width, height);
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 3298c41cf..bff491ffd 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -26,7 +26,7 @@ public class KeyDetector {
private static final boolean DEBUG = false;
public static final int NOT_A_CODE = -1;
- public static final int NOT_A_KEY = -1;
+ private static final int ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE = 2;
private final int mKeyHysteresisDistanceSquared;
@@ -39,7 +39,7 @@ public class KeyDetector {
// working area
private static final int MAX_NEARBY_KEYS = 12;
private final int[] mDistances = new int[MAX_NEARBY_KEYS];
- private final int[] mIndices = new int[MAX_NEARBY_KEYS];
+ private final Key[] mNeighborKeys = new Key[MAX_NEARBY_KEYS];
/**
* This class handles key detection.
@@ -96,22 +96,22 @@ public class KeyDetector {
}
/**
- * Computes maximum size of the array that can contain all nearby key indices returned by
- * {@link #getKeyIndexAndNearbyCodes}.
+ * Computes maximum size of the array that can contain all nearby key codes returned by
+ * {@link #getKeyAndNearbyCodes}.
*
- * @return Returns maximum size of the array that can contain all nearby key indices returned
- * by {@link #getKeyIndexAndNearbyCodes}.
+ * @return Returns maximum size of the array that can contain all nearby key codes returned
+ * by {@link #getKeyAndNearbyCodes}.
*/
protected int getMaxNearbyKeys() {
return MAX_NEARBY_KEYS;
}
/**
- * Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes}
+ * Allocates array that can hold all key codes returned by {@link #getKeyAndNearbyCodes}
* method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}.
*
- * @return Allocates and returns an array that can hold all key indices returned by
- * {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are
+ * @return Allocates and returns an array that can hold all key codes returned by
+ * {@link #getKeyAndNearbyCodes} method. All elements in the returned array are
* initialized by {@link #NOT_A_CODE} value.
*/
public int[] newCodeArray() {
@@ -122,7 +122,7 @@ public class KeyDetector {
private void initializeNearbyKeys() {
Arrays.fill(mDistances, Integer.MAX_VALUE);
- Arrays.fill(mIndices, NOT_A_KEY);
+ Arrays.fill(mNeighborKeys, null);
}
/**
@@ -130,14 +130,14 @@ public class KeyDetector {
* If the distance of two keys are the same, the key which the point is on should be considered
* as a closer one.
*
- * @param keyIndex index of the key.
+ * @param key the key to be inserted into the nearby keys buffer.
* @param distance distance between the key's edge and user touched point.
* @param isOnKey true if the point is on the key.
* @return order of the key in the nearby buffer, 0 if it is the nearest key.
*/
- private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) {
+ private int sortNearbyKeys(Key key, int distance, boolean isOnKey) {
final int[] distances = mDistances;
- final int[] indices = mIndices;
+ final Key[] neighborKeys = mNeighborKeys;
for (int insertPos = 0; insertPos < distances.length; insertPos++) {
final int comparingDistance = distances[insertPos];
if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) {
@@ -145,79 +145,123 @@ public class KeyDetector {
if (nextPos < distances.length) {
System.arraycopy(distances, insertPos, distances, nextPos,
distances.length - nextPos);
- System.arraycopy(indices, insertPos, indices, nextPos,
- indices.length - nextPos);
+ System.arraycopy(neighborKeys, insertPos, neighborKeys, nextPos,
+ neighborKeys.length - nextPos);
}
distances[insertPos] = distance;
- indices[insertPos] = keyIndex;
+ neighborKeys[insertPos] = key;
return insertPos;
}
}
return distances.length;
}
- private void getNearbyKeyCodes(final int[] allCodes) {
- final List<Key> keys = getKeyboard().mKeys;
- final int[] indices = mIndices;
+ private void getNearbyKeyCodes(final int primaryCode, final int[] allCodes) {
+ final Key[] neighborKeys = mNeighborKeys;
+ final int maxCodesSize = allCodes.length;
// allCodes[0] should always have the key code even if it is a non-letter key.
- if (indices[0] == NOT_A_KEY) {
+ if (neighborKeys[0] == null) {
allCodes[0] = NOT_A_CODE;
return;
}
int numCodes = 0;
- for (int j = 0; j < indices.length && numCodes < allCodes.length; j++) {
- final int index = indices[j];
- if (index == NOT_A_KEY)
+ for (int j = 0; j < neighborKeys.length && numCodes < maxCodesSize; j++) {
+ final Key key = neighborKeys[j];
+ if (key == null)
break;
- final int code = keys.get(index).mCode;
+ final int code = key.mCode;
// filter out a non-letter key from nearby keys
if (code < Keyboard.CODE_SPACE)
continue;
allCodes[numCodes++] = code;
}
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ if (primaryCode != NOT_A_CODE) {
+ final List<Integer> additionalChars =
+ mKeyboard.getAdditionalProximityChars().get(primaryCode);
+ if (additionalChars == null || additionalChars.size() == 0) {
+ return;
+ }
+ int currentCodesSize = numCodes;
+ allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
+ for (int i = 0; i < additionalChars.size(); ++i) {
+ final int additionalChar = additionalChars.get(i);
+ boolean contains = false;
+ for (int j = 0; j < currentCodesSize; ++j) {
+ if (additionalChar == allCodes[j]) {
+ contains = true;
+ break;
+ }
+ }
+ if (!contains) {
+ allCodes[numCodes++] = additionalChar;
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ }
+ }
+ }
}
/**
- * Finds all possible nearby key indices around a touch event point and returns the nearest key
- * index. The algorithm to determine the nearby keys depends on the threshold set by
+ * Finds all possible nearby key codes around a touch event point and returns the nearest key.
+ * The algorithm to determine the nearby keys depends on the threshold set by
* {@link #setProximityThreshold(int)} and the mode set by
* {@link #setProximityCorrectionEnabled(boolean)}.
*
* @param x The x-coordinate of a touch point
* @param y The y-coordinate of a touch point
- * @param allCodes All nearby key code except functional key are returned in this array
- * @return The nearest key index
+ * @param allCodes All nearby key codes except functional key are returned in this array
+ * @return The nearest key
*/
- public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
- final List<Key> keys = getKeyboard().mKeys;
+ public Key getKeyAndNearbyCodes(int x, int y, final int[] allCodes) {
final int touchX = getTouchX(x);
final int touchY = getTouchY(y);
initializeNearbyKeys();
- int primaryIndex = NOT_A_KEY;
- for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) {
- final Key key = keys.get(index);
+ Key primaryKey = null;
+ for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) {
final boolean isOnKey = key.isOnKey(touchX, touchY);
final int distance = key.squaredDistanceToEdge(touchX, touchY);
if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
- final int insertedPosition = sortNearbyKeys(index, distance, isOnKey);
- if (insertedPosition == 0 && isOnKey)
- primaryIndex = index;
+ final int insertedPosition = sortNearbyKeys(key, distance, isOnKey);
+ if (insertedPosition == 0 && isOnKey) {
+ primaryKey = key;
+ }
}
}
if (allCodes != null && allCodes.length > 0) {
- getNearbyKeyCodes(allCodes);
+ getNearbyKeyCodes(primaryKey != null ? primaryKey.mCode : NOT_A_CODE, allCodes);
if (DEBUG) {
Log.d(TAG, "x=" + x + " y=" + y
- + " primary="
- + (primaryIndex == NOT_A_KEY ? "none" : keys.get(primaryIndex).mCode)
- + " codes=" + Arrays.toString(allCodes));
+ + " primary=" + printableCode(primaryKey)
+ + " codes=" + printableCodes(allCodes));
}
}
- return primaryIndex;
+ return primaryKey;
+ }
+
+ public static String printableCode(Key key) {
+ return key != null ? Keyboard.printableCode(key.mCode) : "none";
+ }
+
+ public static String printableCodes(int[] codes) {
+ final StringBuilder sb = new StringBuilder();
+ for (final int code : codes) {
+ if (code == NOT_A_CODE) break;
+ if (sb.length() > 0) sb.append(", ");
+ sb.append(code);
+ }
+ return "[" + sb + "]";
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 4578507fc..28f71f443 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -16,14 +16,33 @@
package com.android.inputmethod.keyboard;
-import android.graphics.drawable.Drawable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
+import android.util.Xml;
+import android.view.InflateException;
+import com.android.inputmethod.keyboard.internal.KeyStyles;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
-import com.android.inputmethod.keyboard.internal.KeyboardParams;
-import com.android.inputmethod.keyboard.internal.KeyboardShiftState;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.XmlParseUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -47,7 +66,11 @@ import java.util.Set;
* </pre>
*/
public class Keyboard {
- /** Some common keys code. These should be aligned with values/keycodes.xml */
+ private static final String TAG = Keyboard.class.getSimpleName();
+
+ /** Some common keys code. Must be positive.
+ * These should be aligned with values/keycodes.xml
+ */
public static final int CODE_ENTER = '\n';
public static final int CODE_TAB = '\t';
public static final int CODE_SPACE = ' ';
@@ -64,20 +87,20 @@ public class Keyboard {
public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
public static final int CODE_DIGIT0 = '0';
public static final int CODE_PLUS = '+';
+ private static final int MINIMUM_LETTER_CODE = CODE_TAB;
-
- /** Special keys code. These should be aligned with values/keycodes.xml */
- public static final int CODE_DUMMY = 0;
+ /** Special keys code. Must be negative.
+ * These should be aligned with values/keycodes.xml
+ */
public static final int CODE_SHIFT = -1;
public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
- public static final int CODE_CAPSLOCK = -3;
- public static final int CODE_CANCEL = -4;
- public static final int CODE_DELETE = -5;
- public static final int CODE_SETTINGS = -6;
- public static final int CODE_SHORTCUT = -7;
- public static final int CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY = -98;
+ public static final int CODE_OUTPUT_TEXT = -3;
+ public static final int CODE_DELETE = -4;
+ public static final int CODE_SETTINGS = -5;
+ public static final int CODE_SHORTCUT = -6;
+ public static final int CODE_ACTION_ENTER = -7;
// Code value representing the code is not specified.
- public static final int CODE_UNSPECIFIED = -99;
+ public static final int CODE_UNSPECIFIED = -9;
public final KeyboardId mId;
public final int mThemeId;
@@ -98,150 +121,278 @@ public class Keyboard {
/** More keys keyboard template */
public final int mMoreKeysTemplate;
- /** Maximum column for mini keyboard */
- public final int mMaxMiniKeyboardColumn;
-
- /** True if Right-To-Left keyboard */
- public final boolean mIsRtlKeyboard;
+ /** Maximum column for more keys keyboard */
+ public final int mMaxMoreKeysKeyboardColumn;
/** List of keys and icons in this keyboard */
- public final List<Key> mKeys;
- public final List<Key> mShiftKeys;
- public final Set<Key> mShiftLockKeys;
- public final Map<Key, Drawable> mShiftedIcons;
- public final Map<Key, Drawable> mUnshiftedIcons;
+ public final Set<Key> mKeys;
+ public final Set<Key> mShiftKeys;
public final KeyboardIconsSet mIconsSet;
- private final KeyboardShiftState mShiftState = new KeyboardShiftState();
+ private final Map<Integer, Key> mKeyCache = new HashMap<Integer, Key>();
private final ProximityInfo mProximityInfo;
- public Keyboard(KeyboardParams params) {
+ public final Map<Integer, List<Integer>> mAdditionalProximityChars;
+
+ public Keyboard(Params params) {
mId = params.mId;
mThemeId = params.mThemeId;
mOccupiedHeight = params.mOccupiedHeight;
mOccupiedWidth = params.mOccupiedWidth;
mMostCommonKeyHeight = params.mMostCommonKeyHeight;
mMostCommonKeyWidth = params.mMostCommonKeyWidth;
- mIsRtlKeyboard = params.mIsRtlKeyboard;
mMoreKeysTemplate = params.mMoreKeysTemplate;
- mMaxMiniKeyboardColumn = params.mMaxMiniKeyboardColumn;
+ mMaxMoreKeysKeyboardColumn = params.mMaxMoreKeysKeyboardColumn;
mTopPadding = params.mTopPadding;
mVerticalGap = params.mVerticalGap;
- mKeys = Collections.unmodifiableList(params.mKeys);
- mShiftKeys = Collections.unmodifiableList(params.mShiftKeys);
- mShiftLockKeys = Collections.unmodifiableSet(params.mShiftLockKeys);
- mShiftedIcons = Collections.unmodifiableMap(params.mShiftedIcons);
- mUnshiftedIcons = Collections.unmodifiableMap(params.mUnshiftedIcons);
+ mKeys = Collections.unmodifiableSet(params.mKeys);
+ mShiftKeys = Collections.unmodifiableSet(params.mShiftKeys);
mIconsSet = params.mIconsSet;
+ mAdditionalProximityChars = params.mAdditionalProximityChars;
mProximityInfo = new ProximityInfo(
params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
- mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection);
+ mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection,
+ params.mAdditionalProximityChars);
}
public ProximityInfo getProximityInfo() {
return mProximityInfo;
}
- public boolean hasShiftLockKey() {
- return !mShiftLockKeys.isEmpty();
- }
+ public Key getKey(int code) {
+ if (code == CODE_UNSPECIFIED) {
+ return null;
+ }
+ final Integer keyCode = code;
+ if (mKeyCache.containsKey(keyCode)) {
+ return mKeyCache.get(keyCode);
+ }
- public boolean setShiftLocked(boolean newShiftLockState) {
- for (final Key key : mShiftLockKeys) {
- // To represent "shift locked" state. The highlight is handled by background image that
- // might be a StateListDrawable.
- key.setHighlightOn(newShiftLockState);
- // To represent "shifted" state. The key might have a shifted icon.
- if (newShiftLockState && mShiftedIcons.containsKey(key)) {
- key.setIcon(mShiftedIcons.get(key));
- } else {
- key.setIcon(mUnshiftedIcons.get(key));
+ for (final Key key : mKeys) {
+ if (key.mCode == code) {
+ mKeyCache.put(keyCode, key);
+ return key;
}
}
- mShiftState.setShiftLocked(newShiftLockState);
- return true;
+ mKeyCache.put(keyCode, null);
+ return null;
}
+ // TODO: Remove this method.
public boolean isShiftLocked() {
- return mShiftState.isShiftLocked();
+ return mId.isAlphabetShiftLockedKeyboard();
}
- public boolean isShiftLockShifted() {
- return mShiftState.isShiftLockShifted();
+ // TODO: Remove this method.
+ public boolean isShiftedOrShiftLocked() {
+ return mId.isAlphabetShiftedOrShiftLockedKeyboard();
}
- public boolean setShifted(boolean newShiftState) {
- for (final Key key : mShiftKeys) {
- if (!newShiftState && !mShiftState.isShiftLocked()) {
- key.setIcon(mUnshiftedIcons.get(key));
- } else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
- key.setIcon(mShiftedIcons.get(key));
- }
- }
- return mShiftState.setShifted(newShiftState);
+ // TODO: Remove this method.
+ public boolean isManualShifted() {
+ return mId.isAlphabetManualShiftedKeyboard();
}
- public boolean isShiftedOrShiftLocked() {
- return mShiftState.isShiftedOrShiftLocked();
+ public static boolean isLetterCode(int code) {
+ return code >= MINIMUM_LETTER_CODE;
}
- public void setAutomaticTemporaryUpperCase() {
- setShifted(true);
- mShiftState.setAutomaticTemporaryUpperCase();
- }
+ public static class Params {
+ public KeyboardId mId;
+ public int mThemeId;
- public boolean isAutomaticTemporaryUpperCase() {
- return isAlphaKeyboard() && mShiftState.isAutomaticTemporaryUpperCase();
- }
+ /** Total height and width of the keyboard, including the paddings and keys */
+ public int mOccupiedHeight;
+ public int mOccupiedWidth;
- public boolean isManualTemporaryUpperCase() {
- return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase();
- }
+ /** Base height and width of the keyboard used to calculate rows' or keys' heights and
+ * widths
+ */
+ public int mBaseHeight;
+ public int mBaseWidth;
- public boolean isManualTemporaryUpperCaseFromAuto() {
- return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCaseFromAuto();
- }
+ public int mTopPadding;
+ public int mBottomPadding;
+ public int mHorizontalEdgesPadding;
+ public int mHorizontalCenterPadding;
- public KeyboardShiftState getKeyboardShiftState() {
- return mShiftState;
- }
+ public int mDefaultRowHeight;
+ public int mDefaultKeyWidth;
+ public int mHorizontalGap;
+ public int mVerticalGap;
- public boolean isAlphaKeyboard() {
- return mId.isAlphabetKeyboard();
- }
+ public int mMoreKeysTemplate;
+ public int mMaxMoreKeysKeyboardColumn;
- public boolean isPhoneKeyboard() {
- return mId.isPhoneKeyboard();
- }
+ public int GRID_WIDTH;
+ public int GRID_HEIGHT;
- public boolean isNumberKeyboard() {
- return mId.isNumberKeyboard();
- }
+ public final Set<Key> mKeys = new HashSet<Key>();
+ public final Set<Key> mShiftKeys = new HashSet<Key>();
+ public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
+ // TODO: Should be in Key instead of Keyboard.Params?
+ public final Map<Integer, List<Integer>> mAdditionalProximityChars =
+ new HashMap<Integer, List<Integer>>();
+
+ public KeyboardSet.KeysCache mKeysCache;
+
+ public int mMostCommonKeyHeight = 0;
+ public int mMostCommonKeyWidth = 0;
+
+ public final TouchPositionCorrection mTouchPositionCorrection =
+ new TouchPositionCorrection();
+
+ public static class TouchPositionCorrection {
+ private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
+
+ public boolean mEnabled;
+ public float[] mXs;
+ public float[] mYs;
+ public float[] mRadii;
+
+ public void load(String[] data) {
+ final int dataLength = data.length;
+ if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
+ if (LatinImeLogger.sDBG)
+ throw new RuntimeException(
+ "the size of touch position correction data is invalid");
+ return;
+ }
- public CharSequence adjustLabelCase(CharSequence label) {
- if (isShiftedOrShiftLocked() && !TextUtils.isEmpty(label) && label.length() < 3
- && Character.isLowerCase(label.charAt(0))) {
- return label.toString().toUpperCase(mId.mLocale);
+ final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
+ mXs = new float[length];
+ mYs = new float[length];
+ mRadii = new float[length];
+ try {
+ for (int i = 0; i < dataLength; ++i) {
+ final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
+ final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
+ final float value = Float.parseFloat(data[i]);
+ if (type == 0) {
+ mXs[index] = value;
+ } else if (type == 1) {
+ mYs[index] = value;
+ } else {
+ mRadii[index] = value;
+ }
+ }
+ } catch (NumberFormatException e) {
+ if (LatinImeLogger.sDBG) {
+ throw new RuntimeException(
+ "the number format for touch position correction data is invalid");
+ }
+ mXs = null;
+ mYs = null;
+ mRadii = null;
+ }
+ }
+
+ public void setEnabled(boolean enabled) {
+ mEnabled = enabled;
+ }
+
+ public boolean isValid() {
+ return mEnabled && mXs != null && mYs != null && mRadii != null
+ && mXs.length > 0 && mYs.length > 0 && mRadii.length > 0;
+ }
+ }
+
+ protected void clearKeys() {
+ mKeys.clear();
+ mShiftKeys.clear();
+ clearHistogram();
+ }
+
+ public void onAddKey(Key newKey) {
+ final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
+ mKeys.add(key);
+ updateHistogram(key);
+ if (key.mCode == Keyboard.CODE_SHIFT) {
+ mShiftKeys.add(key);
+ }
+ }
+
+ private int mMaxHeightCount = 0;
+ private int mMaxWidthCount = 0;
+ private final Map<Integer, Integer> mHeightHistogram = new HashMap<Integer, Integer>();
+ private final Map<Integer, Integer> mWidthHistogram = new HashMap<Integer, Integer>();
+
+ private void clearHistogram() {
+ mMostCommonKeyHeight = 0;
+ mMaxHeightCount = 0;
+ mHeightHistogram.clear();
+
+ mMaxWidthCount = 0;
+ mMostCommonKeyWidth = 0;
+ mWidthHistogram.clear();
+ }
+
+ private static int updateHistogramCounter(Map<Integer, Integer> histogram, Integer key) {
+ final int count = (histogram.containsKey(key) ? histogram.get(key) : 0) + 1;
+ histogram.put(key, count);
+ return count;
+ }
+
+ private void updateHistogram(Key key) {
+ final Integer height = key.mHeight + key.mVerticalGap;
+ final int heightCount = updateHistogramCounter(mHeightHistogram, height);
+ if (heightCount > mMaxHeightCount) {
+ mMaxHeightCount = heightCount;
+ mMostCommonKeyHeight = height;
+ }
+
+ final Integer width = key.mWidth + key.mHorizontalGap;
+ final int widthCount = updateHistogramCounter(mWidthHistogram, width);
+ if (widthCount > mMaxWidthCount) {
+ mMaxWidthCount = widthCount;
+ mMostCommonKeyWidth = width;
+ }
}
- return label;
}
/**
- * Returns the indices of the keys that are closest to the given point.
+ * Returns the array of the keys that are closest to the given point.
* @param x the x-coordinate of the point
* @param y the y-coordinate of the point
- * @return the array of integer indices for the nearest keys to the given point. If the given
+ * @return the array of the nearest keys to the given point. If the given
* point is out of range, then an array of size zero is returned.
*/
- public int[] getNearestKeys(int x, int y) {
- return mProximityInfo.getNearestKeys(x, y);
+ public Key[] getNearestKeys(int x, int y) {
+ // Avoid dead pixels at edges of the keyboard
+ final int adjustedX = Math.max(0, Math.min(x, mOccupiedWidth - 1));
+ final int adjustedY = Math.max(0, Math.min(y, mOccupiedHeight - 1));
+ return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
}
- public static String themeName(int themeId) {
+ public Map<Integer, List<Integer>> getAdditionalProximityChars() {
+ return mAdditionalProximityChars;
+ }
+
+ public static String printableCode(int code) {
+ switch (code) {
+ case CODE_SHIFT: return "shift";
+ case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
+ case CODE_OUTPUT_TEXT: return "text";
+ case CODE_DELETE: return "delete";
+ case CODE_SETTINGS: return "settings";
+ case CODE_SHORTCUT: return "shortcut";
+ case CODE_ACTION_ENTER: return "actionEnter";
+ case CODE_UNSPECIFIED: return "unspec";
+ case CODE_TAB: return "tab";
+ case CODE_ENTER: return "enter";
+ default:
+ if (code <= 0) Log.w(TAG, "Unknown non-positive key code=" + code);
+ if (code < CODE_SPACE) return String.format("'\\u%02x'", code);
+ if (code < 0x100) return String.format("'%c'", code);
+ return String.format("'\\u%04x'", code);
+ }
+ }
+
+ public static String toThemeName(int themeId) {
// This should be aligned with theme-*.xml resource files' themeId attribute.
switch (themeId) {
case 0: return "Basic";
@@ -253,4 +404,912 @@ public class Keyboard {
default: return null;
}
}
+
+ /**
+ * Keyboard Building helper.
+ *
+ * This class parses Keyboard XML file and eventually build a Keyboard.
+ * The Keyboard XML file looks like:
+ * <pre>
+ * &gt;!-- xml/keyboard.xml --&lt;
+ * &gt;Keyboard keyboard_attributes*&lt;
+ * &gt;!-- Keyboard Content --&lt;
+ * &gt;Row row_attributes*&lt;
+ * &gt;!-- Row Content --&lt;
+ * &gt;Key key_attributes* /&lt;
+ * &gt;Spacer horizontalGap="0.2in" /&lt;
+ * &gt;include keyboardLayout="@xml/other_keys"&lt;
+ * ...
+ * &gt;/Row&lt;
+ * &gt;include keyboardLayout="@xml/other_rows"&lt;
+ * ...
+ * &gt;/Keyboard&lt;
+ * </pre>
+ * The XML file which is included in other file must have &gt;merge&lt; as root element,
+ * such as:
+ * <pre>
+ * &gt;!-- xml/other_keys.xml --&lt;
+ * &gt;merge&lt;
+ * &gt;Key key_attributes* /&lt;
+ * ...
+ * &gt;/merge&lt;
+ * </pre>
+ * and
+ * <pre>
+ * &gt;!-- xml/other_rows.xml --&lt;
+ * &gt;merge&lt;
+ * &gt;Row row_attributes*&lt;
+ * &gt;Key key_attributes* /&lt;
+ * &gt;/Row&lt;
+ * ...
+ * &gt;/merge&lt;
+ * </pre>
+ * You can also use switch-case-default tags to select Rows and Keys.
+ * <pre>
+ * &gt;switch&lt;
+ * &gt;case case_attribute*&lt;
+ * &gt;!-- Any valid tags at switch position --&lt;
+ * &gt;/case&lt;
+ * ...
+ * &gt;default&lt;
+ * &gt;!-- Any valid tags at switch position --&lt;
+ * &gt;/default&lt;
+ * &gt;/switch&lt;
+ * </pre>
+ * You can declare Key style and specify styles within Key tags.
+ * <pre>
+ * &gt;switch&lt;
+ * &gt;case mode="email"&lt;
+ * &gt;key-style styleName="f1-key" parentStyle="modifier-key"
+ * keyLabel=".com"
+ * /&lt;
+ * &gt;/case&lt;
+ * &gt;case mode="url"&lt;
+ * &gt;key-style styleName="f1-key" parentStyle="modifier-key"
+ * keyLabel="http://"
+ * /&lt;
+ * &gt;/case&lt;
+ * &gt;/switch&lt;
+ * ...
+ * &gt;Key keyStyle="shift-key" ... /&lt;
+ * </pre>
+ */
+
+ public static class Builder<KP extends Params> {
+ private static final String BUILDER_TAG = "Keyboard.Builder";
+ private static final boolean DEBUG = false;
+
+ // Keyboard XML Tags
+ private static final String TAG_KEYBOARD = "Keyboard";
+ private static final String TAG_ROW = "Row";
+ private static final String TAG_KEY = "Key";
+ 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";
+ public static final String TAG_KEY_STYLE = "key-style";
+
+ private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
+ private static final int DEFAULT_KEYBOARD_ROWS = 4;
+
+ protected final KP mParams;
+ protected final Context mContext;
+ protected final Resources mResources;
+ private final DisplayMetrics mDisplayMetrics;
+
+ private int mCurrentY = 0;
+ private Row mCurrentRow = null;
+ private boolean mLeftEdge;
+ private boolean mTopEdge;
+ private Key mRightEdgeKey = null;
+ private final KeyStyles mKeyStyles = new KeyStyles();
+
+ /**
+ * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
+ * Some of the key size defaults can be overridden per row from what the {@link Keyboard}
+ * defines.
+ */
+ public static class Row {
+ // keyWidth enum constants
+ private static final int KEYWIDTH_NOT_ENUM = 0;
+ private static final int KEYWIDTH_FILL_RIGHT = -1;
+ private static final int KEYWIDTH_FILL_BOTH = -2;
+
+ private final Params mParams;
+ /** Default width of a key in this row. */
+ private float mDefaultKeyWidth;
+ /** Default height of a key in this row. */
+ public final int mRowHeight;
+
+ private final int mCurrentY;
+ // Will be updated by {@link Key}'s constructor.
+ private float mCurrentX;
+
+ public Row(Resources res, Params params, XmlPullParser parser, int y) {
+ mParams = params;
+ TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard);
+ mRowHeight = (int)Builder.getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_rowHeight,
+ params.mBaseHeight, params.mDefaultRowHeight);
+ keyboardAttr.recycle();
+ TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Key);
+ mDefaultKeyWidth = Builder.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_keyWidth,
+ params.mBaseWidth, params.mDefaultKeyWidth);
+ keyAttr.recycle();
+
+ mCurrentY = y;
+ mCurrentX = 0.0f;
+ }
+
+ public float getDefaultKeyWidth() {
+ return mDefaultKeyWidth;
+ }
+
+ public void setDefaultKeyWidth(float defaultKeyWidth) {
+ mDefaultKeyWidth = defaultKeyWidth;
+ }
+
+ public void setXPos(float keyXPos) {
+ mCurrentX = keyXPos;
+ }
+
+ public void advanceXPos(float width) {
+ mCurrentX += width;
+ }
+
+ public int getKeyY() {
+ return mCurrentY;
+ }
+
+ public float getKeyX(TypedArray keyAttr) {
+ final int widthType = Builder.getEnumValue(keyAttr,
+ R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
+ if (widthType == KEYWIDTH_FILL_BOTH) {
+ // If keyWidth is fillBoth, the key width should start right after the nearest
+ // key on the left hand side.
+ return mCurrentX;
+ }
+
+ final int keyboardRightEdge = mParams.mOccupiedWidth
+ - mParams.mHorizontalEdgesPadding;
+ if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
+ final float keyXPos = Builder.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_keyXPos, mParams.mBaseWidth, 0);
+ if (keyXPos < 0) {
+ // If keyXPos is negative, the actual x-coordinate will be
+ // keyboardWidth + keyXPos.
+ // keyXPos shouldn't be less than mCurrentX because drawable area for this
+ // key starts at mCurrentX. Or, this key will overlaps the adjacent key on
+ // its left hand side.
+ return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
+ } else {
+ return keyXPos + mParams.mHorizontalEdgesPadding;
+ }
+ }
+ return mCurrentX;
+ }
+
+ public float getKeyWidth(TypedArray keyAttr) {
+ return getKeyWidth(keyAttr, mCurrentX);
+ }
+
+ public float getKeyWidth(TypedArray keyAttr, float keyXPos) {
+ final int widthType = Builder.getEnumValue(keyAttr,
+ R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
+ switch (widthType) {
+ case KEYWIDTH_FILL_RIGHT:
+ case KEYWIDTH_FILL_BOTH:
+ final int keyboardRightEdge =
+ mParams.mOccupiedWidth - mParams.mHorizontalEdgesPadding;
+ // If keyWidth is fillRight, the actual key width will be determined to fill
+ // out the area up to the right edge of the keyboard.
+ // If keyWidth is fillBoth, the actual key width will be determined to fill out
+ // the area between the nearest key on the left hand side and the right edge of
+ // the keyboard.
+ return keyboardRightEdge - keyXPos;
+ default: // KEYWIDTH_NOT_ENUM
+ return Builder.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_keyWidth,
+ mParams.mBaseWidth, mDefaultKeyWidth);
+ }
+ }
+ }
+
+ public Builder(Context context, KP params) {
+ mContext = context;
+ final Resources res = context.getResources();
+ mResources = res;
+ mDisplayMetrics = res.getDisplayMetrics();
+
+ mParams = params;
+
+ setTouchPositionCorrectionData(context, params);
+ setAdditionalProximityChars(context, params);
+
+ params.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
+ params.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
+ }
+
+ private static void setTouchPositionCorrectionData(Context context, Params params) {
+ final TypedArray a = context.obtainStyledAttributes(
+ null, R.styleable.Keyboard, R.attr.keyboardStyle, 0);
+ params.mThemeId = a.getInt(R.styleable.Keyboard_themeId, 0);
+ final int resourceId = a.getResourceId(
+ R.styleable.Keyboard_touchPositionCorrectionData, 0);
+ a.recycle();
+ if (resourceId == 0) {
+ if (LatinImeLogger.sDBG)
+ Log.e(BUILDER_TAG, "touchPositionCorrectionData is not defined");
+ return;
+ }
+
+ final String[] data = context.getResources().getStringArray(resourceId);
+ params.mTouchPositionCorrection.load(data);
+ }
+
+ private static void setAdditionalProximityChars(Context context, Params params) {
+ final String[] additionalChars =
+ context.getResources().getStringArray(R.array.additional_proximitychars);
+ int currentPrimaryIndex = 0;
+ for (int i = 0; i < additionalChars.length; ++i) {
+ final String additionalChar = additionalChars[i];
+ if (TextUtils.isEmpty(additionalChar)) {
+ currentPrimaryIndex = 0;
+ } else if (currentPrimaryIndex == 0) {
+ currentPrimaryIndex = additionalChar.charAt(0);
+ params.mAdditionalProximityChars.put(
+ currentPrimaryIndex, new ArrayList<Integer>());
+ } else if (currentPrimaryIndex != 0) {
+ final int c = additionalChar.charAt(0);
+ params.mAdditionalProximityChars.get(currentPrimaryIndex).add(c);
+ }
+ }
+ }
+
+ public void setAutoGenerate(KeyboardSet.KeysCache keysCache) {
+ mParams.mKeysCache = keysCache;
+ }
+
+ public Builder<KP> load(int xmlId, KeyboardId id) {
+ mParams.mId = id;
+ final XmlResourceParser parser = mResources.getXml(xmlId);
+ try {
+ parseKeyboard(parser);
+ } catch (XmlPullParserException e) {
+ Log.w(BUILDER_TAG, "keyboard XML parse error: " + e);
+ throw new IllegalArgumentException(e);
+ } catch (IOException e) {
+ Log.w(BUILDER_TAG, "keyboard XML parse error: " + e);
+ throw new RuntimeException(e);
+ } finally {
+ parser.close();
+ }
+ return this;
+ }
+
+ public void setTouchPositionCorrectionEnabled(boolean enabled) {
+ mParams.mTouchPositionCorrection.setEnabled(enabled);
+ }
+
+ public Keyboard build() {
+ return new Keyboard(mParams);
+ }
+
+ private int mIndent;
+ private static final String SPACES = " ";
+
+ private static String spaces(int count) {
+ return (count < SPACES.length()) ? SPACES.substring(0, count) : SPACES;
+ }
+
+ private void startTag(String format, Object ... args) {
+ Log.d(BUILDER_TAG, String.format(spaces(++mIndent * 2) + format, args));
+ }
+
+ private void endTag(String format, Object ... args) {
+ Log.d(BUILDER_TAG, String.format(spaces(mIndent-- * 2) + format, args));
+ }
+
+ private void startEndTag(String format, Object ... args) {
+ Log.d(BUILDER_TAG, String.format(spaces(++mIndent * 2) + format, args));
+ mIndent--;
+ }
+
+ private void parseKeyboard(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ if (DEBUG) startTag("<%s> %s", TAG_KEYBOARD, mParams.mId);
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_KEYBOARD.equals(tag)) {
+ parseKeyboardAttributes(parser);
+ startKeyboard();
+ parseKeyboardContent(parser, false);
+ break;
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD);
+ }
+ }
+ }
+ }
+
+ private void parseKeyboardAttributes(XmlPullParser parser) {
+ final int displayWidth = mDisplayMetrics.widthPixels;
+ final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
+ Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
+ R.style.Keyboard);
+ final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Key);
+ try {
+ final int displayHeight = mDisplayMetrics.heightPixels;
+ final int keyboardHeight = (int)keyboardAttr.getDimension(
+ R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
+ final int maxKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
+ int minKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
+ if (minKeyboardHeight < 0) {
+ // Specified fraction was negative, so it should be calculated against display
+ // width.
+ minKeyboardHeight = -(int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
+ }
+ final Params params = mParams;
+ // Keyboard height will not exceed maxKeyboardHeight and will not be less than
+ // minKeyboardHeight.
+ params.mOccupiedHeight = Math.max(
+ Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
+ params.mOccupiedWidth = params.mId.mWidth;
+ params.mTopPadding = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_keyboardTopPadding, params.mOccupiedHeight, 0);
+ params.mBottomPadding = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_keyboardBottomPadding, params.mOccupiedHeight, 0);
+ params.mHorizontalEdgesPadding = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_keyboardHorizontalEdgesPadding,
+ mParams.mOccupiedWidth, 0);
+
+ params.mBaseWidth = params.mOccupiedWidth - params.mHorizontalEdgesPadding * 2
+ - params.mHorizontalCenterPadding;
+ params.mDefaultKeyWidth = (int)getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_keyWidth, params.mBaseWidth,
+ params.mBaseWidth / DEFAULT_KEYBOARD_COLUMNS);
+ params.mHorizontalGap = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_horizontalGap, params.mBaseWidth, 0);
+ params.mVerticalGap = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_verticalGap, params.mOccupiedHeight, 0);
+ params.mBaseHeight = params.mOccupiedHeight - params.mTopPadding
+ - params.mBottomPadding + params.mVerticalGap;
+ params.mDefaultRowHeight = (int)getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_rowHeight, params.mBaseHeight,
+ params.mBaseHeight / DEFAULT_KEYBOARD_ROWS);
+
+ params.mMoreKeysTemplate = keyboardAttr.getResourceId(
+ R.styleable.Keyboard_moreKeysTemplate, 0);
+ params.mMaxMoreKeysKeyboardColumn = keyAttr.getInt(
+ R.styleable.Keyboard_Key_maxMoreKeysColumn, 5);
+
+ params.mIconsSet.loadIcons(keyboardAttr);
+ } finally {
+ keyAttr.recycle();
+ keyboardAttr.recycle();
+ }
+ }
+
+ private void parseKeyboardContent(XmlPullParser parser, boolean skip)
+ throws XmlPullParserException, IOException {
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_ROW.equals(tag)) {
+ Row row = parseRowAttributes(parser);
+ if (DEBUG) startTag("<%s>%s", TAG_ROW, skip ? " skipped" : "");
+ if (!skip) {
+ startRow(row);
+ }
+ parseRowContent(parser, row, skip);
+ } else if (TAG_INCLUDE.equals(tag)) {
+ parseIncludeKeyboardContent(parser, skip);
+ } else if (TAG_SWITCH.equals(tag)) {
+ parseSwitchKeyboardContent(parser, skip);
+ } else if (TAG_KEY_STYLE.equals(tag)) {
+ parseKeyStyle(parser, skip);
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_ROW);
+ }
+ } else if (event == XmlPullParser.END_TAG) {
+ final String tag = parser.getName();
+ if (DEBUG) endTag("</%s>", tag);
+ if (TAG_KEYBOARD.equals(tag)) {
+ endKeyboard();
+ break;
+ } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
+ || TAG_MERGE.equals(tag)) {
+ break;
+ } else {
+ throw new XmlParseUtils.IllegalEndTag(parser, TAG_ROW);
+ }
+ }
+ }
+ }
+
+ private Row parseRowAttributes(XmlPullParser parser) throws XmlPullParserException {
+ final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard);
+ try {
+ if (a.hasValue(R.styleable.Keyboard_horizontalGap))
+ throw new XmlParseUtils.IllegalAttribute(parser, "horizontalGap");
+ if (a.hasValue(R.styleable.Keyboard_verticalGap))
+ throw new XmlParseUtils.IllegalAttribute(parser, "verticalGap");
+ return new Row(mResources, mParams, parser, mCurrentY);
+ } finally {
+ a.recycle();
+ }
+ }
+
+ private void parseRowContent(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_KEY.equals(tag)) {
+ parseKey(parser, row, skip);
+ } else if (TAG_SPACER.equals(tag)) {
+ parseSpacer(parser, row, skip);
+ } else if (TAG_INCLUDE.equals(tag)) {
+ parseIncludeRowContent(parser, row, skip);
+ } else if (TAG_SWITCH.equals(tag)) {
+ parseSwitchRowContent(parser, row, skip);
+ } else if (TAG_KEY_STYLE.equals(tag)) {
+ parseKeyStyle(parser, skip);
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY);
+ }
+ } else if (event == XmlPullParser.END_TAG) {
+ final String tag = parser.getName();
+ if (DEBUG) endTag("</%s>", tag);
+ if (TAG_ROW.equals(tag)) {
+ if (!skip) {
+ endRow(row);
+ }
+ break;
+ } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
+ || TAG_MERGE.equals(tag)) {
+ break;
+ } else {
+ throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
+ }
+ }
+ }
+ }
+
+ private void parseKey(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ if (skip) {
+ XmlParseUtils.checkEndTag(TAG_KEY, parser);
+ if (DEBUG) startEndTag("<%s /> skipped", TAG_KEY);
+ } else {
+ final Key key = new Key(mResources, mParams, row, parser, mKeyStyles);
+ if (DEBUG) {
+ startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY,
+ (key.isEnabled() ? "" : " disabled"), key,
+ Arrays.toString(key.mMoreKeys));
+ }
+ XmlParseUtils.checkEndTag(TAG_KEY, parser);
+ endKey(key);
+ }
+ }
+
+ private void parseSpacer(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ if (skip) {
+ XmlParseUtils.checkEndTag(TAG_SPACER, parser);
+ if (DEBUG) startEndTag("<%s /> skipped", TAG_SPACER);
+ } else {
+ final Key.Spacer spacer = new Key.Spacer(
+ mResources, mParams, row, parser, mKeyStyles);
+ if (DEBUG) startEndTag("<%s />", TAG_SPACER);
+ XmlParseUtils.checkEndTag(TAG_SPACER, parser);
+ endKey(spacer);
+ }
+ }
+
+ private void parseIncludeKeyboardContent(XmlPullParser parser, boolean skip)
+ throws XmlPullParserException, IOException {
+ parseIncludeInternal(parser, null, skip);
+ }
+
+ private void parseIncludeRowContent(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ parseIncludeInternal(parser, row, skip);
+ }
+
+ private void parseIncludeInternal(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ if (skip) {
+ XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
+ if (DEBUG) startEndTag("</%s> skipped", TAG_INCLUDE);
+ } else {
+ final AttributeSet attr = Xml.asAttributeSet(parser);
+ final TypedArray keyboardAttr = mResources.obtainAttributes(attr,
+ R.styleable.Keyboard_Include);
+ final TypedArray keyAttr = mResources.obtainAttributes(attr,
+ R.styleable.Keyboard_Key);
+ int keyboardLayout = 0;
+ float savedDefaultKeyWidth = 0;
+ try {
+ XmlParseUtils.checkAttributeExists(keyboardAttr,
+ R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout",
+ TAG_INCLUDE, parser);
+ keyboardLayout = keyboardAttr.getResourceId(
+ R.styleable.Keyboard_Include_keyboardLayout, 0);
+ if (row != null) {
+ savedDefaultKeyWidth = row.getDefaultKeyWidth();
+ if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
+ // Override current x coordinate.
+ row.setXPos(row.getKeyX(keyAttr));
+ }
+ if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyWidth)) {
+ // Override default key width.
+ row.setDefaultKeyWidth(row.getKeyWidth(keyAttr));
+ }
+ }
+ } finally {
+ keyboardAttr.recycle();
+ keyAttr.recycle();
+ }
+
+ XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
+ if (DEBUG) {
+ startEndTag("<%s keyboardLayout=%s />",TAG_INCLUDE,
+ mResources.getResourceEntryName(keyboardLayout));
+ }
+ final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout);
+ try {
+ parseMerge(parserForInclude, row, skip);
+ } finally {
+ if (row != null) {
+ // Restore default key width.
+ row.setDefaultKeyWidth(savedDefaultKeyWidth);
+ }
+ parserForInclude.close();
+ }
+ }
+ }
+
+ private void parseMerge(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ if (DEBUG) startTag("<%s>", TAG_MERGE);
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_MERGE.equals(tag)) {
+ if (row == null) {
+ parseKeyboardContent(parser, skip);
+ } else {
+ parseRowContent(parser, row, skip);
+ }
+ break;
+ } else {
+ throw new XmlParseUtils.ParseException(
+ "Included keyboard layout must have <merge> root element", parser);
+ }
+ }
+ }
+ }
+
+ private void parseSwitchKeyboardContent(XmlPullParser parser, boolean skip)
+ throws XmlPullParserException, IOException {
+ parseSwitchInternal(parser, null, skip);
+ }
+
+ private void parseSwitchRowContent(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ parseSwitchInternal(parser, row, skip);
+ }
+
+ private void parseSwitchInternal(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ if (DEBUG) startTag("<%s> %s", TAG_SWITCH, mParams.mId);
+ boolean selected = false;
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_CASE.equals(tag)) {
+ selected |= parseCase(parser, row, selected ? true : skip);
+ } else if (TAG_DEFAULT.equals(tag)) {
+ selected |= parseDefault(parser, row, selected ? true : skip);
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY);
+ }
+ } else if (event == XmlPullParser.END_TAG) {
+ final String tag = parser.getName();
+ if (TAG_SWITCH.equals(tag)) {
+ if (DEBUG) endTag("</%s>", TAG_SWITCH);
+ break;
+ } else {
+ throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
+ }
+ }
+ }
+ }
+
+ private boolean parseCase(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ final boolean selected = parseCaseCondition(parser);
+ if (row == null) {
+ // Processing Rows.
+ parseKeyboardContent(parser, selected ? skip : true);
+ } else {
+ // Processing Keys.
+ parseRowContent(parser, row, selected ? skip : true);
+ }
+ return selected;
+ }
+
+ private boolean parseCaseCondition(XmlPullParser parser) {
+ final KeyboardId id = mParams.mId;
+ if (id == null)
+ return true;
+
+ final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Case);
+ try {
+ final boolean keyboardSetElementMatched = matchTypedValue(a,
+ R.styleable.Keyboard_Case_keyboardSetElement, id.mElementId,
+ KeyboardId.elementIdToName(id.mElementId));
+ final boolean modeMatched = matchTypedValue(a,
+ R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
+ final boolean navigateActionMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_navigateAction, id.navigateAction());
+ final boolean passwordInputMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
+ final boolean hasSettingsKeyMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_hasSettingsKey, id.hasSettingsKey());
+ final boolean f2KeyModeMatched = matchInteger(a,
+ R.styleable.Keyboard_Case_f2KeyMode, id.f2KeyMode());
+ final boolean clobberSettingsKeyMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
+ final boolean shortcutKeyEnabledMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
+ final boolean hasShortcutKeyMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
+ final boolean isMultiLineMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
+ final boolean imeActionMatched = matchInteger(a,
+ R.styleable.Keyboard_Case_imeAction, id.imeAction());
+ final boolean localeCodeMatched = matchString(a,
+ R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
+ final boolean languageCodeMatched = matchString(a,
+ R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
+ final boolean countryCodeMatched = matchString(a,
+ R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
+ final boolean selected = keyboardSetElementMatched && modeMatched
+ && navigateActionMatched && passwordInputMatched && hasSettingsKeyMatched
+ && f2KeyModeMatched && clobberSettingsKeyMatched
+ && shortcutKeyEnabledMatched && hasShortcutKeyMatched && isMultiLineMatched
+ && imeActionMatched && localeCodeMatched && languageCodeMatched
+ && countryCodeMatched;
+
+ if (DEBUG) {
+ startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
+ textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement),
+ "keyboardSetElement"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
+ booleanAttr(a, R.styleable.Keyboard_Case_navigateAction,
+ "navigateAction"),
+ booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
+ "passwordInput"),
+ booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey,
+ "hasSettingsKey"),
+ textAttr(KeyboardId.f2KeyModeName(
+ a.getInt(R.styleable.Keyboard_Case_f2KeyMode, -1)),
+ "f2KeyMode"),
+ booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
+ "clobberSettingsKey"),
+ booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyEnabled,
+ "shortcutKeyEnabled"),
+ booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey,
+ "hasShortcutKey"),
+ booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine,
+ "isMultiLine"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_imeAction),
+ "imeAction"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_localeCode),
+ "localeCode"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_languageCode),
+ "languageCode"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_countryCode),
+ "countryCode"),
+ selected ? "" : " skipped");
+ }
+
+ return selected;
+ } finally {
+ a.recycle();
+ }
+ }
+
+ private static boolean matchInteger(TypedArray a, int index, int value) {
+ // If <case> does not have "index" attribute, that means this <case> is wild-card for
+ // the attribute.
+ return !a.hasValue(index) || a.getInt(index, 0) == value;
+ }
+
+ private static boolean matchBoolean(TypedArray a, int index, boolean value) {
+ // If <case> does not have "index" attribute, that means this <case> is wild-card for
+ // the attribute.
+ return !a.hasValue(index) || a.getBoolean(index, false) == value;
+ }
+
+ private static boolean matchString(TypedArray a, int index, String value) {
+ // If <case> does not have "index" attribute, that means this <case> is wild-card for
+ // the attribute.
+ return !a.hasValue(index)
+ || stringArrayContains(a.getString(index).split("\\|"), value);
+ }
+
+ private static boolean matchTypedValue(TypedArray a, int index, int intValue,
+ String strValue) {
+ // If <case> does not have "index" attribute, that means this <case> is wild-card for
+ // the attribute.
+ final TypedValue v = a.peekValue(index);
+ if (v == null)
+ return true;
+
+ if (isIntegerValue(v)) {
+ return intValue == a.getInt(index, 0);
+ } else if (isStringValue(v)) {
+ return stringArrayContains(a.getString(index).split("\\|"), strValue);
+ }
+ return false;
+ }
+
+ private static boolean stringArrayContains(String[] array, String value) {
+ for (final String elem : array) {
+ if (elem.equals(value))
+ return true;
+ }
+ return false;
+ }
+
+ private boolean parseDefault(XmlPullParser parser, Row row, boolean skip)
+ throws XmlPullParserException, IOException {
+ if (DEBUG) startTag("<%s>", TAG_DEFAULT);
+ if (row == null) {
+ parseKeyboardContent(parser, skip);
+ } else {
+ parseRowContent(parser, row, skip);
+ }
+ return true;
+ }
+
+ private void parseKeyStyle(XmlPullParser parser, boolean skip)
+ throws XmlPullParserException, IOException {
+ TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_KeyStyle);
+ TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Key);
+ try {
+ if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName))
+ throw new XmlParseUtils.ParseException("<" + TAG_KEY_STYLE
+ + "/> needs styleName attribute", parser);
+ if (DEBUG) {
+ startEndTag("<%s styleName=%s />%s", TAG_KEY_STYLE,
+ keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName),
+ skip ? " skipped" : "");
+ }
+ if (!skip)
+ mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser);
+ } finally {
+ keyStyleAttr.recycle();
+ keyAttrs.recycle();
+ }
+ XmlParseUtils.checkEndTag(TAG_KEY_STYLE, parser);
+ }
+
+ private void startKeyboard() {
+ mCurrentY += mParams.mTopPadding;
+ mTopEdge = true;
+ }
+
+ private void startRow(Row row) {
+ addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
+ mCurrentRow = row;
+ mLeftEdge = true;
+ mRightEdgeKey = null;
+ }
+
+ private void endRow(Row row) {
+ if (mCurrentRow == null)
+ throw new InflateException("orphant end row tag");
+ if (mRightEdgeKey != null) {
+ mRightEdgeKey.markAsRightEdge(mParams);
+ mRightEdgeKey = null;
+ }
+ addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
+ mCurrentY += row.mRowHeight;
+ mCurrentRow = null;
+ mTopEdge = false;
+ }
+
+ private void endKey(Key key) {
+ mParams.onAddKey(key);
+ if (mLeftEdge) {
+ key.markAsLeftEdge(mParams);
+ mLeftEdge = false;
+ }
+ if (mTopEdge) {
+ key.markAsTopEdge(mParams);
+ }
+ mRightEdgeKey = key;
+ }
+
+ private void endKeyboard() {
+ // nothing to do here.
+ }
+
+ private void addEdgeSpace(float width, Row row) {
+ row.advanceXPos(width);
+ mLeftEdge = false;
+ mRightEdgeKey = null;
+ }
+
+ public static float getDimensionOrFraction(TypedArray a, int index, int base,
+ float defValue) {
+ final TypedValue value = a.peekValue(index);
+ if (value == null)
+ return defValue;
+ if (isFractionValue(value)) {
+ return a.getFraction(index, base, base, defValue);
+ } else if (isDimensionValue(value)) {
+ return a.getDimension(index, defValue);
+ }
+ return defValue;
+ }
+
+ public static int getEnumValue(TypedArray a, int index, int defValue) {
+ final TypedValue value = a.peekValue(index);
+ if (value == null)
+ return defValue;
+ if (isIntegerValue(value)) {
+ return a.getInt(index, defValue);
+ }
+ return defValue;
+ }
+
+ private static boolean isFractionValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_FRACTION;
+ }
+
+ private static boolean isDimensionValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_DIMENSION;
+ }
+
+ private static boolean isIntegerValue(TypedValue v) {
+ return v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT;
+ }
+
+ private static boolean isStringValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_STRING;
+ }
+
+ private static String textAttr(String value, String name) {
+ return value != null ? String.format(" %s=%s", name, value) : "";
+ }
+
+ private static String booleanAttr(TypedArray a, int index, String name) {
+ return a.hasValue(index)
+ ? String.format(" %s=%s", name, a.getBoolean(index, false)) : "";
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 6f5420882..6e13b95b5 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -24,10 +24,8 @@ public interface KeyboardActionListener {
*
* @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key,
* the value will be zero.
- * @param withSliding true if pressing has occurred because the user slid finger from other key
- * to this key without releasing the finger.
*/
- public void onPress(int primaryCode, boolean withSliding);
+ public void onPressKey(int primaryCode);
/**
* Called when the user releases a key. This is sent after the {@link #onCodeInput} is called.
@@ -37,7 +35,7 @@ public interface KeyboardActionListener {
* @param withSliding true if releasing has occurred because the user slid finger from the key
* to other key without releasing the finger.
*/
- public void onRelease(int primaryCode, boolean withSliding);
+ public void onReleaseKey(int primaryCode, boolean withSliding);
/**
* Send a key code to the listener.
@@ -50,14 +48,17 @@ public interface KeyboardActionListener {
* presses of a key adjacent to the intended key.
* @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
* {@link PointerTracker#onTouchEvent} or so, the value should be
- * {@link #NOT_A_TOUCH_COORDINATE}.
+ * {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
+ * strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
* @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by
* {@link PointerTracker#onTouchEvent} or so, the value should be
- * {@link #NOT_A_TOUCH_COORDINATE}.
+ * {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion
+ * strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}.
*/
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y);
public static final int NOT_A_TOUCH_COORDINATE = -1;
+ public static final int SUGGESTION_STRIP_COORDINATE = -2;
/**
* Sends a sequence of characters to the listener.
@@ -79,9 +80,9 @@ public interface KeyboardActionListener {
public static class Adapter implements KeyboardActionListener {
@Override
- public void onPress(int primaryCode, boolean withSliding) {}
+ public void onPressKey(int primaryCode) {}
@Override
- public void onRelease(int primaryCode, boolean withSliding) {}
+ public void onReleaseKey(int primaryCode, boolean withSliding) {}
@Override
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 2e4988fb0..3ab24933c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -16,18 +16,18 @@
package com.android.inputmethod.keyboard;
+import android.text.InputType;
+import android.text.TextUtils;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.compat.InputTypeCompatUtils;
-import com.android.inputmethod.latin.R;
import java.util.Arrays;
import java.util.Locale;
/**
- * Represents the parameters necessary to construct a new LatinKeyboard,
- * which also serve as a unique identifier for each keyboard type.
+ * Unique identifier for each keyboard type.
*/
public class KeyboardId {
public static final int MODE_TEXT = 0;
@@ -37,104 +37,169 @@ public class KeyboardId {
public static final int MODE_PHONE = 4;
public static final int MODE_NUMBER = 5;
- public static final int F2KEY_MODE_NONE = 0;
- public static final int F2KEY_MODE_SETTINGS = 1;
- public static final int F2KEY_MODE_SHORTCUT_IME = 2;
- public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
+ public static final int ELEMENT_ALPHABET = 0;
+ public static final int ELEMENT_ALPHABET_MANUAL_SHIFTED = 1;
+ public static final int ELEMENT_ALPHABET_AUTOMATIC_SHIFTED = 2;
+ public static final int ELEMENT_ALPHABET_SHIFT_LOCKED = 3;
+ public static final int ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED = 4;
+ public static final int ELEMENT_SYMBOLS = 5;
+ public static final int ELEMENT_SYMBOLS_SHIFTED = 6;
+ public static final int ELEMENT_PHONE = 7;
+ public static final int ELEMENT_PHONE_SYMBOLS = 8;
+ public static final int ELEMENT_NUMBER = 9;
+
+ private static final int F2KEY_MODE_NONE = 0;
+ private static final int F2KEY_MODE_SETTINGS = 1;
+ private static final int F2KEY_MODE_SHORTCUT_IME = 2;
+ private static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
+
+ private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
public final Locale mLocale;
public final int mOrientation;
public final int mWidth;
public final int mMode;
- public final int mXmlId;
- public final boolean mNavigateAction;
- public final boolean mPasswordInput;
- // TODO: Clean up these booleans and modes.
- public final boolean mHasSettingsKey;
- public final int mF2KeyMode;
+ public final int mElementId;
+ private final EditorInfo mEditorInfo;
+ private final boolean mSettingsKeyEnabled;
public final boolean mClobberSettingsKey;
public final boolean mShortcutKeyEnabled;
public final boolean mHasShortcutKey;
- public final int mImeAction;
-
- public final String mXmlName;
- public final EditorInfo mAttribute;
+ public final String mCustomActionLabel;
private final int mHashCode;
- public KeyboardId(String xmlName, int xmlId, Locale locale, int orientation, int width,
- int mode, EditorInfo attribute, boolean hasSettingsKey, int f2KeyMode,
- boolean clobberSettingsKey, boolean shortcutKeyEnabled, boolean hasShortcutKey) {
- final int inputType = (attribute != null) ? attribute.inputType : 0;
- final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
+ public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
+ EditorInfo editorInfo, boolean settingsKeyEnabled, boolean clobberSettingsKey,
+ boolean shortcutKeyEnabled, boolean hasShortcutKey) {
this.mLocale = locale;
this.mOrientation = orientation;
this.mWidth = width;
this.mMode = mode;
- this.mXmlId = xmlId;
- // Note: Turn off checking navigation flag to show TAB key for now.
- this.mNavigateAction = InputTypeCompatUtils.isWebInputType(inputType);
-// || EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
-// || EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions);
- this.mPasswordInput = InputTypeCompatUtils.isPasswordInputType(inputType)
- || InputTypeCompatUtils.isVisiblePasswordInputType(inputType);
- this.mHasSettingsKey = hasSettingsKey;
- this.mF2KeyMode = f2KeyMode;
+ this.mElementId = elementId;
+ this.mEditorInfo = editorInfo;
+ this.mSettingsKeyEnabled = settingsKeyEnabled;
this.mClobberSettingsKey = clobberSettingsKey;
this.mShortcutKeyEnabled = shortcutKeyEnabled;
this.mHasShortcutKey = hasShortcutKey;
- // We are interested only in {@link EditorInfo#IME_MASK_ACTION} enum value and
- // {@link EditorInfo#IME_FLAG_NO_ENTER_ACTION}.
- this.mImeAction = imeOptions & (
- EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
-
- this.mXmlName = xmlName;
- this.mAttribute = attribute;
-
- this.mHashCode = Arrays.hashCode(new Object[] {
- locale,
- orientation,
- width,
- mode,
- xmlId,
- mNavigateAction,
- mPasswordInput,
- hasSettingsKey,
- f2KeyMode,
- clobberSettingsKey,
- shortcutKeyEnabled,
- hasShortcutKey,
- mImeAction,
- });
+ this.mCustomActionLabel = (editorInfo.actionLabel != null)
+ ? editorInfo.actionLabel.toString() : null;
+
+ this.mHashCode = hashCode(this);
}
- public KeyboardId cloneWithNewXml(String xmlName, int xmlId) {
- return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mAttribute,
- false, F2KEY_MODE_NONE, false, false, false);
+ private static int hashCode(KeyboardId id) {
+ return Arrays.hashCode(new Object[] {
+ id.mOrientation,
+ id.mElementId,
+ id.mMode,
+ id.mWidth,
+ id.navigateAction(),
+ id.passwordInput(),
+ id.mSettingsKeyEnabled,
+ id.mClobberSettingsKey,
+ id.mShortcutKeyEnabled,
+ id.mHasShortcutKey,
+ id.isMultiLine(),
+ id.imeAction(),
+ id.mCustomActionLabel,
+ id.mLocale
+ });
}
- public int getXmlId() {
- return mXmlId;
+ private boolean equals(KeyboardId other) {
+ if (other == this)
+ return true;
+ return other.mOrientation == this.mOrientation
+ && other.mElementId == this.mElementId
+ && other.mMode == this.mMode
+ && other.mWidth == this.mWidth
+ && other.navigateAction() == this.navigateAction()
+ && other.passwordInput() == this.passwordInput()
+ && other.mSettingsKeyEnabled == this.mSettingsKeyEnabled
+ && other.mClobberSettingsKey == this.mClobberSettingsKey
+ && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
+ && other.mHasShortcutKey == this.mHasShortcutKey
+ && other.isMultiLine() == this.isMultiLine()
+ && other.imeAction() == this.imeAction()
+ && TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel)
+ && other.mLocale.equals(this.mLocale);
}
public boolean isAlphabetKeyboard() {
- return mXmlId == R.xml.kbd_qwerty;
+ return mElementId < ELEMENT_SYMBOLS;
+ }
+
+ public boolean isAlphabetShiftLockedKeyboard() {
+ return mElementId == ELEMENT_ALPHABET_SHIFT_LOCKED
+ || mElementId == ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED;
+ }
+
+ public boolean isAlphabetShiftedOrShiftLockedKeyboard() {
+ return isAlphabetKeyboard() && mElementId != ELEMENT_ALPHABET;
+ }
+
+ public boolean isAlphabetManualShiftedKeyboard() {
+ return mElementId == ELEMENT_ALPHABET_MANUAL_SHIFTED;
}
public boolean isSymbolsKeyboard() {
- return mXmlId == R.xml.kbd_symbols || mXmlId == R.xml.kbd_symbols_shift;
+ return mElementId == ELEMENT_SYMBOLS || mElementId == ELEMENT_SYMBOLS_SHIFTED;
}
public boolean isPhoneKeyboard() {
- return mMode == MODE_PHONE;
+ return mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS;
}
public boolean isPhoneShiftKeyboard() {
- return mXmlId == R.xml.kbd_phone_shift;
+ return mElementId == ELEMENT_PHONE_SYMBOLS;
+ }
+
+ public boolean navigateAction() {
+ // Note: Turn off checking navigation flag to show TAB key for now.
+ boolean navigateAction = InputTypeCompatUtils.isWebInputType(mEditorInfo.inputType);
+// || EditorInfoCompatUtils.hasFlagNavigateNext(mImeOptions)
+// || EditorInfoCompatUtils.hasFlagNavigatePrevious(mImeOptions);
+ return navigateAction;
+ }
+
+ public boolean passwordInput() {
+ final int inputType = mEditorInfo.inputType;
+ return InputTypeCompatUtils.isPasswordInputType(inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(inputType);
}
- public boolean isNumberKeyboard() {
- return mMode == MODE_NUMBER;
+ public boolean isMultiLine() {
+ return (mEditorInfo.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0;
+ }
+
+ public int imeAction() {
+ if ((mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
+ return EditorInfo.IME_ACTION_NONE;
+ } else if (mEditorInfo.actionLabel != null) {
+ return IME_ACTION_CUSTOM_LABEL;
+ } else {
+ return mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION;
+ }
+ }
+
+ public boolean hasSettingsKey() {
+ return mSettingsKeyEnabled && !mClobberSettingsKey;
+ }
+
+ public int f2KeyMode() {
+ if (mClobberSettingsKey) {
+ // Never shows the Settings key
+ return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
+ }
+
+ if (mSettingsKeyEnabled) {
+ return KeyboardId.F2KEY_MODE_SETTINGS;
+ } else {
+ // It should be alright to fall back to the Settings key on 7-inch layouts
+ // even when the Settings key is not explicitly enabled.
+ return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
+ }
}
@Override
@@ -142,22 +207,6 @@ public class KeyboardId {
return other instanceof KeyboardId && equals((KeyboardId) other);
}
- private boolean equals(KeyboardId other) {
- return other.mLocale.equals(this.mLocale)
- && other.mOrientation == this.mOrientation
- && other.mWidth == this.mWidth
- && other.mMode == this.mMode
- && other.mXmlId == this.mXmlId
- && other.mNavigateAction == this.mNavigateAction
- && other.mPasswordInput == this.mPasswordInput
- && other.mHasSettingsKey == this.mHasSettingsKey
- && other.mF2KeyMode == this.mF2KeyMode
- && other.mClobberSettingsKey == this.mClobberSettingsKey
- && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
- && other.mHasShortcutKey == this.mHasShortcutKey
- && other.mImeAction == this.mImeAction;
- }
-
@Override
public int hashCode() {
return mHashCode;
@@ -165,22 +214,46 @@ public class KeyboardId {
@Override
public String toString() {
- return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s]",
- mXmlName,
+ return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]",
+ elementIdToName(mElementId),
mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode),
- EditorInfoCompatUtils.imeOptionsName(mImeAction),
- f2KeyModeName(mF2KeyMode),
+ imeAction(),
+ f2KeyModeName(f2KeyMode()),
(mClobberSettingsKey ? " clobberSettingsKey" : ""),
- (mNavigateAction ? " navigateAction" : ""),
- (mPasswordInput ? " passwordInput" : ""),
- (mHasSettingsKey ? " hasSettingsKey" : ""),
+ (navigateAction() ? " navigateAction" : ""),
+ (passwordInput() ? " passwordInput" : ""),
+ (hasSettingsKey() ? " hasSettingsKey" : ""),
(mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
(mHasShortcutKey ? " hasShortcutKey" : "")
);
}
+ public static boolean equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b) {
+ if (a == null && b == null) return true;
+ if (a == null || b == null) return false;
+ return a.inputType == b.inputType
+ && a.imeOptions == b.imeOptions
+ && TextUtils.equals(a.privateImeOptions, b.privateImeOptions);
+ }
+
+ public static String elementIdToName(int elementId) {
+ switch (elementId) {
+ case ELEMENT_ALPHABET: return "alphabet";
+ case ELEMENT_ALPHABET_MANUAL_SHIFTED: return "alphabetManualShifted";
+ case ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: return "alphabetAutomaticShifted";
+ case ELEMENT_ALPHABET_SHIFT_LOCKED: return "alphabetShiftLocked";
+ case ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: return "alphabetShiftLockShifted";
+ case ELEMENT_SYMBOLS: return "symbols";
+ case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted";
+ case ELEMENT_PHONE: return "phone";
+ case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols";
+ case ELEMENT_NUMBER: return "number";
+ default: return null;
+ }
+ }
+
public static String modeName(int mode) {
switch (mode) {
case MODE_TEXT: return "text";
@@ -193,6 +266,11 @@ public class KeyboardId {
}
}
+ public static String actionName(int actionId) {
+ return (actionId == IME_ACTION_CUSTOM_LABEL) ? "actionCustomLabel"
+ : EditorInfoCompatUtils.imeActionName(actionId);
+ }
+
public static String f2KeyModeName(int f2KeyMode) {
switch (f2KeyMode) {
case F2KEY_MODE_NONE: return "none";
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
new file mode 100644
index 000000000..f27170a89
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2011 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;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.Log;
+import android.util.Xml;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.inputmethod.compat.EditorInfoCompatUtils;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.LocaleUtils;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.XmlParseUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * This class represents a set of keyboards. Each of them represents a different keyboard
+ * specific to a keyboard state, such as alphabet, symbols, and so on. Layouts in the same
+ * {@link KeyboardSet} are related to each other.
+ * A {@link KeyboardSet} needs to be created for each {@link android.view.inputmethod.EditorInfo}.
+ */
+public class KeyboardSet {
+ private static final String TAG = KeyboardSet.class.getSimpleName();
+ private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG;
+
+ private static final String TAG_KEYBOARD_SET = TAG;
+ private static final String TAG_ELEMENT = "Element";
+
+ private final Context mContext;
+ private final Params mParams;
+
+ private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
+ new HashMap<KeyboardId, SoftReference<Keyboard>>();
+ private static final KeysCache sKeysCache = new KeysCache();
+
+ private static final EditorInfo EMPTY_EDITOR_INFO = new EditorInfo();
+
+ public static class KeyboardSetException extends RuntimeException {
+ public final KeyboardId mKeyboardId;
+ public KeyboardSetException(Throwable cause, KeyboardId keyboardId) {
+ super(cause);
+ mKeyboardId = keyboardId;
+ }
+ }
+
+ public static class KeysCache {
+ private final Map<Key, Key> mMap;
+
+ public KeysCache() {
+ mMap = new HashMap<Key, Key>();
+ }
+
+ public void clear() {
+ mMap.clear();
+ }
+
+ public Key get(Key key) {
+ final Key existingKey = mMap.get(key);
+ if (existingKey != null) {
+ // Reuse the existing element that equals to "key" without adding "key" to the map.
+ return existingKey;
+ }
+ mMap.put(key, key);
+ return key;
+ }
+ }
+
+ static class Params {
+ int mMode;
+ EditorInfo mEditorInfo;
+ boolean mTouchPositionCorrectionEnabled;
+ boolean mSettingsKeyEnabled;
+ boolean mVoiceKeyEnabled;
+ boolean mVoiceKeyOnMain;
+ boolean mNoSettingsKey;
+ Locale mLocale;
+ int mOrientation;
+ int mWidth;
+ // KeyboardSet element id to keyboard layout XML id map.
+ final Map<Integer, Integer> mKeyboardSetElementIdToXmlIdMap =
+ new HashMap<Integer, Integer>();
+ Params() {}
+ }
+
+ public static void clearKeyboardCache() {
+ sKeyboardCache.clear();
+ sKeysCache.clear();
+ }
+
+ private KeyboardSet(Context context, Params params) {
+ mContext = context;
+ mParams = params;
+ }
+
+ public Keyboard getKeyboard(int baseKeyboardSetElementId) {
+ final int keyboardSetElementId;
+ switch (mParams.mMode) {
+ case KeyboardId.MODE_PHONE:
+ if (baseKeyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS) {
+ keyboardSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS;
+ } else {
+ keyboardSetElementId = KeyboardId.ELEMENT_PHONE;
+ }
+ break;
+ case KeyboardId.MODE_NUMBER:
+ keyboardSetElementId = KeyboardId.ELEMENT_NUMBER;
+ break;
+ default:
+ keyboardSetElementId = baseKeyboardSetElementId;
+ break;
+ }
+
+ Integer keyboardXmlId = mParams.mKeyboardSetElementIdToXmlIdMap.get(keyboardSetElementId);
+ if (keyboardXmlId == null) {
+ keyboardXmlId = mParams.mKeyboardSetElementIdToXmlIdMap.get(
+ KeyboardId.ELEMENT_ALPHABET);
+ }
+ final KeyboardId id = getKeyboardId(keyboardSetElementId);
+ try {
+ return getKeyboard(mContext, keyboardXmlId, id);
+ } catch (RuntimeException e) {
+ throw new KeyboardSetException(e, id);
+ }
+ }
+
+ private Keyboard getKeyboard(Context context, int keyboardXmlId, KeyboardId id) {
+ final Resources res = context.getResources();
+ final SoftReference<Keyboard> ref = sKeyboardCache.get(id);
+ Keyboard keyboard = (ref == null) ? null : ref.get();
+ if (keyboard == null) {
+ final Locale savedLocale = LocaleUtils.setSystemLocale(res, id.mLocale);
+ try {
+ final Keyboard.Builder<Keyboard.Params> builder =
+ new Keyboard.Builder<Keyboard.Params>(context, new Keyboard.Params());
+ if (id.isAlphabetKeyboard()) {
+ builder.setAutoGenerate(sKeysCache);
+ }
+ builder.load(keyboardXmlId, id);
+ builder.setTouchPositionCorrectionEnabled(mParams.mTouchPositionCorrectionEnabled);
+ keyboard = builder.build();
+ } finally {
+ LocaleUtils.setSystemLocale(res, savedLocale);
+ }
+ sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard));
+
+ if (DEBUG_CACHE) {
+ Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": "
+ + ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
+ }
+ } else if (DEBUG_CACHE) {
+ Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": HIT id=" + id);
+ }
+
+ return keyboard;
+ }
+
+ // Note: The keyboard for each locale, shift state, and mode are represented as KeyboardSet
+ // element id that is a key in keyboard_set.xml. Also that file specifies which XML layout
+ // should be used for each keyboard. The KeyboardId is an internal key for Keyboard object.
+ private KeyboardId getKeyboardId(int keyboardSetElementId) {
+ final Params params = mParams;
+ final boolean isSymbols = (keyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS
+ || keyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED);
+ final boolean hasShortcutKey = params.mVoiceKeyEnabled
+ && (isSymbols != params.mVoiceKeyOnMain);
+ return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation,
+ params.mWidth, params.mMode, params.mEditorInfo, params.mSettingsKeyEnabled,
+ params.mNoSettingsKey, params.mVoiceKeyEnabled, hasShortcutKey);
+ }
+
+ public static class Builder {
+ private final Context mContext;
+ private final String mPackageName;
+ private final Resources mResources;
+ private final EditorInfo mEditorInfo;
+
+ private final Params mParams = new Params();
+
+ public Builder(Context context, EditorInfo editorInfo) {
+ mContext = context;
+ mPackageName = context.getPackageName();
+ mResources = context.getResources();
+ mEditorInfo = editorInfo;
+ final Params params = mParams;
+
+ params.mMode = Utils.getKeyboardMode(editorInfo);
+ params.mEditorInfo = (editorInfo != null) ? editorInfo : EMPTY_EDITOR_INFO;
+ params.mNoSettingsKey = Utils.inPrivateImeOptions(
+ mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, mEditorInfo);
+ }
+
+ public Builder setScreenGeometry(int orientation, int widthPixels) {
+ mParams.mOrientation = orientation;
+ mParams.mWidth = widthPixels;
+ return this;
+ }
+
+ // TODO: Use InputMethodSubtype object as argument.
+ public Builder setSubtype(Locale inputLocale, boolean asciiCapable,
+ boolean touchPositionCorrectionEnabled) {
+ final boolean deprecatedForceAscii = Utils.inPrivateImeOptions(
+ mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, mEditorInfo);
+ final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
+ mParams.mEditorInfo.imeOptions)
+ || deprecatedForceAscii;
+ mParams.mLocale = (forceAscii && !asciiCapable) ? Locale.US : inputLocale;
+ mParams.mTouchPositionCorrectionEnabled = touchPositionCorrectionEnabled;
+ return this;
+ }
+
+ public Builder setOptions(boolean settingsKeyEnabled, boolean voiceKeyEnabled,
+ boolean voiceKeyOnMain) {
+ mParams.mSettingsKeyEnabled = settingsKeyEnabled;
+ @SuppressWarnings("deprecation")
+ final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions(
+ null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
+ final boolean noMicrophone = Utils.inPrivateImeOptions(
+ mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, mEditorInfo)
+ || deprecatedNoMicrophone;
+ mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone;
+ mParams.mVoiceKeyOnMain = voiceKeyOnMain;
+ return this;
+ }
+
+ public KeyboardSet build() {
+ if (mParams.mOrientation == Configuration.ORIENTATION_UNDEFINED)
+ throw new RuntimeException("Screen geometry is not specified");
+ if (mParams.mLocale == null)
+ throw new RuntimeException("KeyboardSet subtype is not specified");
+
+ final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, mParams.mLocale);
+ try {
+ parseKeyboardSet(mResources, R.xml.keyboard_set);
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage() + " in "
+ + mResources.getResourceName(R.xml.keyboard_set)
+ + " of locale " + mParams.mLocale);
+ } finally {
+ LocaleUtils.setSystemLocale(mResources, savedLocale);
+ }
+ return new KeyboardSet(mContext, mParams);
+ }
+
+ private void parseKeyboardSet(Resources res, int resId) throws XmlPullParserException,
+ IOException {
+ final XmlResourceParser parser = res.getXml(resId);
+ try {
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_KEYBOARD_SET.equals(tag)) {
+ parseKeyboardSetContent(parser);
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
+ }
+ }
+ }
+ } finally {
+ parser.close();
+ }
+ }
+
+ private void parseKeyboardSetContent(XmlPullParser parser) throws XmlPullParserException,
+ IOException {
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_ELEMENT.equals(tag)) {
+ parseKeyboardSetElement(parser);
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
+ }
+ } else if (event == XmlPullParser.END_TAG) {
+ final String tag = parser.getName();
+ if (TAG_KEYBOARD_SET.equals(tag)) {
+ break;
+ } else {
+ throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEYBOARD_SET);
+ }
+ }
+ }
+ }
+
+ private void parseKeyboardSetElement(XmlPullParser parser) throws XmlPullParserException,
+ IOException {
+ final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.KeyboardSet_Element);
+ try {
+ XmlParseUtils.checkAttributeExists(a,
+ R.styleable.KeyboardSet_Element_elementName, "elementName",
+ TAG_ELEMENT, parser);
+ XmlParseUtils.checkAttributeExists(a,
+ R.styleable.KeyboardSet_Element_elementKeyboard, "elementKeyboard",
+ TAG_ELEMENT, parser);
+ XmlParseUtils.checkEndTag(TAG_ELEMENT, parser);
+
+ final int elementName = a.getInt(
+ R.styleable.KeyboardSet_Element_elementName, 0);
+ final int elementKeyboard = a.getResourceId(
+ R.styleable.KeyboardSet_Element_elementKeyboard, 0);
+ mParams.mKeyboardSetElementIdToXmlIdMap.put(elementName, elementKeyboard);
+ } finally {
+ a.recycle();
+ }
+ }
+ }
+
+ public static String parseKeyboardLocale(Resources res, int resId)
+ throws XmlPullParserException, IOException {
+ final XmlPullParser parser = res.getXml(resId);
+ if (parser == null)
+ return "";
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ if (event == XmlPullParser.START_TAG) {
+ final String tag = parser.getName();
+ if (TAG_KEYBOARD_SET.equals(tag)) {
+ final TypedArray keyboardSetAttr = res.obtainAttributes(
+ Xml.asAttributeSet(parser), R.styleable.KeyboardSet);
+ final String locale = keyboardSetAttr.getString(
+ R.styleable.KeyboardSet_keyboardLocale);
+ keyboardSetAttr.recycle();
+ return locale;
+ } else {
+ throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
+ }
+ }
+ }
+ return "";
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index ac718fc62..5ba560d72 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -18,10 +18,7 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.res.Configuration;
import android.content.res.Resources;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.InflateException;
@@ -30,25 +27,22 @@ import android.view.View;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
-import com.android.inputmethod.keyboard.internal.ModifierKeyState;
-import com.android.inputmethod.keyboard.internal.ShiftKeyState;
+import com.android.inputmethod.keyboard.KeyboardSet.KeyboardSetException;
+import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.keyboard.internal.KeyboardState;
+import com.android.inputmethod.latin.DebugSettings;
import com.android.inputmethod.latin.InputView;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.LocaleUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.SettingsValues;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Utils;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Locale;
-
-public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
+public class KeyboardSwitcher implements KeyboardState.SwitchActions,
+ SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
- private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG;
- public static final boolean DEBUG_STATE = false;
public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916";
private static final int[] KEYBOARD_THEMES = {
@@ -62,99 +56,26 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs;
+ private boolean mForceNonDistinctMultitouch;
private InputView mCurrentInputView;
private LatinKeyboardView mKeyboardView;
private LatinIME mInputMethodService;
- private String mPackageName;
private Resources mResources;
- // TODO: Combine these key state objects with auto mode switch state.
- private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
- private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
-
- private KeyboardId mMainKeyboardId;
- private KeyboardId mSymbolsKeyboardId;
- private KeyboardId mSymbolsShiftedKeyboardId;
+ private KeyboardState mState;
- private KeyboardId mCurrentId;
- private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache =
- new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
-
- private KeyboardLayoutState mSavedKeyboardState = new KeyboardLayoutState();
+ private KeyboardSet mKeyboardSet;
/** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of
* what user actually typed. */
private boolean mIsAutoCorrectionActive;
- // TODO: Encapsulate these state handling to separate class and combine with ShiftKeyState
- // and ModifierKeyState.
- private static final int SWITCH_STATE_ALPHA = 0;
- private static final int SWITCH_STATE_SYMBOL_BEGIN = 1;
- private static final int SWITCH_STATE_SYMBOL = 2;
- // The following states are used only on the distinct multi-touch panel devices.
- private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 3;
- private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 4;
- private static final int SWITCH_STATE_CHORDING_ALPHA = 5;
- private static final int SWITCH_STATE_CHORDING_SYMBOL = 6;
- private int mSwitchState = SWITCH_STATE_ALPHA;
-
- private static String mLayoutSwitchBackSymbols;
-
private int mThemeIndex = -1;
private Context mThemeContext;
private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
- private class KeyboardLayoutState {
- private boolean mIsValid;
- private boolean mIsAlphabetMode;
- private boolean mIsShiftLocked;
- private boolean mIsShifted;
-
- public void save() {
- if (mCurrentId == null) {
- return;
- }
- mIsAlphabetMode = isAlphabetMode();
- if (mIsAlphabetMode) {
- mIsShiftLocked = isShiftLocked();
- mIsShifted = !mIsShiftLocked && isShiftedOrShiftLocked();
- } else {
- mIsShiftLocked = false;
- mIsShifted = mCurrentId.equals(mSymbolsShiftedKeyboardId);
- }
- mIsValid = true;
- }
-
- public KeyboardId getKeyboardId() {
- if (!mIsValid) return mMainKeyboardId;
-
- if (mIsAlphabetMode) {
- return mMainKeyboardId;
- } else {
- return mIsShifted ? mSymbolsShiftedKeyboardId : mSymbolsKeyboardId;
- }
- }
-
- public void restore() {
- if (!mIsValid) return;
- mIsValid = false;
-
- if (mIsAlphabetMode) {
- final boolean isAlphabetMode = isAlphabetMode();
- final boolean isShiftLocked = isAlphabetMode && isShiftLocked();
- final boolean isShifted = !isShiftLocked && isShiftedOrShiftLocked();
- if (mIsShiftLocked != isShiftLocked) {
- toggleCapsLock();
- } else if (mIsShifted != isShifted) {
- onPressShift(false);
- onReleaseShift(false);
- }
- }
- }
- }
-
public static KeyboardSwitcher getInstance() {
return sInstance;
}
@@ -169,12 +90,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void initInternal(LatinIME ims, SharedPreferences prefs) {
mInputMethodService = ims;
- mPackageName = ims.getPackageName();
mResources = ims.getResources();
mPrefs = prefs;
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ mState = new KeyboardState(this);
setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs));
prefs.registerOnSharedPreferenceChangeListener(this);
+ mForceNonDistinctMultitouch = prefs.getBoolean(
+ DebugSettings.FORCE_NON_DISTINCT_MULTITOUCH_KEY, false);
}
private static int getKeyboardThemeIndex(Context context, SharedPreferences prefs) {
@@ -195,26 +118,38 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
if (mThemeIndex != themeIndex) {
mThemeIndex = themeIndex;
mThemeContext = new ContextThemeWrapper(context, KEYBOARD_THEMES[themeIndex]);
- mKeyboardCache.clear();
+ KeyboardSet.clearKeyboardCache();
}
}
- public void loadKeyboard(EditorInfo editorInfo, Settings.Values settingsValues) {
+ public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) {
+ final KeyboardSet.Builder builder = new KeyboardSet.Builder(mThemeContext, editorInfo);
+ builder.setScreenGeometry(mThemeContext.getResources().getConfiguration().orientation,
+ mThemeContext.getResources().getDisplayMetrics().widthPixels);
+ builder.setSubtype(
+ mSubtypeSwitcher.getInputLocale(),
+ mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
+ LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE),
+ mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
+ LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
+ builder.setOptions(
+ settingsValues.isSettingsKeyEnabled(),
+ settingsValues.isVoiceKeyEnabled(editorInfo),
+ settingsValues.isVoiceKeyOnMain());
+ mKeyboardSet = builder.build();
try {
- mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues);
- mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
- mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
- mLayoutSwitchBackSymbols = mResources.getString(R.string.layout_switch_back_symbols);
- setKeyboard(getKeyboard(mSavedKeyboardState.getKeyboardId()));
- mSavedKeyboardState.restore();
- } catch (RuntimeException e) {
- Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
- LatinImeLogger.logOnException(mMainKeyboardId.toString(), e);
+ mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols));
+ } catch (KeyboardSetException e) {
+ Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
+ LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause());
+ return;
}
}
public void saveKeyboardState() {
- mSavedKeyboardState.save();
+ if (getKeyboard() != null) {
+ mState.onSaveKeyboardState();
+ }
}
public void onFinishInputView() {
@@ -229,532 +164,157 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
mKeyboardView.setKeyboard(keyboard);
mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding);
- mCurrentId = keyboard.mId;
- mSwitchState = getSwitchState(mCurrentId);
- updateShiftLockState(keyboard);
mKeyboardView.setKeyPreviewPopupEnabled(
- Settings.Values.isKeyPreviewPopupEnabled(mPrefs, mResources),
- Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, mResources));
+ SettingsValues.isKeyPreviewPopupEnabled(mPrefs, mResources),
+ SettingsValues.getKeyPreviewPopupDismissDelay(mPrefs, mResources));
+ mKeyboardView.updateAutoCorrectionState(mIsAutoCorrectionActive);
+ // If the cached keyboard had been switched to another keyboard while the language was
+ // displayed on its spacebar, it might have had arbitrary text fade factor. In such
+ // case, we should reset the text fade factor. It is also applicable to shortcut key.
+ mKeyboardView.updateSpacebar(0.0f,
+ mSubtypeSwitcher.needsToDisplayLanguage(keyboard.mId.mLocale));
+ mKeyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
final boolean localeChanged = (oldKeyboard == null)
|| !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
- updateShiftState();
- }
-
- private int getSwitchState(KeyboardId id) {
- return id.equals(mMainKeyboardId) ? SWITCH_STATE_ALPHA : SWITCH_STATE_SYMBOL_BEGIN;
}
- private void updateShiftLockState(Keyboard keyboard) {
- if (mCurrentId.equals(mSymbolsShiftedKeyboardId)) {
- // Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a.
- // sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked()
- // that takes care of the current keyboard having such ALT key or not.
- keyboard.setShiftLocked(keyboard.hasShiftLockKey());
- } else if (mCurrentId.equals(mSymbolsKeyboardId)) {
- // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the
- // indicator, we need to call setShiftLocked(false).
- keyboard.setShiftLocked(false);
- }
- }
-
- private LatinKeyboard getKeyboard(KeyboardId id) {
- final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id);
- LatinKeyboard keyboard = (ref == null) ? null : ref.get();
- if (keyboard == null) {
- final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, id.mLocale);
- try {
- final LatinKeyboard.Builder builder = new LatinKeyboard.Builder(mThemeContext);
- builder.load(id);
- builder.setTouchPositionCorrectionEnabled(
- mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
- LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
- keyboard = builder.build();
- } finally {
- LocaleUtils.setSystemLocale(mResources, savedLocale);
- }
- mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
-
- if (DEBUG_CACHE) {
- Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
- + ((ref == null) ? "LOAD" : "GCed") + " id=" + id
- + " theme=" + Keyboard.themeName(keyboard.mThemeId));
- }
- } else if (DEBUG_CACHE) {
- Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id
- + " theme=" + Keyboard.themeName(keyboard.mThemeId));
- }
-
- keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive);
- keyboard.setShiftLocked(false);
- keyboard.setShifted(false);
- // If the cached keyboard had been switched to another keyboard while the language was
- // displayed on its spacebar, it might have had arbitrary text fade factor. In such case,
- // we should reset the text fade factor. It is also applicable to shortcut key.
- keyboard.setSpacebarTextFadeFactor(0.0f, null);
- keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady(), null);
- return keyboard;
- }
-
- private KeyboardId getKeyboardId(EditorInfo editorInfo, final boolean isSymbols,
- final boolean isShift, Settings.Values settingsValues) {
- final int mode = Utils.getKeyboardMode(editorInfo);
- final int xmlId;
- switch (mode) {
- case KeyboardId.MODE_PHONE:
- xmlId = (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone;
- break;
- case KeyboardId.MODE_NUMBER:
- xmlId = R.xml.kbd_number;
- break;
- default:
- if (isSymbols) {
- xmlId = isShift ? R.xml.kbd_symbols_shift : R.xml.kbd_symbols;
- } else {
- xmlId = R.xml.kbd_qwerty;
- }
- break;
- }
-
- final boolean settingsKeyEnabled = settingsValues.isSettingsKeyEnabled();
- @SuppressWarnings("deprecation")
- final boolean noMicrophone = Utils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo)
- || Utils.inPrivateImeOptions(
- null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo);
- final boolean voiceKeyEnabled = settingsValues.isVoiceKeyEnabled(editorInfo)
- && !noMicrophone;
- final boolean voiceKeyOnMain = settingsValues.isVoiceKeyOnMain();
- final boolean noSettingsKey = Utils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, editorInfo);
- final boolean hasSettingsKey = settingsKeyEnabled && !noSettingsKey;
- final int f2KeyMode = getF2KeyMode(settingsKeyEnabled, noSettingsKey);
- final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain);
- final boolean forceAscii = Utils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, editorInfo);
- final boolean asciiCapable = mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
- LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE);
- final Locale locale = (forceAscii && !asciiCapable)
- ? Locale.US : mSubtypeSwitcher.getInputLocale();
- final Configuration conf = mResources.getConfiguration();
- final DisplayMetrics dm = mResources.getDisplayMetrics();
-
- return new KeyboardId(
- mResources.getResourceEntryName(xmlId), xmlId, locale, conf.orientation,
- dm.widthPixels, mode, editorInfo, hasSettingsKey, f2KeyMode, noSettingsKey,
- voiceKeyEnabled, hasShortcutKey);
- }
-
- public int getKeyboardMode() {
- return mCurrentId != null ? mCurrentId.mMode : KeyboardId.MODE_TEXT;
- }
-
- public boolean isAlphabetMode() {
- return mCurrentId != null && mCurrentId.isAlphabetKeyboard();
- }
-
- public boolean isInputViewShown() {
- return mCurrentInputView != null && mCurrentInputView.isShown();
- }
-
- public boolean isKeyboardAvailable() {
- if (mKeyboardView != null)
- return mKeyboardView.getKeyboard() != null;
- return false;
- }
-
- public LatinKeyboard getLatinKeyboard() {
+ public Keyboard getKeyboard() {
if (mKeyboardView != null) {
- final Keyboard keyboard = mKeyboardView.getKeyboard();
- if (keyboard instanceof LatinKeyboard)
- return (LatinKeyboard)keyboard;
+ return mKeyboardView.getKeyboard();
}
return null;
}
- public boolean isShiftedOrShiftLocked() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- return latinKeyboard.isShiftedOrShiftLocked();
- return false;
- }
-
- public boolean isShiftLocked() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- return latinKeyboard.isShiftLocked();
- return false;
+ /**
+ * Update keyboard shift state triggered by connected EditText status change.
+ */
+ public void updateShiftState() {
+ mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
}
- private boolean isShiftLockShifted() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- return latinKeyboard.isShiftLockShifted();
- return false;
+ public void onPressKey(int code) {
+ if (isVibrateAndSoundFeedbackRequired()) {
+ mInputMethodService.hapticAndAudioFeedback(code);
+ }
+ mState.onPressKey(code);
}
- public boolean isAutomaticTemporaryUpperCase() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- return latinKeyboard.isAutomaticTemporaryUpperCase();
- return false;
+ public void onReleaseKey(int code, boolean withSliding) {
+ mState.onReleaseKey(code, withSliding);
}
- public boolean isManualTemporaryUpperCase() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- return latinKeyboard.isManualTemporaryUpperCase();
- return false;
+ public void onCancelInput() {
+ mState.onCancelInput(isSinglePointer());
}
- private boolean isManualTemporaryUpperCaseFromAuto() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- return latinKeyboard.isManualTemporaryUpperCaseFromAuto();
- return false;
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET));
}
- private void setManualTemporaryUpperCase(boolean shifted) {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null) {
- // On non-distinct multi touch panel device, we should also turn off the shift locked
- // state when shift key is pressed to go to normal mode.
- // On the other hand, on distinct multi touch panel device, turning off the shift locked
- // state with shift key pressing is handled by onReleaseShift().
- if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) {
- latinKeyboard.setShiftLocked(false);
- }
- if (latinKeyboard.setShifted(shifted)) {
- mKeyboardView.invalidateAllKeys();
- }
- }
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetManualShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED));
}
- private void setShiftLocked(boolean shiftLocked) {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null && latinKeyboard.setShiftLocked(shiftLocked)) {
- mKeyboardView.invalidateAllKeys();
- }
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetAutomaticShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED));
}
- /**
- * Toggle keyboard shift state triggered by user touch event.
- */
- public void toggleShift() {
- mInputMethodService.mHandler.cancelUpdateShiftState();
- if (DEBUG_STATE)
- Log.d(TAG, "toggleShift:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + mShiftKeyState);
- if (isAlphabetMode()) {
- setManualTemporaryUpperCase(!isShiftedOrShiftLocked());
- } else {
- toggleShiftInSymbol();
- }
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetShiftLockedKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED));
}
- public void toggleCapsLock() {
- mInputMethodService.mHandler.cancelUpdateShiftState();
- if (DEBUG_STATE)
- Log.d(TAG, "toggleCapsLock:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + mShiftKeyState);
- if (isAlphabetMode()) {
- if (isShiftLocked()) {
- // Shift key is long pressed while caps lock state, we will toggle back to normal
- // state. And mark as if shift key is released.
- setShiftLocked(false);
- mShiftKeyState.onRelease();
- } else {
- setShiftLocked(true);
- }
- }
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetShiftLockShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED));
}
- private void setAutomaticTemporaryUpperCase() {
- if (mKeyboardView == null) return;
- final Keyboard keyboard = mKeyboardView.getKeyboard();
- if (keyboard == null) return;
- keyboard.setAutomaticTemporaryUpperCase();
- mKeyboardView.invalidateAllKeys();
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setSymbolsKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS));
}
- /**
- * Update keyboard shift state triggered by connected EditText status change.
- */
- public void updateShiftState() {
- final ShiftKeyState shiftKeyState = mShiftKeyState;
- if (DEBUG_STATE)
- Log.d(TAG, "updateShiftState:"
- + " autoCaps=" + mInputMethodService.getCurrentAutoCapsState()
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + shiftKeyState
- + " isAlphabetMode=" + isAlphabetMode()
- + " isShiftLocked=" + isShiftLocked());
- if (isAlphabetMode()) {
- if (!isShiftLocked() && !shiftKeyState.isIgnoring()) {
- if (shiftKeyState.isReleasing() && mInputMethodService.getCurrentAutoCapsState()) {
- // Only when shift key is releasing, automatic temporary upper case will be set.
- setAutomaticTemporaryUpperCase();
- } else {
- setManualTemporaryUpperCase(shiftKeyState.isMomentary());
- }
- }
- } else {
- // In symbol keyboard mode, we should clear shift key state because only alphabet
- // keyboard has shift key.
- shiftKeyState.onRelease();
- }
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setSymbolsShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED));
}
- public void changeKeyboardMode() {
- if (DEBUG_STATE)
- Log.d(TAG, "changeKeyboardMode:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + mShiftKeyState);
- toggleKeyboardMode();
- if (isShiftLocked() && isAlphabetMode())
- setShiftLocked(true);
- updateShiftState();
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void requestUpdatingShiftState() {
+ mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
}
- public void onPressShift(boolean withSliding) {
- if (!isKeyboardAvailable())
- return;
- ShiftKeyState shiftKeyState = mShiftKeyState;
- if (DEBUG_STATE)
- Log.d(TAG, "onPressShift:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + shiftKeyState + " sliding=" + withSliding);
- if (isAlphabetMode()) {
- if (isShiftLocked()) {
- // Shift key is pressed while caps lock state, we will treat this state as shifted
- // caps lock state and mark as if shift key pressed while normal state.
- shiftKeyState.onPress();
- setManualTemporaryUpperCase(true);
- } else if (isAutomaticTemporaryUpperCase()) {
- // Shift key is pressed while automatic temporary upper case, we have to move to
- // manual temporary upper case.
- shiftKeyState.onPress();
- setManualTemporaryUpperCase(true);
- } else if (isShiftedOrShiftLocked()) {
- // In manual upper case state, we just record shift key has been pressing while
- // shifted state.
- shiftKeyState.onPressOnShifted();
- } else {
- // In base layout, chording or manual temporary upper case mode is started.
- shiftKeyState.onPress();
- toggleShift();
- }
- } else {
- // In symbol mode, just toggle symbol and symbol more keyboard.
- shiftKeyState.onPress();
- toggleShift();
- mSwitchState = SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void startDoubleTapTimer() {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ if (keyboardView != null) {
+ final TimerProxy timer = keyboardView.getTimerProxy();
+ timer.startDoubleTapTimer();
}
}
- public void onReleaseShift(boolean withSliding) {
- if (!isKeyboardAvailable())
- return;
- ShiftKeyState shiftKeyState = mShiftKeyState;
- if (DEBUG_STATE)
- Log.d(TAG, "onReleaseShift:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + shiftKeyState + " sliding=" + withSliding);
- if (isAlphabetMode()) {
- if (shiftKeyState.isMomentary()) {
- // After chording input while normal state.
- toggleShift();
- } else if (isShiftLocked() && !isShiftLockShifted() && shiftKeyState.isPressing()
- && !withSliding) {
- // Shift has been long pressed, ignore this release.
- } else if (isShiftLocked() && !shiftKeyState.isIgnoring() && !withSliding) {
- // Shift has been pressed without chording while caps lock state.
- toggleCapsLock();
- // To be able to turn off caps lock by "double tap" on shift key, we should ignore
- // the second tap of the "double tap" from now for a while because we just have
- // already turned off caps lock above.
- mKeyboardView.startIgnoringDoubleTap();
- } else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()
- && !withSliding) {
- // Shift has been pressed without chording while shifted state.
- toggleShift();
- } else if (isManualTemporaryUpperCaseFromAuto() && shiftKeyState.isPressing()
- && !withSliding) {
- // Shift has been pressed without chording while manual temporary upper case
- // transited from automatic temporary upper case.
- toggleShift();
- }
- } else {
- // In symbol mode, snap back to the previous keyboard mode if the user chords the shift
- // key and another key, then releases the shift key.
- if (mSwitchState == SWITCH_STATE_CHORDING_SYMBOL) {
- toggleShift();
- }
- }
- shiftKeyState.onRelease();
- }
-
- public void onPressSymbol() {
- if (DEBUG_STATE)
- Log.d(TAG, "onPressSymbol:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " symbolKeyState=" + mSymbolKeyState);
- changeKeyboardMode();
- mSymbolKeyState.onPress();
- mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
- }
-
- public void onReleaseSymbol() {
- if (DEBUG_STATE)
- Log.d(TAG, "onReleaseSymbol:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " symbolKeyState=" + mSymbolKeyState);
- // Snap back to the previous keyboard mode if the user chords the mode change key and
- // another key, then releases the mode change key.
- if (mSwitchState == SWITCH_STATE_CHORDING_ALPHA) {
- changeKeyboardMode();
- }
- mSymbolKeyState.onRelease();
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public boolean isInDoubleTapTimeout() {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ return (keyboardView != null)
+ ? keyboardView.getTimerProxy().isInDoubleTapTimeout() : false;
}
- public void onOtherKeyPressed() {
- if (DEBUG_STATE)
- Log.d(TAG, "onOtherKeyPressed:"
- + " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
- + " shiftKeyState=" + mShiftKeyState
- + " symbolKeyState=" + mSymbolKeyState);
- mShiftKeyState.onOtherKeyPressed();
- mSymbolKeyState.onOtherKeyPressed();
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void startLongPressTimer(int code) {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ if (keyboardView != null) {
+ final TimerProxy timer = keyboardView.getTimerProxy();
+ timer.startLongPressTimer(code);
+ }
}
- public void onCancelInput() {
- // Snap back to the previous keyboard mode if the user cancels sliding input.
- if (getPointerCount() == 1) {
- if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) {
- changeKeyboardMode();
- } else if (mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE) {
- toggleShift();
- }
- }
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void hapticAndAudioFeedback(int code) {
+ mInputMethodService.hapticAndAudioFeedback(code);
}
- private void toggleShiftInSymbol() {
- if (isAlphabetMode())
- return;
- final LatinKeyboard keyboard;
- if (mCurrentId.equals(mSymbolsKeyboardId)
- || !mCurrentId.equals(mSymbolsShiftedKeyboardId)) {
- keyboard = getKeyboard(mSymbolsShiftedKeyboardId);
- } else {
- keyboard = getKeyboard(mSymbolsKeyboardId);
- }
- setKeyboard(keyboard);
+ public void onLongPressTimeout(int code) {
+ mState.onLongPressTimeout(code);
}
public boolean isInMomentarySwitchState() {
- return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL
- || mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
+ return mState.isInMomentarySwitchState();
}
- public boolean isVibrateAndSoundFeedbackRequired() {
+ private boolean isVibrateAndSoundFeedbackRequired() {
return mKeyboardView != null && !mKeyboardView.isInSlidingKeyInput();
}
- private int getPointerCount() {
- return mKeyboardView == null ? 0 : mKeyboardView.getPointerCount();
- }
-
- private void toggleKeyboardMode() {
- if (mCurrentId.equals(mMainKeyboardId)) {
- setKeyboard(getKeyboard(mSymbolsKeyboardId));
- } else {
- setKeyboard(getKeyboard(mMainKeyboardId));
- }
+ private boolean isSinglePointer() {
+ return mKeyboardView != null && mKeyboardView.getPointerCount() == 1;
}
public boolean hasDistinctMultitouch() {
return mKeyboardView != null && mKeyboardView.hasDistinctMultitouch();
}
- private static boolean isSpaceCharacter(int c) {
- return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER;
- }
-
- private static boolean isLayoutSwitchBackCharacter(int c) {
- if (TextUtils.isEmpty(mLayoutSwitchBackSymbols)) return false;
- if (mLayoutSwitchBackSymbols.indexOf(c) >= 0) return true;
- return false;
- }
-
/**
- * Updates state machine to figure out when to automatically snap back to the previous mode.
+ * Updates state machine to figure out when to automatically switch back to the previous mode.
*/
- public void onKey(int code) {
- if (DEBUG_STATE)
- Log.d(TAG, "onKey: code=" + code + " switchState=" + mSwitchState
- + " pointers=" + getPointerCount());
- switch (mSwitchState) {
- case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
- // Only distinct multi touch devices can be in this state.
- // On non-distinct multi touch devices, mode change key is handled by
- // {@link LatinIME#onCodeInput}, not by {@link LatinIME#onPress} and
- // {@link LatinIME#onRelease}. So, on such devices, {@link #mSwitchState} starts
- // from {@link #SWITCH_STATE_SYMBOL_BEGIN}, or {@link #SWITCH_STATE_ALPHA}, not from
- // {@link #SWITCH_STATE_MOMENTARY}.
- if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
- // Detected only the mode change key has been pressed, and then released.
- if (mCurrentId.equals(mMainKeyboardId)) {
- mSwitchState = SWITCH_STATE_ALPHA;
- } else {
- mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
- }
- } else if (getPointerCount() == 1) {
- // Snap back to the previous keyboard mode if the user pressed the mode change key
- // and slid to other key, then released the finger.
- // If the user cancels the sliding input, snapping back to the previous keyboard
- // mode is handled by {@link #onCancelInput}.
- changeKeyboardMode();
- } else {
- // Chording input is being started. The keyboard mode will be snapped back to the
- // previous mode in {@link onReleaseSymbol} when the mode change key is released.
- mSwitchState = SWITCH_STATE_CHORDING_ALPHA;
- }
- break;
- case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
- if (code == Keyboard.CODE_SHIFT) {
- // Detected only the shift key has been pressed on symbol layout, and then released.
- mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
- } else if (getPointerCount() == 1) {
- // Snap back to the previous keyboard mode if the user pressed the shift key on
- // symbol mode and slid to other key, then released the finger.
- toggleShift();
- mSwitchState = SWITCH_STATE_SYMBOL;
- } else {
- // Chording input is being started. The keyboard mode will be snapped back to the
- // previous mode in {@link onReleaseShift} when the shift key is released.
- mSwitchState = SWITCH_STATE_CHORDING_SYMBOL;
- }
- break;
- case SWITCH_STATE_SYMBOL_BEGIN:
- if (!isSpaceCharacter(code) && code >= 0) {
- mSwitchState = SWITCH_STATE_SYMBOL;
- }
- // Snap back to alpha keyboard mode immediately if user types a quote character.
- if (isLayoutSwitchBackCharacter(code)) {
- changeKeyboardMode();
- }
- break;
- case SWITCH_STATE_SYMBOL:
- case SWITCH_STATE_CHORDING_SYMBOL:
- // Snap back to alpha keyboard mode if user types one or more non-space/enter
- // characters followed by a space/enter or a quote character.
- if (isSpaceCharacter(code) || isLayoutSwitchBackCharacter(code)) {
- changeKeyboardMode();
- }
- break;
- }
+ public void onCodeInput(int code) {
+ mState.onCodeInput(code, isSinglePointer(), mInputMethodService.getCurrentAutoCapsState());
}
public LatinKeyboardView getKeyboardView() {
@@ -795,6 +355,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
mKeyboardView.setKeyboardActionListener(mInputMethodService);
+ if (mForceNonDistinctMultitouch) {
+ mKeyboardView.setDistinctMultitouch(false);
+ }
// This always needs to be set since the accessibility state can
// potentially change without the input view being re-created.
@@ -804,13 +367,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
private void postSetInputView(final View newInputView) {
- mInputMethodService.mHandler.post(new Runnable() {
+ final LatinIME latinIme = mInputMethodService;
+ latinIme.mHandler.post(new Runnable() {
@Override
public void run() {
if (newInputView != null) {
- mInputMethodService.setInputView(newInputView);
+ latinIme.setInputView(newInputView);
}
- mInputMethodService.updateInputViewShown();
+ latinIme.updateInputViewShown();
}
});
}
@@ -825,31 +389,18 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
+ public void onNetworkStateChanged() {
+ if (mKeyboardView != null) {
+ mKeyboardView.updateShortcutKey(SubtypeSwitcher.getInstance().isShortcutImeReady());
+ }
+ }
+
public void onAutoCorrectionStateChanged(boolean isAutoCorrection) {
if (mIsAutoCorrectionActive != isAutoCorrection) {
mIsAutoCorrectionActive = isAutoCorrection;
- final LatinKeyboard keyboard = getLatinKeyboard();
- if (keyboard != null && keyboard.needsAutoCorrectionSpacebarLed()) {
- final Key invalidatedKey = keyboard.onAutoCorrectionStateChanged(isAutoCorrection);
- final LatinKeyboardView keyboardView = getKeyboardView();
- if (keyboardView != null)
- keyboardView.invalidateKey(invalidatedKey);
+ if (mKeyboardView != null) {
+ mKeyboardView.updateAutoCorrectionState(isAutoCorrection);
}
}
}
-
- private static int getF2KeyMode(boolean settingsKeyEnabled, boolean noSettingsKey) {
- if (noSettingsKey) {
- // Never shows the Settings key
- return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
- }
-
- if (settingsKeyEnabled) {
- return KeyboardId.F2KEY_MODE_SETTINGS;
- } else {
- // It should be alright to fall back to the Settings key on 7-inch layouts
- // even when the Settings key is not explicitly enabled.
- return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
- }
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 04e672590..d65253ede 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.keyboard;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -42,6 +41,7 @@ import com.android.inputmethod.compat.FrameLayoutCompatUtils;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.Utils;
import java.util.HashMap;
@@ -54,12 +54,12 @@ import java.util.HashMap;
* @attr ref R.styleable#KeyboardView_keyLargeLetterRatio
* @attr ref R.styleable#KeyboardView_keyLabelRatio
* @attr ref R.styleable#KeyboardView_keyHintLetterRatio
- * @attr ref R.styleable#KeyboardView_keyUppercaseLetterRatio
+ * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintRatio
* @attr ref R.styleable#KeyboardView_keyHintLabelRatio
* @attr ref R.styleable#KeyboardView_keyLabelHorizontalPadding
* @attr ref R.styleable#KeyboardView_keyHintLetterPadding
* @attr ref R.styleable#KeyboardView_keyPopupHintLetterPadding
- * @attr ref R.styleable#KeyboardView_keyUppercaseLetterPadding
+ * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintPadding
* @attr ref R.styleable#KeyboardView_keyTextStyle
* @attr ref R.styleable#KeyboardView_keyPreviewLayout
* @attr ref R.styleable#KeyboardView_keyPreviewTextRatio
@@ -69,8 +69,8 @@ import java.util.HashMap;
* @attr ref R.styleable#KeyboardView_keyTextColorDisabled
* @attr ref R.styleable#KeyboardView_keyHintLetterColor
* @attr ref R.styleable#KeyboardView_keyHintLabelColor
- * @attr ref R.styleable#KeyboardView_keyUppercaseLetterInactivatedColor
- * @attr ref R.styleable#KeyboardView_keyUppercaseLetterActivatedColor
+ * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintInactivatedColor
+ * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintActivatedColor
* @attr ref R.styleable#KeyboardView_shadowColor
* @attr ref R.styleable#KeyboardView_shadowRadius
*/
@@ -102,7 +102,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final int mKeyPreviewLayoutId;
protected final KeyPreviewDrawParams mKeyPreviewDrawParams;
private boolean mShowKeyPreviewPopup = true;
- private final int mDelayBeforePreview;
private int mDelayAfterPreview;
private ViewGroup mPreviewPlacer;
@@ -134,8 +133,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final DrawingHandler mDrawingHandler = new DrawingHandler(this);
public static class DrawingHandler extends StaticInnerHandlerWrapper<KeyboardView> {
- private static final int MSG_SHOW_KEY_PREVIEW = 1;
- private static final int MSG_DISMISS_KEY_PREVIEW = 2;
+ private static final int MSG_DISMISS_KEY_PREVIEW = 1;
public DrawingHandler(KeyboardView outerInstance) {
super(outerInstance);
@@ -147,36 +145,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (keyboardView == null) return;
final PointerTracker tracker = (PointerTracker) msg.obj;
switch (msg.what) {
- case MSG_SHOW_KEY_PREVIEW:
- keyboardView.showKey(msg.arg1, tracker);
- break;
case MSG_DISMISS_KEY_PREVIEW:
tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
break;
}
}
- public void showKeyPreview(long delay, int keyIndex, PointerTracker tracker) {
- removeMessages(MSG_SHOW_KEY_PREVIEW);
- final KeyboardView keyboardView = getOuterInstance();
- if (keyboardView == null) return;
- if (tracker.getKeyPreviewText().getVisibility() == VISIBLE || delay == 0) {
- // Show right away, if it's already visible and finger is moving around
- keyboardView.showKey(keyIndex, tracker);
- } else {
- sendMessageDelayed(
- obtainMessage(MSG_SHOW_KEY_PREVIEW, keyIndex, 0, tracker), delay);
- }
- }
-
- public void cancelShowKeyPreview(PointerTracker tracker) {
- removeMessages(MSG_SHOW_KEY_PREVIEW, tracker);
- }
-
- public void cancelAllShowKeyPreviews() {
- removeMessages(MSG_SHOW_KEY_PREVIEW);
- }
-
public void dismissKeyPreview(long delay, PointerTracker tracker) {
sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay);
}
@@ -190,12 +164,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
public void cancelAllMessages() {
- cancelAllShowKeyPreviews();
cancelAllDismissKeyPreviews();
}
}
- private static class KeyDrawParams {
+ /* package */ static class KeyDrawParams {
// XML attributes
public final int mKeyTextColor;
public final int mKeyTextInactivatedColor;
@@ -203,20 +176,20 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public final float mKeyLabelHorizontalPadding;
public final float mKeyHintLetterPadding;
public final float mKeyPopupHintLetterPadding;
- public final float mKeyUppercaseLetterPadding;
+ public final float mKeyShiftedLetterHintPadding;
public final int mShadowColor;
public final float mShadowRadius;
public final Drawable mKeyBackground;
public final int mKeyHintLetterColor;
public final int mKeyHintLabelColor;
- public final int mKeyUppercaseLetterInactivatedColor;
- public final int mKeyUppercaseLetterActivatedColor;
+ public final int mKeyShiftedLetterHintInactivatedColor;
+ public final int mKeyShiftedLetterHintActivatedColor;
- private final float mKeyLetterRatio;
+ /* package */ final float mKeyLetterRatio;
private final float mKeyLargeLetterRatio;
private final float mKeyLabelRatio;
private final float mKeyHintLetterRatio;
- private final float mKeyUppercaseLetterRatio;
+ private final float mKeyShiftedLetterHintRatio;
private final float mKeyHintLabelRatio;
private static final float UNDEFINED_RATIO = -1.0f;
@@ -225,7 +198,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public int mKeyLargeLetterSize;
public int mKeyLabelSize;
public int mKeyHintLetterSize;
- public int mKeyUppercaseLetterSize;
+ public int mKeyShiftedLetterHintSize;
public int mKeyHintLabelSize;
public KeyDrawParams(TypedArray a) {
@@ -244,8 +217,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
mKeyLargeLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLargeLetterRatio);
mKeyHintLetterRatio = getRatio(a, R.styleable.KeyboardView_keyHintLetterRatio);
- mKeyUppercaseLetterRatio = getRatio(a,
- R.styleable.KeyboardView_keyUppercaseLetterRatio);
+ mKeyShiftedLetterHintRatio = getRatio(a,
+ R.styleable.KeyboardView_keyShiftedLetterHintRatio);
mKeyHintLabelRatio = getRatio(a, R.styleable.KeyboardView_keyHintLabelRatio);
mKeyLabelHorizontalPadding = a.getDimension(
R.styleable.KeyboardView_keyLabelHorizontalPadding, 0);
@@ -253,17 +226,17 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
R.styleable.KeyboardView_keyHintLetterPadding, 0);
mKeyPopupHintLetterPadding = a.getDimension(
R.styleable.KeyboardView_keyPopupHintLetterPadding, 0);
- mKeyUppercaseLetterPadding = a.getDimension(
- R.styleable.KeyboardView_keyUppercaseLetterPadding, 0);
+ mKeyShiftedLetterHintPadding = a.getDimension(
+ R.styleable.KeyboardView_keyShiftedLetterHintPadding, 0);
mKeyTextColor = a.getColor(R.styleable.KeyboardView_keyTextColor, 0xFF000000);
mKeyTextInactivatedColor = a.getColor(
R.styleable.KeyboardView_keyTextInactivatedColor, 0xFF000000);
mKeyHintLetterColor = a.getColor(R.styleable.KeyboardView_keyHintLetterColor, 0);
mKeyHintLabelColor = a.getColor(R.styleable.KeyboardView_keyHintLabelColor, 0);
- mKeyUppercaseLetterInactivatedColor = a.getColor(
- R.styleable.KeyboardView_keyUppercaseLetterInactivatedColor, 0);
- mKeyUppercaseLetterActivatedColor = a.getColor(
- R.styleable.KeyboardView_keyUppercaseLetterActivatedColor, 0);
+ mKeyShiftedLetterHintInactivatedColor = a.getColor(
+ R.styleable.KeyboardView_keyShiftedLetterHintInactivatedColor, 0);
+ mKeyShiftedLetterHintActivatedColor = a.getColor(
+ R.styleable.KeyboardView_keyShiftedLetterHintActivatedColor, 0);
mKeyTextStyle = Typeface.defaultFromStyle(
a.getInt(R.styleable.KeyboardView_keyTextStyle, Typeface.NORMAL));
mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
@@ -279,12 +252,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio);
mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio);
mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio);
- mKeyUppercaseLetterSize = (int)(keyHeight * mKeyUppercaseLetterRatio);
+ mKeyShiftedLetterHintSize = (int)(keyHeight * mKeyShiftedLetterHintRatio);
mKeyHintLabelSize = (int)(keyHeight * mKeyHintLabelRatio);
}
}
- protected static class KeyPreviewDrawParams {
+ /* package */ static class KeyPreviewDrawParams {
// XML attributes.
public final Drawable mPreviewBackground;
public final Drawable mPreviewLeftBackground;
@@ -295,6 +268,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public final int mPreviewOffset;
public final int mPreviewHeight;
public final Typeface mKeyTextStyle;
+ public final int mLingerTimeout;
private final float mPreviewTextRatio;
private final float mKeyLetterRatio;
@@ -324,6 +298,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
R.styleable.KeyboardView_keyPreviewHeight, 80);
mPreviewTextRatio = getRatio(a, R.styleable.KeyboardView_keyPreviewTextRatio);
mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
+ mLingerTimeout = a.getInt(R.styleable.KeyboardView_keyPreviewLingerTimeout, 0);
mKeyLetterRatio = keyDrawParams.mKeyLetterRatio;
mKeyTextStyle = keyDrawParams.mKeyTextStyle;
@@ -363,10 +338,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
a.recycle();
- final Resources res = getResources();
-
- mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
- mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
+ mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
mPaint.setAntiAlias(true);
mPaint.setTextAlign(Align.CENTER);
@@ -374,7 +346,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
// Read fraction value in TypedArray as float.
- private static float getRatio(TypedArray a, int index) {
+ /* package */ static float getRatio(TypedArray a, int index) {
return a.getFraction(index, 1000, 1000, 1) / 1000.0f;
}
@@ -386,8 +358,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
* @param keyboard the keyboard to display in this view
*/
public void setKeyboard(Keyboard keyboard) {
- // Remove any pending dismissing preview
- mDrawingHandler.cancelAllShowKeyPreviews();
+ // Remove any pending messages.
+ mDrawingHandler.cancelAllMessages();
if (mKeyboard != null) {
PointerTracker.dismissAllKeyPreviews();
}
@@ -475,7 +447,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (mKeyboard == null) return;
- final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
final KeyDrawParams params = mKeyDrawParams;
if (mInvalidatedKey != null && mInvalidatedKeyRect.contains(mDirtyRect)) {
// Draw a single key.
@@ -483,8 +454,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
+ getPaddingLeft();
final int keyDrawY = mInvalidatedKey.mY + getPaddingTop();
canvas.translate(keyDrawX, keyDrawY);
- onBufferDrawKey(mInvalidatedKey, mKeyboard, canvas, mPaint, params,
- isManualTemporaryUpperCase);
+ onDrawKey(mInvalidatedKey, canvas, mPaint, params);
canvas.translate(-keyDrawX, -keyDrawY);
} else {
// Draw all keys.
@@ -492,7 +462,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
final int keyDrawX = key.mX + key.mVisualInsetsLeft + getPaddingLeft();
final int keyDrawY = key.mY + getPaddingTop();
canvas.translate(keyDrawX, keyDrawY);
- onBufferDrawKey(key, mKeyboard, canvas, mPaint, params, isManualTemporaryUpperCase);
+ onDrawKey(key, canvas, mPaint, params);
canvas.translate(-keyDrawX, -keyDrawY);
}
}
@@ -515,47 +485,51 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- private static void onBufferDrawKey(final Key key, final Keyboard keyboard, final Canvas canvas,
- Paint paint, KeyDrawParams params, boolean isManualTemporaryUpperCase) {
- final boolean debugShowAlign = LatinImeLogger.sVISUALDEBUG;
- // Draw key background.
+ private void onDrawKey(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
if (!key.isSpacer()) {
- final int bgWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight
- + params.mPadding.left + params.mPadding.right;
- final int bgHeight = key.mHeight + params.mPadding.top + params.mPadding.bottom;
- final int bgX = -params.mPadding.left;
- final int bgY = -params.mPadding.top;
- final int[] drawableState = key.getCurrentDrawableState();
- final Drawable background = params.mKeyBackground;
- background.setState(drawableState);
- final Rect bounds = background.getBounds();
- if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
- background.setBounds(0, 0, bgWidth, bgHeight);
- }
- canvas.translate(bgX, bgY);
- background.draw(canvas);
- if (debugShowAlign) {
- drawRectangle(canvas, 0, 0, bgWidth, bgHeight, 0x80c00000, new Paint());
- }
- canvas.translate(-bgX, -bgY);
+ onDrawKeyBackground(key, canvas, params);
}
+ onDrawKeyTopVisuals(key, canvas, paint, params);
+ }
+
+ // Draw key background.
+ protected void onDrawKeyBackground(Key key, Canvas canvas, KeyDrawParams params) {
+ final int bgWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight
+ + params.mPadding.left + params.mPadding.right;
+ final int bgHeight = key.mHeight + params.mPadding.top + params.mPadding.bottom;
+ final int bgX = -params.mPadding.left;
+ final int bgY = -params.mPadding.top;
+ final int[] drawableState = key.getCurrentDrawableState();
+ final Drawable background = params.mKeyBackground;
+ background.setState(drawableState);
+ final Rect bounds = background.getBounds();
+ if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
+ background.setBounds(0, 0, bgWidth, bgHeight);
+ }
+ canvas.translate(bgX, bgY);
+ background.draw(canvas);
+ if (LatinImeLogger.sVISUALDEBUG) {
+ drawRectangle(canvas, 0, 0, bgWidth, bgHeight, 0x80c00000, new Paint());
+ }
+ canvas.translate(-bgX, -bgY);
+ }
- // Draw key top visuals.
+ // Draw key top visuals.
+ protected void onDrawKeyTopVisuals(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
final int keyWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
final int keyHeight = key.mHeight;
final float centerX = keyWidth * 0.5f;
final float centerY = keyHeight * 0.5f;
- if (debugShowAlign) {
+ if (LatinImeLogger.sVISUALDEBUG) {
drawRectangle(canvas, 0, 0, keyWidth, keyHeight, 0x800000c0, new Paint());
}
// Draw key label.
- final Drawable icon = key.getIcon();
+ final Drawable icon = key.getIcon(mKeyboard.mIconsSet);
float positionX = centerX;
if (key.mLabel != null) {
- // Switch the character to uppercase if shift is pressed
- final CharSequence label = keyboard.adjustLabelCase(key.mLabel);
+ final String label = key.mLabel;
// For characters, use large font. For labels like "Done", use smaller font.
paint.setTypeface(key.selectTypeface(params.mKeyTextStyle));
final int labelSize = key.selectTextSize(params.mKeyLetterSize,
@@ -598,11 +572,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
Math.min(1.0f, (keyWidth * MAX_LABEL_RATIO) / getLabelWidth(label, paint)));
}
- if (key.hasUppercaseLetter() && isManualTemporaryUpperCase) {
- paint.setColor(params.mKeyTextInactivatedColor);
- } else {
- paint.setColor(params.mKeyTextColor);
- }
+ paint.setColor(key.isShiftedLetterActivated()
+ ? params.mKeyTextInactivatedColor : params.mKeyTextColor);
if (key.isEnabled()) {
// Set a drop shadow for the text
paint.setShadowLayer(params.mShadowRadius, 0, 0, params.mShadowColor);
@@ -628,7 +599,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- if (debugShowAlign) {
+ if (LatinImeLogger.sVISUALDEBUG) {
final Paint line = new Paint();
drawHorizontalLine(canvas, baseline, keyWidth, 0xc0008000, line);
drawVerticalLine(canvas, positionX, keyHeight, 0xc0800080, line);
@@ -637,18 +608,18 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// Draw hint label.
if (key.mHintLabel != null) {
- final CharSequence hint = key.mHintLabel;
+ final String hint = key.mHintLabel;
final int hintColor;
final int hintSize;
if (key.hasHintLabel()) {
hintColor = params.mKeyHintLabelColor;
hintSize = params.mKeyHintLabelSize;
paint.setTypeface(Typeface.DEFAULT);
- } else if (key.hasUppercaseLetter()) {
- hintColor = isManualTemporaryUpperCase
- ? params.mKeyUppercaseLetterActivatedColor
- : params.mKeyUppercaseLetterInactivatedColor;
- hintSize = params.mKeyUppercaseLetterSize;
+ } else if (key.hasShiftedLetterHint()) {
+ hintColor = key.isShiftedLetterActivated()
+ ? params.mKeyShiftedLetterHintActivatedColor
+ : params.mKeyShiftedLetterHintInactivatedColor;
+ hintSize = params.mKeyShiftedLetterHintSize;
} else { // key.hasHintLetter()
hintColor = params.mKeyHintLetterColor;
hintSize = params.mKeyHintLetterSize;
@@ -663,9 +634,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
hintX = positionX + getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint) * 2;
hintY = centerY + getCharHeight(KEY_LABEL_REFERENCE_CHAR, paint) / 2;
paint.setTextAlign(Align.LEFT);
- } else if (key.hasUppercaseLetter()) {
+ } else if (key.hasShiftedLetterHint()) {
// The hint label is placed at top-right corner of the key. Used mainly on tablet.
- hintX = keyWidth - params.mKeyUppercaseLetterPadding
+ hintX = keyWidth - params.mKeyShiftedLetterHintPadding
- getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint) / 2;
hintY = -paint.ascent();
paint.setTextAlign(Align.CENTER);
@@ -678,7 +649,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
canvas.drawText(hint, 0, hint.length(), hintX, hintY, paint);
- if (debugShowAlign) {
+ if (LatinImeLogger.sVISUALDEBUG) {
final Paint line = new Paint();
drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
@@ -703,33 +674,37 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
- if (debugShowAlign) {
+ if (LatinImeLogger.sVISUALDEBUG) {
final Paint line = new Paint();
drawVerticalLine(canvas, alignX, keyHeight, 0xc0800080, line);
drawRectangle(canvas, iconX, iconY, iconWidth, iconHeight, 0x80c00000, line);
}
}
- // Draw popup hint "..." at the bottom right corner of the key.
- if ((key.hasPopupHint() && key.mMoreKeys != null && key.mMoreKeys.length > 0)
- || key.needsSpecialPopupHint()) {
- paint.setTextSize(params.mKeyHintLetterSize);
- paint.setColor(params.mKeyHintLabelColor);
- paint.setTextAlign(Align.CENTER);
- final float hintX = keyWidth - params.mKeyHintLetterPadding
- - getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint) / 2;
- final float hintY = keyHeight - params.mKeyPopupHintLetterPadding;
- canvas.drawText(POPUP_HINT_CHAR, hintX, hintY, paint);
-
- if (debugShowAlign) {
- final Paint line = new Paint();
- drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
- drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
- }
+ if (key.hasPopupHint() && key.mMoreKeys != null && key.mMoreKeys.length > 0) {
+ drawKeyPopupHint(key, canvas, paint, params);
}
}
- private static final Rect sTextBounds = new Rect();
+ // Draw popup hint "..." at the bottom right corner of the key.
+ protected void drawKeyPopupHint(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
+ final int keyWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
+ final int keyHeight = key.mHeight;
+
+ paint.setTextSize(params.mKeyHintLetterSize);
+ paint.setColor(params.mKeyHintLabelColor);
+ paint.setTextAlign(Align.CENTER);
+ final float hintX = keyWidth - params.mKeyHintLetterPadding
+ - getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint) / 2;
+ final float hintY = keyHeight - params.mKeyPopupHintLetterPadding;
+ canvas.drawText(POPUP_HINT_CHAR, hintX, hintY, paint);
+
+ if (LatinImeLogger.sVISUALDEBUG) {
+ final Paint line = new Paint();
+ drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
+ drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
+ }
+ }
private static int getCharGeometryCacheKey(char reference, Paint paint) {
final int labelSize = (int)paint.getTextSize();
@@ -746,42 +721,45 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- private static float getCharHeight(char[] character, Paint paint) {
+ // Working variable for the following methods.
+ private final Rect mTextBounds = new Rect();
+
+ private float getCharHeight(char[] character, Paint paint) {
final Integer key = getCharGeometryCacheKey(character[0], paint);
final Float cachedValue = sTextHeightCache.get(key);
if (cachedValue != null)
return cachedValue;
- paint.getTextBounds(character, 0, 1, sTextBounds);
- final float height = sTextBounds.height();
+ paint.getTextBounds(character, 0, 1, mTextBounds);
+ final float height = mTextBounds.height();
sTextHeightCache.put(key, height);
return height;
}
- private static float getCharWidth(char[] character, Paint paint) {
+ private float getCharWidth(char[] character, Paint paint) {
final Integer key = getCharGeometryCacheKey(character[0], paint);
final Float cachedValue = sTextWidthCache.get(key);
if (cachedValue != null)
return cachedValue;
- paint.getTextBounds(character, 0, 1, sTextBounds);
- final float width = sTextBounds.width();
+ paint.getTextBounds(character, 0, 1, mTextBounds);
+ final float width = mTextBounds.width();
sTextWidthCache.put(key, width);
return width;
}
- private static float getLabelWidth(CharSequence label, Paint paint) {
- paint.getTextBounds(label.toString(), 0, label.length(), sTextBounds);
- return sTextBounds.width();
+ protected float getLabelWidth(CharSequence label, Paint paint) {
+ paint.getTextBounds(label.toString(), 0, label.length(), mTextBounds);
+ return mTextBounds.width();
}
- public float getDefaultLabelWidth(CharSequence label, Paint paint) {
+ public float getDefaultLabelWidth(String label, Paint paint) {
paint.setTextSize(mKeyDrawParams.mKeyLabelSize);
paint.setTypeface(mKeyDrawParams.mKeyTextStyle);
return getLabelWidth(label, paint);
}
- private static void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width,
+ protected static void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width,
int height) {
canvas.translate(x, y);
icon.setBounds(0, 0, width, height);
@@ -830,20 +808,14 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
@Override
- public void showKeyPreview(int keyIndex, PointerTracker tracker) {
+ public void showKeyPreview(PointerTracker tracker) {
if (mShowKeyPreviewPopup) {
- mDrawingHandler.showKeyPreview(mDelayBeforePreview, keyIndex, tracker);
+ showKey(tracker);
}
}
@Override
- public void cancelShowKeyPreview(PointerTracker tracker) {
- mDrawingHandler.cancelShowKeyPreview(tracker);
- }
-
- @Override
public void dismissKeyPreview(PointerTracker tracker) {
- mDrawingHandler.cancelShowKeyPreview(tracker);
mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
}
@@ -858,7 +830,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
keyPreview, FrameLayoutCompatUtils.newLayoutParam(mPreviewPlacer, 0, 0));
}
- private void showKey(final int keyIndex, PointerTracker tracker) {
+ private void showKey(PointerTracker tracker) {
final TextView previewText = tracker.getKeyPreviewText();
// If the key preview has no parent view yet, add it to the ViewGroup which can place
// key preview absolutely in SoftInputWindow.
@@ -867,8 +839,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
mDrawingHandler.cancelDismissKeyPreview(tracker);
- final Key key = tracker.getKey(keyIndex);
- // If keyIndex is invalid or IME is already closed, we must not show key preview.
+ final Key key = tracker.getKey();
+ // If key is invalid or IME is already closed, we must not show key preview.
// Trying to show key preview while root window is closed causes
// WindowManager.BadTokenException.
if (key == null)
@@ -881,18 +853,17 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (key.mLabel != null) {
// TODO Should take care of temporaryShiftLabel here.
previewText.setCompoundDrawables(null, null, null, null);
- if (key.mLabel.length() > 1) {
+ if (Utils.codePointCount(key.mLabel) > 1) {
previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mKeyLetterSize);
previewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mPreviewTextSize);
previewText.setTypeface(params.mKeyTextStyle);
}
- previewText.setText(mKeyboard.adjustLabelCase(key.mLabel));
+ previewText.setText(key.mLabel);
} else {
- final Drawable previewIcon = key.getPreviewIcon();
previewText.setCompoundDrawables(null, null, null,
- previewIcon != null ? previewIcon : key.getIcon());
+ key.getPreviewIcon(mKeyboard.mIconsSet));
previewText.setText(null);
}
previewText.setBackgroundDrawable(params.mPreviewBackground);
@@ -906,12 +877,16 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + params.mCoordinates[0];
final int previewY = key.mY - previewHeight
+ params.mCoordinates[1] + params.mPreviewOffset;
- if (previewX < 0 && params.mPreviewLeftBackground != null) {
- previewText.setBackgroundDrawable(params.mPreviewLeftBackground);
+ if (previewX < 0) {
previewX = 0;
- } else if (previewX + previewWidth > getWidth() && params.mPreviewRightBackground != null) {
- previewText.setBackgroundDrawable(params.mPreviewRightBackground);
+ if (params.mPreviewLeftBackground != null) {
+ previewText.setBackgroundDrawable(params.mPreviewLeftBackground);
+ }
+ } else if (previewX > getWidth() - previewWidth) {
previewX = getWidth() - previewWidth;
+ if (params.mPreviewRightBackground != null) {
+ previewText.setBackgroundDrawable(params.mPreviewRightBackground);
+ }
}
// Set the preview background state
@@ -932,6 +907,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public void invalidateAllKeys() {
mDirtyRect.union(0, 0, getWidth(), getHeight());
mBufferNeedsUpdate = true;
+ mInvalidatedKey = null;
invalidate();
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
deleted file mode 100644
index 762039625..000000000
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-
-import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.KeyboardParams;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.Utils;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Locale;
-
-// TODO: We should remove this class
-public class LatinKeyboard extends Keyboard {
- private static final int SPACE_LED_LENGTH_PERCENT = 80;
-
- private final Resources mRes;
- private final Theme mTheme;
- private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance();
-
- /* Space key and its icons, drawables and colors. */
- private final Key mSpaceKey;
- private final Drawable mSpaceIcon;
- private final boolean mAutoCorrectionSpacebarLedEnabled;
- private final Drawable mAutoCorrectionSpacebarLedIcon;
- private final int mSpacebarTextColor;
- private final int mSpacebarTextShadowColor;
- private float mSpacebarTextFadeFactor = 0.0f;
- private final HashMap<Integer, BitmapDrawable> mSpaceDrawableCache =
- new HashMap<Integer, BitmapDrawable>();
- private final boolean mIsSpacebarTriggeringPopupByLongPress;
-
- /* Shortcut key and its icons if available */
- private final Key mShortcutKey;
- private final Drawable mEnabledShortcutIcon;
- private final Drawable mDisabledShortcutIcon;
-
- // Height in space key the language name will be drawn. (proportional to space key height)
- public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
- // If the full language name needs to be smaller than this value to be drawn on space key,
- // its short language name will be used instead.
- private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f;
-
- private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small";
- private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium";
-
- private LatinKeyboard(Context context, LatinKeyboardParams params) {
- super(params);
- mRes = context.getResources();
- mTheme = context.getTheme();
-
- // The index of space key is available only after Keyboard constructor has finished.
- mSpaceKey = params.mSpaceKey;
- mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null;
-
- mShortcutKey = params.mShortcutKey;
- mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null;
- final int longPressSpaceKeyTimeout =
- mRes.getInteger(R.integer.config_long_press_space_key_timeout);
- mIsSpacebarTriggeringPopupByLongPress = (longPressSpaceKeyTimeout > 0);
-
- final TypedArray a = context.obtainStyledAttributes(
- null, R.styleable.LatinKeyboard, R.attr.latinKeyboardStyle, R.style.LatinKeyboard);
- mAutoCorrectionSpacebarLedEnabled = a.getBoolean(
- R.styleable.LatinKeyboard_autoCorrectionSpacebarLedEnabled, false);
- mAutoCorrectionSpacebarLedIcon = a.getDrawable(
- R.styleable.LatinKeyboard_autoCorrectionSpacebarLedIcon);
- mDisabledShortcutIcon = a.getDrawable(R.styleable.LatinKeyboard_disabledShortcutIcon);
- mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboard_spacebarTextColor, 0);
- mSpacebarTextShadowColor = a.getColor(
- R.styleable.LatinKeyboard_spacebarTextShadowColor, 0);
- a.recycle();
- }
-
- private static class LatinKeyboardParams extends KeyboardParams {
- public Key mSpaceKey = null;
- public Key mShortcutKey = null;
-
- @Override
- public void onAddKey(Key key) {
- super.onAddKey(key);
-
- switch (key.mCode) {
- case Keyboard.CODE_SPACE:
- mSpaceKey = key;
- break;
- case Keyboard.CODE_SHORTCUT:
- mShortcutKey = key;
- break;
- }
- }
- }
-
- public static class Builder extends KeyboardBuilder<LatinKeyboardParams> {
- public Builder(Context context) {
- super(context, new LatinKeyboardParams());
- }
-
- @Override
- public Builder load(KeyboardId id) {
- super.load(id);
- return this;
- }
-
- @Override
- public LatinKeyboard build() {
- return new LatinKeyboard(mContext, mParams);
- }
- }
-
- public void setSpacebarTextFadeFactor(float fadeFactor, KeyboardView view) {
- mSpacebarTextFadeFactor = fadeFactor;
- updateSpacebarForLocale(false);
- if (view != null)
- view.invalidateKey(mSpaceKey);
- }
-
- private static int getSpacebarTextColor(int color, float fadeFactor) {
- final int newColor = Color.argb((int)(Color.alpha(color) * fadeFactor),
- Color.red(color), Color.green(color), Color.blue(color));
- return newColor;
- }
-
- public void updateShortcutKey(boolean available, KeyboardView view) {
- if (mShortcutKey == null)
- return;
- mShortcutKey.setEnabled(available);
- mShortcutKey.setIcon(available ? mEnabledShortcutIcon : mDisabledShortcutIcon);
- if (view != null)
- view.invalidateKey(mShortcutKey);
- }
-
- public boolean needsAutoCorrectionSpacebarLed() {
- return mAutoCorrectionSpacebarLedEnabled;
- }
-
- /**
- * @return a key which should be invalidated.
- */
- public Key onAutoCorrectionStateChanged(boolean isAutoCorrection) {
- updateSpacebarForLocale(isAutoCorrection);
- return mSpaceKey;
- }
-
- @Override
- public CharSequence adjustLabelCase(CharSequence label) {
- if (isAlphaKeyboard() && isShiftedOrShiftLocked() && !TextUtils.isEmpty(label)
- && label.length() < 3 && Character.isLowerCase(label.charAt(0))) {
- return label.toString().toUpperCase(mId.mLocale);
- }
- return label;
- }
-
- private void updateSpacebarForLocale(boolean isAutoCorrection) {
- if (mSpaceKey == null) return;
- final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
- if (imm == null) return;
- // The "..." popup hint for triggering something by a long-pressing the spacebar
- final boolean shouldShowInputMethodPicker = mIsSpacebarTriggeringPopupByLongPress
- && Utils.hasMultipleEnabledIMEsOrSubtypes(imm, true /* include aux subtypes */);
- mSpaceKey.setNeedsSpecialPopupHint(shouldShowInputMethodPicker);
- // If application locales are explicitly selected.
- if (mSubtypeSwitcher.needsToDisplayLanguage(mId.mLocale)) {
- mSpaceKey.setIcon(getSpaceDrawable(mId.mLocale, isAutoCorrection));
- } else if (isAutoCorrection) {
- mSpaceKey.setIcon(getSpaceDrawable(null, true));
- } else {
- mSpaceKey.setIcon(mSpaceIcon);
- }
- }
-
- // Compute width of text with specified text size using paint.
- private static int getTextWidth(Paint paint, String text, float textSize, Rect bounds) {
- paint.setTextSize(textSize);
- paint.getTextBounds(text, 0, text.length(), bounds);
- return bounds.width();
- }
-
- // Layout local language name and left and right arrow on spacebar.
- private static String layoutSpacebar(Paint paint, Locale locale, int width,
- float origTextSize) {
- final Rect bounds = new Rect();
-
- // Estimate appropriate language name text size to fit in maxTextWidth.
- String language = Utils.getFullDisplayName(locale, true);
- int textWidth = getTextWidth(paint, language, origTextSize, bounds);
- // Assuming text width and text size are proportional to each other.
- float textSize = origTextSize * Math.min(width / textWidth, 1.0f);
- // allow variable text size
- textWidth = getTextWidth(paint, language, textSize, bounds);
- // If text size goes too small or text does not fit, use middle or short name
- final boolean useMiddleName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME)
- || (textWidth > width);
-
- final boolean useShortName;
- if (useMiddleName) {
- language = Utils.getMiddleDisplayLanguage(locale);
- textWidth = getTextWidth(paint, language, origTextSize, bounds);
- textSize = origTextSize * Math.min(width / textWidth, 1.0f);
- useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME)
- || (textWidth > width);
- } else {
- useShortName = false;
- }
-
- if (useShortName) {
- language = Utils.getShortDisplayLanguage(locale);
- textWidth = getTextWidth(paint, language, origTextSize, bounds);
- textSize = origTextSize * Math.min(width / textWidth, 1.0f);
- }
- paint.setTextSize(textSize);
-
- return language;
- }
-
- private BitmapDrawable getSpaceDrawable(Locale locale, boolean isAutoCorrection) {
- final Integer hashCode = Arrays.hashCode(
- new Object[] { locale, isAutoCorrection, mSpacebarTextFadeFactor });
- final BitmapDrawable cached = mSpaceDrawableCache.get(hashCode);
- if (cached != null) {
- return cached;
- }
- final BitmapDrawable drawable = new BitmapDrawable(mRes, drawSpacebar(
- locale, isAutoCorrection, mSpacebarTextFadeFactor));
- mSpaceDrawableCache.put(hashCode, drawable);
- return drawable;
- }
-
- private Bitmap drawSpacebar(Locale inputLocale, boolean isAutoCorrection,
- float textFadeFactor) {
- final int width = mSpaceKey.mWidth;
- final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight;
- final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- final Canvas canvas = new Canvas(buffer);
- final Resources res = mRes;
- canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
-
- // If application locales are explicitly selected.
- if (inputLocale != null) {
- final Paint paint = new Paint();
- paint.setAntiAlias(true);
- paint.setTextAlign(Align.CENTER);
-
- final String textSizeOfLanguageOnSpacebar = res.getString(
- R.string.config_text_size_of_language_on_spacebar,
- SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR);
- final int textStyle;
- final int defaultTextSize;
- if (MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR.equals(textSizeOfLanguageOnSpacebar)) {
- textStyle = android.R.style.TextAppearance_Medium;
- defaultTextSize = 18;
- } else {
- textStyle = android.R.style.TextAppearance_Small;
- defaultTextSize = 14;
- }
-
- final String language = layoutSpacebar(paint, inputLocale, width, getTextSizeFromTheme(
- mTheme, textStyle, defaultTextSize));
-
- // Draw language text with shadow
- // In case there is no space icon, we will place the language text at the center of
- // spacebar.
- final float descent = paint.descent();
- final float textHeight = -paint.ascent() + descent;
- final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE
- : height / 2 + textHeight / 2;
- paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor));
- canvas.drawText(language, width / 2, baseline - descent - 1, paint);
- paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor));
- canvas.drawText(language, width / 2, baseline - descent, paint);
- }
-
- // Draw the spacebar icon at the bottom
- if (isAutoCorrection) {
- final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100;
- final int iconHeight = mAutoCorrectionSpacebarLedIcon.getIntrinsicHeight();
- int x = (width - iconWidth) / 2;
- int y = height - iconHeight;
- mAutoCorrectionSpacebarLedIcon.setBounds(x, y, x + iconWidth, y + iconHeight);
- mAutoCorrectionSpacebarLedIcon.draw(canvas);
- } else if (mSpaceIcon != null) {
- final int iconWidth = mSpaceIcon.getIntrinsicWidth();
- final int iconHeight = mSpaceIcon.getIntrinsicHeight();
- int x = (width - iconWidth) / 2;
- int y = height - iconHeight;
- mSpaceIcon.setBounds(x, y, x + iconWidth, y + iconHeight);
- mSpaceIcon.draw(canvas);
- }
- return buffer;
- }
-
- @Override
- public int[] getNearestKeys(int x, int y) {
- // Avoid dead pixels at edges of the keyboard
- return super.getNearestKeys(Math.max(0, Math.min(x, mOccupiedWidth - 1)),
- Math.max(0, Math.min(y, mOccupiedHeight - 1)));
- }
-
- private static final int[] ATTR_TEXT_SIZE = { android.R.attr.textSize };
-
- public static int getTextSizeFromTheme(Theme theme, int style, int defValue) {
- final TypedArray a = theme.obtainStyledAttributes(style, ATTR_TEXT_SIZE);
- final int textSize = a.getDimensionPixelSize(a.getResourceId(0, 0), defValue);
- a.recycle();
- return textSize;
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 6ce3876b6..88a41579d 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -18,13 +18,17 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
import android.os.Message;
-import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -38,11 +42,15 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils;
+import java.util.Locale;
import java.util.WeakHashMap;
/**
@@ -56,45 +64,66 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
SuddenJumpingTouchEventHandler.ProcessMotionEvent {
private static final String TAG = LatinKeyboardView.class.getSimpleName();
- private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
+ // TODO: Kill process when the usability study mode was changed.
+ private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy;
- private final SuddenJumpingTouchEventHandler mTouchScreenRegulator;
-
- // Timing constants
- private final int mKeyRepeatInterval;
+ /** Listener for {@link KeyboardActionListener}. */
+ private KeyboardActionListener mKeyboardActionListener;
- // Mini keyboard
+ /* Space key and its icons */
+ private Key mSpaceKey;
+ private Drawable mSpaceIcon;
+ // Stuff to draw language name on spacebar.
+ private boolean mNeedsToDisplayLanguage;
+ private Locale mSpacebarLocale;
+ private float mSpacebarTextFadeFactor = 0.0f;
+ private final float mSpacebarTextRatio;
+ private float mSpacebarTextSize;
+ private final int mSpacebarTextColor;
+ private final int mSpacebarTextShadowColor;
+ // Height in space key the language name will be drawn. (proportional to space key height)
+ private static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
+ // If the full language name needs to be smaller than this value to be drawn on space key,
+ // its short language name will be used instead.
+ private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f;
+ // Stuff to draw auto correction LED on spacebar.
+ private boolean mAutoCorrectionSpacebarLedOn;
+ private final boolean mAutoCorrectionSpacebarLedEnabled;
+ private final Drawable mAutoCorrectionSpacebarLedIcon;
+ private static final int SPACE_LED_LENGTH_PERCENT = 80;
+
+ // More keys keyboard
private PopupWindow mMoreKeysWindow;
private MoreKeysPanel mMoreKeysPanel;
private int mMoreKeysPanelPointerTrackerId;
private final WeakHashMap<Key, MoreKeysPanel> mMoreKeysPanelCache =
new WeakHashMap<Key, MoreKeysPanel>();
+ private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint;
- /** Listener for {@link KeyboardActionListener}. */
- private KeyboardActionListener mKeyboardActionListener;
-
- private final boolean mHasDistinctMultitouch;
- private int mOldPointerCount = 1;
- private int mOldKeyIndex;
+ private final PointerTrackerParams mPointerTrackerParams;
+ private final boolean mIsSpacebarTriggeringPopupByLongPress;
+ private final SuddenJumpingTouchEventHandler mTouchScreenRegulator;
- private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
protected KeyDetector mKeyDetector;
+ private boolean mHasDistinctMultitouch;
+ private int mOldPointerCount = 1;
+ private Key mOldKey;
- // To detect double tap.
- protected GestureDetector mGestureDetector;
-
- private final KeyTimerHandler mKeyTimerHandler = new KeyTimerHandler(this);
+ private final KeyTimerHandler mKeyTimerHandler;
private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView>
implements TimerProxy {
private static final int MSG_REPEAT_KEY = 1;
private static final int MSG_LONGPRESS_KEY = 2;
- private static final int MSG_IGNORE_DOUBLE_TAP = 3;
+ private static final int MSG_DOUBLE_TAP = 3;
+ private static final int MSG_KEY_TYPED = 4;
+ private final KeyTimerParams mParams;
private boolean mInKeyRepeat;
- public KeyTimerHandler(LatinKeyboardView outerInstance) {
+ public KeyTimerHandler(LatinKeyboardView outerInstance, KeyTimerParams params) {
super(outerInstance);
+ mParams = params;
}
@Override
@@ -103,19 +132,27 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
final PointerTracker tracker = (PointerTracker) msg.obj;
switch (msg.what) {
case MSG_REPEAT_KEY:
- tracker.onRepeatKey(msg.arg1);
- startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, msg.arg1, tracker);
+ tracker.onRepeatKey(tracker.getKey());
+ startKeyRepeatTimer(tracker, mParams.mKeyRepeatInterval);
break;
case MSG_LONGPRESS_KEY:
- keyboardView.openMiniKeyboardIfRequired(msg.arg1, tracker);
+ if (tracker != null) {
+ keyboardView.openMoreKeysKeyboardIfRequired(tracker.getKey(), tracker);
+ } else {
+ KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1);
+ }
break;
}
}
+ private void startKeyRepeatTimer(PointerTracker tracker, long delay) {
+ sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker), delay);
+ }
+
@Override
- public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
+ public void startKeyRepeatTimer(PointerTracker tracker) {
mInKeyRepeat = true;
- sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
+ startKeyRepeatTimer(tracker, mParams.mKeyRepeatStartTimeout);
}
public void cancelKeyRepeatTimer() {
@@ -128,9 +165,49 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
@Override
- public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
+ public void startLongPressTimer(int code) {
+ cancelLongPressTimer();
+ final int delay;
+ switch (code) {
+ case Keyboard.CODE_SHIFT:
+ delay = mParams.mLongPressShiftKeyTimeout;
+ break;
+ default:
+ delay = 0;
+ break;
+ }
+ if (delay > 0) {
+ sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, code, 0), delay);
+ }
+ }
+
+ @Override
+ public void startLongPressTimer(PointerTracker tracker) {
cancelLongPressTimer();
- sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
+ if (tracker != null) {
+ final Key key = tracker.getKey();
+ final int delay;
+ switch (key.mCode) {
+ case Keyboard.CODE_SHIFT:
+ delay = mParams.mLongPressShiftKeyTimeout;
+ break;
+ case Keyboard.CODE_SPACE:
+ delay = mParams.mLongPressSpaceKeyTimeout;
+ break;
+ default:
+ if (KeyboardSwitcher.getInstance().isInMomentarySwitchState()) {
+ // We use longer timeout for sliding finger input started from the symbols
+ // mode key.
+ delay = mParams.mLongPressKeyTimeout * 3;
+ } else {
+ delay = mParams.mLongPressKeyTimeout;
+ }
+ break;
+ }
+ if (delay > 0) {
+ sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
+ }
+ }
}
@Override
@@ -139,19 +216,31 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
@Override
- public void cancelKeyTimers() {
- cancelKeyRepeatTimer();
- cancelLongPressTimer();
- removeMessages(MSG_IGNORE_DOUBLE_TAP);
+ public void startKeyTypedTimer() {
+ removeMessages(MSG_KEY_TYPED);
+ sendMessageDelayed(obtainMessage(MSG_KEY_TYPED), mParams.mIgnoreSpecialKeyTimeout);
+ }
+
+ @Override
+ public boolean isTyping() {
+ return hasMessages(MSG_KEY_TYPED);
}
- public void startIgnoringDoubleTap() {
- sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
+ @Override
+ public void startDoubleTapTimer() {
+ sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP),
ViewConfiguration.getDoubleTapTimeout());
}
- public boolean isIgnoringDoubleTap() {
- return hasMessages(MSG_IGNORE_DOUBLE_TAP);
+ @Override
+ public boolean isInDoubleTapTimeout() {
+ return hasMessages(MSG_DOUBLE_TAP);
+ }
+
+ @Override
+ public void cancelKeyTimers() {
+ cancelKeyRepeatTimer();
+ cancelLongPressTimer();
}
public void cancelAllMessages() {
@@ -159,52 +248,64 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
}
- private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
- private boolean mProcessingShiftDoubleTapEvent = false;
+ public static class PointerTrackerParams {
+ public final boolean mSlidingKeyInputEnabled;
+ public final int mTouchNoiseThresholdTime;
+ public final float mTouchNoiseThresholdDistance;
- @Override
- public boolean onDoubleTap(MotionEvent firstDown) {
- final Keyboard keyboard = getKeyboard();
- if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard instanceof LatinKeyboard
- && ((LatinKeyboard) keyboard).isAlphaKeyboard()) {
- final int pointerIndex = firstDown.getActionIndex();
- final int id = firstDown.getPointerId(pointerIndex);
- final PointerTracker tracker = getPointerTracker(id);
- // If the first down event is on shift key.
- if (tracker.isOnShiftKey((int) firstDown.getX(), (int) firstDown.getY())) {
- mProcessingShiftDoubleTapEvent = true;
- return true;
- }
- }
- mProcessingShiftDoubleTapEvent = false;
- return false;
+ public static final PointerTrackerParams DEFAULT = new PointerTrackerParams();
+
+ private PointerTrackerParams() {
+ mSlidingKeyInputEnabled = false;
+ mTouchNoiseThresholdTime =0;
+ mTouchNoiseThresholdDistance = 0;
}
- @Override
- public boolean onDoubleTapEvent(MotionEvent secondTap) {
- if (mProcessingShiftDoubleTapEvent
- && secondTap.getAction() == MotionEvent.ACTION_DOWN) {
- final MotionEvent secondDown = secondTap;
- final int pointerIndex = secondDown.getActionIndex();
- final int id = secondDown.getPointerId(pointerIndex);
- final PointerTracker tracker = getPointerTracker(id);
- // If the second down event is also on shift key.
- if (tracker.isOnShiftKey((int) secondDown.getX(), (int) secondDown.getY())) {
- // Detected a double tap on shift key. If we are in the ignoring double tap
- // mode, it means we have already turned off caps lock in
- // {@link KeyboardSwitcher#onReleaseShift} .
- onDoubleTapShiftKey(tracker, mKeyTimerHandler.isIgnoringDoubleTap());
- return true;
- }
- // Otherwise these events should not be handled as double tap.
- mProcessingShiftDoubleTapEvent = false;
- }
- return mProcessingShiftDoubleTapEvent;
+ public PointerTrackerParams(TypedArray latinKeyboardViewAttr) {
+ mSlidingKeyInputEnabled = latinKeyboardViewAttr.getBoolean(
+ R.styleable.LatinKeyboardView_slidingKeyInputEnable, false);
+ mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0);
+ mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension(
+ R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0);
+ }
+ }
+
+ static class KeyTimerParams {
+ public final int mKeyRepeatStartTimeout;
+ public final int mKeyRepeatInterval;
+ public final int mLongPressKeyTimeout;
+ public final int mLongPressShiftKeyTimeout;
+ public final int mLongPressSpaceKeyTimeout;
+ public final int mIgnoreSpecialKeyTimeout;
+
+ KeyTimerParams() {
+ mKeyRepeatStartTimeout = 0;
+ mKeyRepeatInterval = 0;
+ mLongPressKeyTimeout = 0;
+ mLongPressShiftKeyTimeout = 0;
+ mLongPressSpaceKeyTimeout = 0;
+ mIgnoreSpecialKeyTimeout = 0;
+ }
+
+ public KeyTimerParams(TypedArray latinKeyboardViewAttr) {
+ mKeyRepeatStartTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_keyRepeatStartTimeout, 0);
+ mKeyRepeatInterval = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_keyRepeatInterval, 0);
+ mLongPressKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_longPressKeyTimeout, 0);
+ mLongPressShiftKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_longPressShiftKeyTimeout, 0);
+ mLongPressSpaceKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_longPressSpaceKeyTimeout, 0);
+ mIgnoreSpecialKeyTimeout = latinKeyboardViewAttr.getInt(
+ R.styleable.LatinKeyboardView_ignoreSpecialKeyTimeout, 0);
}
}
public LatinKeyboardView(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.keyboardViewStyle);
+ this(context, attrs, R.attr.latinKeyboardViewStyle);
}
public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
@@ -212,27 +313,36 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this);
- final Resources res = getResources();
- mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean(
- R.bool.config_show_mini_keyboard_at_touched_point);
- final float keyHysteresisDistance = res.getDimension(R.dimen.key_hysteresis_distance);
- mKeyDetector = new KeyDetector(keyHysteresisDistance);
-
- final boolean ignoreMultitouch = true;
- mGestureDetector = new GestureDetector(
- getContext(), new DoubleTapListener(), null, ignoreMultitouch);
- mGestureDetector.setIsLongpressEnabled(false);
-
mHasDistinctMultitouch = context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
- mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
- PointerTracker.init(mHasDistinctMultitouch, getContext());
- }
+ PointerTracker.init(mHasDistinctMultitouch);
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.LatinKeyboardView, defStyle, R.style.LatinKeyboardView);
+ mAutoCorrectionSpacebarLedEnabled = a.getBoolean(
+ R.styleable.LatinKeyboardView_autoCorrectionSpacebarLedEnabled, false);
+ mAutoCorrectionSpacebarLedIcon = a.getDrawable(
+ R.styleable.LatinKeyboardView_autoCorrectionSpacebarLedIcon);
+ mSpacebarTextRatio = a.getFraction(R.styleable.LatinKeyboardView_spacebarTextRatio,
+ 1000, 1000, 1) / 1000.0f;
+ mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboardView_spacebarTextColor, 0);
+ mSpacebarTextShadowColor = a.getColor(
+ R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0);
+
+ final KeyTimerParams keyTimerParams = new KeyTimerParams(a);
+ mPointerTrackerParams = new PointerTrackerParams(a);
+ mIsSpacebarTriggeringPopupByLongPress = (keyTimerParams.mLongPressSpaceKeyTimeout > 0);
+
+ final float keyHysteresisDistance = a.getDimension(
+ R.styleable.LatinKeyboardView_keyHysteresisDistance, 0);
+ mKeyDetector = new KeyDetector(keyHysteresisDistance);
+ mKeyTimerHandler = new KeyTimerHandler(this, keyTimerParams);
+ mConfigShowMoreKeysKeyboardAtTouchedPoint = a.getBoolean(
+ R.styleable.LatinKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false);
+ a.recycle();
- public void startIgnoringDoubleTap() {
- if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
- mKeyTimerHandler.startIgnoringDoubleTap();
+ PointerTracker.setParameters(mPointerTrackerParams);
}
public void setKeyboardActionListener(KeyboardActionListener listener) {
@@ -264,20 +374,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
return mKeyTimerHandler;
}
- @Override
- public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
- final Keyboard keyboard = getKeyboard();
- if (keyboard instanceof LatinKeyboard) {
- final LatinKeyboard latinKeyboard = (LatinKeyboard)keyboard;
- if (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard()) {
- // Phone and number keyboard never shows popup preview.
- super.setKeyPreviewPopupEnabled(false, delay);
- return;
- }
- }
- super.setKeyPreviewPopupEnabled(previewEnabled, delay);
- }
-
/**
* Attaches a keyboard to this view. The keyboard can be switched at any time and the
* view will re-layout itself to accommodate the keyboard.
@@ -296,6 +392,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
PointerTracker.setKeyDetector(mKeyDetector);
mTouchScreenRegulator.setKeyboard(keyboard);
mMoreKeysPanelCache.clear();
+
+ mSpaceKey = keyboard.getKey(Keyboard.CODE_SPACE);
+ mSpaceIcon = keyboard.mIconsSet.getIconDrawable(KeyboardIconsSet.ICON_SPACE);
+ final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
+ mSpacebarTextSize = keyHeight * mSpacebarTextRatio;
+ mSpacebarLocale = keyboard.mId.mLocale;
}
/**
@@ -306,6 +408,10 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
return mHasDistinctMultitouch;
}
+ public void setDistinctMultitouch(boolean hasDistinctMultitouch) {
+ mHasDistinctMultitouch = hasDistinctMultitouch;
+ }
+
/**
* When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
* codes for adjacent keys. When disabled, only the primary key code will be
@@ -329,7 +435,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
super.cancelAllMessages();
}
- private boolean openMiniKeyboardIfRequired(int keyIndex, PointerTracker tracker) {
+ private boolean openMoreKeysKeyboardIfRequired(Key parentKey, PointerTracker tracker) {
// Check if we have a popup layout specified first.
if (mMoreKeysLayout == 0) {
return false;
@@ -338,22 +444,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
// Check if we are already displaying popup panel.
if (mMoreKeysPanel != null)
return false;
- final Key parentKey = tracker.getKey(keyIndex);
if (parentKey == null)
return false;
return onLongPress(parentKey, tracker);
}
- private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker,
- final boolean ignore) {
- // When shift key is double tapped, the first tap is correctly processed as usual tap. And
- // the second tap is treated as this double tap event, so that we need not mark tracker
- // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue.
- final int primaryCode = ignore ? Keyboard.CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY
- : Keyboard.CODE_CAPSLOCK;
- invokeCodeInput(primaryCode);
- }
-
// This default implementation returns a more keys panel.
protected MoreKeysPanel onCreateMoreKeysPanel(Key parentKey) {
if (parentKey.mMoreKeys == null)
@@ -363,28 +458,19 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
if (container == null)
throw new NullPointerException();
- final MiniKeyboardView miniKeyboardView =
- (MiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
+ final MoreKeysKeyboardView moreKeysKeyboardView =
+ (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view);
final Keyboard parentKeyboard = getKeyboard();
- final Keyboard miniKeyboard = new MiniKeyboard.Builder(
+ final Keyboard moreKeysKeyboard = new MoreKeysKeyboard.Builder(
this, parentKeyboard.mMoreKeysTemplate, parentKey, parentKeyboard).build();
- miniKeyboardView.setKeyboard(miniKeyboard);
+ moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- return miniKeyboardView;
- }
-
- public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboard oldKeyboard) {
- final Keyboard keyboard = getKeyboard();
- // We should not set text fade factor to the keyboard which does not display the language on
- // its spacebar.
- if (keyboard instanceof LatinKeyboard && keyboard == oldKeyboard) {
- ((LatinKeyboard)keyboard).setSpacebarTextFadeFactor(fadeFactor, this);
- }
+ return moreKeysKeyboardView;
}
/**
- * Called when a key is long pressed. By default this will open mini keyboard associated
+ * Called when a key is long pressed. By default this will open more keys keyboard associated
* with this key.
* @param parentKey the key that was long pressed
* @param tracker the pointer tracker which pressed the parent key
@@ -394,48 +480,37 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
protected boolean onLongPress(Key parentKey, PointerTracker tracker) {
final int primaryCode = parentKey.mCode;
final Keyboard keyboard = getKeyboard();
- if (keyboard instanceof LatinKeyboard) {
- final LatinKeyboard latinKeyboard = (LatinKeyboard) keyboard;
- if (primaryCode == Keyboard.CODE_DIGIT0 && latinKeyboard.isPhoneKeyboard()) {
- tracker.onLongPressed();
- // Long pressing on 0 in phone number keypad gives you a '+'.
- invokeCodeInput(Keyboard.CODE_PLUS);
- invokeReleaseKey(primaryCode);
- return true;
- }
- if (primaryCode == Keyboard.CODE_SHIFT && latinKeyboard.isAlphaKeyboard()) {
- tracker.onLongPressed();
- invokeCodeInput(Keyboard.CODE_CAPSLOCK);
- invokeReleaseKey(primaryCode);
- return true;
- }
+ if (primaryCode == Keyboard.CODE_DIGIT0 && keyboard.mId.isPhoneKeyboard()) {
+ tracker.onLongPressed();
+ // Long pressing on 0 in phone number keypad gives you a '+'.
+ invokeCodeInput(Keyboard.CODE_PLUS);
+ invokeReleaseKey(primaryCode);
+ KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode);
+ return true;
}
- if (primaryCode == Keyboard.CODE_SETTINGS || primaryCode == Keyboard.CODE_SPACE) {
- // Both long pressing settings key and space key invoke IME switcher dialog.
+ if (primaryCode == Keyboard.CODE_SPACE) {
+ // Long pressing the space key invokes IME switcher dialog.
if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) {
tracker.onLongPressed();
invokeReleaseKey(primaryCode);
return true;
- } else {
- return openMoreKeysPanel(parentKey, tracker);
}
- } else {
- return openMoreKeysPanel(parentKey, tracker);
}
+ return openMoreKeysPanel(parentKey, tracker);
}
private boolean invokeCustomRequest(int code) {
- return getKeyboardActionListener().onCustomRequest(code);
+ return mKeyboardActionListener.onCustomRequest(code);
}
private void invokeCodeInput(int primaryCode) {
- getKeyboardActionListener().onCodeInput(primaryCode, null,
+ mKeyboardActionListener.onCodeInput(primaryCode, null,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
}
private void invokeReleaseKey(int primaryCode) {
- getKeyboardActionListener().onRelease(primaryCode, false);
+ mKeyboardActionListener.onReleaseKey(primaryCode, false);
}
private boolean openMoreKeysPanel(Key parentKey, PointerTracker tracker) {
@@ -449,30 +524,24 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
if (mMoreKeysWindow == null) {
mMoreKeysWindow = new PopupWindow(getContext());
mMoreKeysWindow.setBackgroundDrawable(null);
- mMoreKeysWindow.setAnimationStyle(R.style.MiniKeyboardAnimation);
+ mMoreKeysWindow.setAnimationStyle(R.style.MoreKeysKeyboardAnimation);
}
mMoreKeysPanel = moreKeysPanel;
mMoreKeysPanelPointerTrackerId = tracker.mPointerId;
final Keyboard keyboard = getKeyboard();
- moreKeysPanel.setShifted(keyboard.isShiftedOrShiftLocked());
- final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX()
+ final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint) ? tracker.getLastX()
: parentKey.mX + parentKey.mWidth / 2;
final int pointY = parentKey.mY - keyboard.mVerticalGap;
moreKeysPanel.showMoreKeysPanel(
- this, this, pointX, pointY, mMoreKeysWindow, getKeyboardActionListener());
+ this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
final int translatedX = moreKeysPanel.translateX(tracker.getLastX());
final int translatedY = moreKeysPanel.translateY(tracker.getLastY());
- tracker.onShowMoreKeysPanel(
- translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel);
+ tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel);
dimEntireKeyboard(true);
return true;
}
- private PointerTracker getPointerTracker(final int id) {
- return PointerTracker.getPointerTracker(id, this);
- }
-
public boolean isInSlidingKeyInput() {
if (mMoreKeysPanel != null) {
return true;
@@ -508,14 +577,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
return true;
}
- // Gesture detector must be enabled only when mini-keyboard is not on the screen.
- if (mMoreKeysPanel == null && mGestureDetector != null
- && mGestureDetector.onTouchEvent(me)) {
- PointerTracker.dismissAllKeyPreviews();
- mKeyTimerHandler.cancelKeyTimers();
- return true;
- }
-
final long eventTime = me.getEventTime();
final int index = me.getActionIndex();
final int id = me.getPointerId(index);
@@ -527,9 +588,37 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
x = (int)me.getX(index);
y = (int)me.getY(index);
}
+ if (ENABLE_USABILITY_STUDY_LOG) {
+ final String eventTag;
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ eventTag = "[Up]";
+ break;
+ case MotionEvent.ACTION_DOWN:
+ eventTag = "[Down]";
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ eventTag = "[PointerUp]";
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ eventTag = "[PointerDown]";
+ break;
+ case MotionEvent.ACTION_MOVE: // Skip this as being logged below
+ eventTag = "";
+ break;
+ default:
+ eventTag = "[Action" + action + "]";
+ break;
+ }
+ if (!TextUtils.isEmpty(eventTag)) {
+ UsabilityStudyLogUtils.getInstance().write(
+ eventTag + eventTime + "," + id + "," + x + "," + y + ","
+ + me.getSize(index) + "," + me.getPressure(index));
+ }
+ }
if (mKeyTimerHandler.isInKeyRepeat()) {
- final PointerTracker tracker = getPointerTracker(id);
+ final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
// Key repeating timer will be canceled if 2 or more keys are in action, and current
// event (UP or DOWN) is non-modifier key.
if (pointerCount > 1 && !tracker.isModifier()) {
@@ -543,13 +632,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
// multi-touch panel.
if (nonDistinctMultitouch) {
// Use only main (id=0) pointer tracker.
- PointerTracker tracker = getPointerTracker(0);
+ final PointerTracker tracker = PointerTracker.getPointerTracker(0, this);
if (pointerCount == 1 && oldPointerCount == 2) {
// Multi-touch to single touch transition.
// Send a down event for the latest pointer if the key is different from the
// previous key.
- final int newKeyIndex = tracker.getKeyIndexOn(x, y);
- if (mOldKeyIndex != newKeyIndex) {
+ final Key newKey = tracker.getKeyOn(x, y);
+ if (mOldKey != newKey) {
tracker.onDownEvent(x, y, eventTime, this);
if (action == MotionEvent.ACTION_UP)
tracker.onUpEvent(x, y, eventTime);
@@ -559,7 +648,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
// Send an up event for the last pointer.
final int lastX = tracker.getLastX();
final int lastY = tracker.getLastY();
- mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
+ mOldKey = tracker.getKeyOn(lastX, lastY);
tracker.onUpEvent(lastX, lastY, eventTime);
} else if (pointerCount == 1 && oldPointerCount == 1) {
tracker.processMotionEvent(action, x, y, eventTime, this);
@@ -572,7 +661,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
if (action == MotionEvent.ACTION_MOVE) {
for (int i = 0; i < pointerCount; i++) {
- final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
+ final PointerTracker tracker = PointerTracker.getPointerTracker(
+ me.getPointerId(i), this);
final int px, py;
if (mMoreKeysPanel != null
&& tracker.mPointerId == mMoreKeysPanelPointerTrackerId) {
@@ -583,9 +673,15 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
py = (int)me.getY(i);
}
tracker.onMoveEvent(px, py, eventTime);
+ if (ENABLE_USABILITY_STUDY_LOG) {
+ UsabilityStudyLogUtils.getInstance().write("[Move]" + eventTime + ","
+ + me.getPointerId(i) + "," + px + "," + py + ","
+ + me.getSize(i) + "," + me.getPressure(i));
+ }
}
} else {
- getPointerTracker(id).processMotionEvent(action, x, y, eventTime, this);
+ final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
+ tracker.processMotionEvent(action, x, y, eventTime, this);
}
return true;
@@ -637,9 +733,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- final PointerTracker tracker = getPointerTracker(0);
return AccessibleKeyboardViewProxy.getInstance().dispatchPopulateAccessibilityEvent(
- event, tracker) || super.dispatchPopulateAccessibilityEvent(event);
+ event) || super.dispatchPopulateAccessibilityEvent(event);
}
return super.dispatchPopulateAccessibilityEvent(event);
@@ -656,11 +751,133 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
*/
public boolean dispatchHoverEvent(MotionEvent event) {
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- final PointerTracker tracker = getPointerTracker(0);
+ final PointerTracker tracker = PointerTracker.getPointerTracker(0, this);
return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(event, tracker);
}
// Reflection doesn't support calling superclass methods.
return false;
}
+
+ public void updateShortcutKey(boolean available) {
+ final Keyboard keyboard = getKeyboard();
+ if (keyboard == null) return;
+ final Key shortcutKey = keyboard.getKey(Keyboard.CODE_SHORTCUT);
+ if (shortcutKey == null) return;
+ shortcutKey.setEnabled(available);
+ invalidateKey(shortcutKey);
+ }
+
+ public void updateSpacebar(float fadeFactor, boolean needsToDisplayLanguage) {
+ mSpacebarTextFadeFactor = fadeFactor;
+ mNeedsToDisplayLanguage = needsToDisplayLanguage;
+ invalidateKey(mSpaceKey);
+ }
+
+ public void updateAutoCorrectionState(boolean isAutoCorrection) {
+ if (!mAutoCorrectionSpacebarLedEnabled) return;
+ mAutoCorrectionSpacebarLedOn = isAutoCorrection;
+ invalidateKey(mSpaceKey);
+ }
+
+ @Override
+ protected void onDrawKeyTopVisuals(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
+ super.onDrawKeyTopVisuals(key, canvas, paint, params);
+
+ if (key.mCode == Keyboard.CODE_SPACE) {
+ drawSpacebar(key, canvas, paint);
+
+ // Whether space key needs to show the "..." popup hint for special purposes
+ if (mIsSpacebarTriggeringPopupByLongPress
+ && Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
+ drawKeyPopupHint(key, canvas, paint, params);
+ }
+ }
+ }
+
+ private static int getSpacebarTextColor(int color, float fadeFactor) {
+ final int newColor = Color.argb((int)(Color.alpha(color) * fadeFactor),
+ Color.red(color), Color.green(color), Color.blue(color));
+ return newColor;
+ }
+
+ // Compute width of text with specified text size using paint.
+ private int getTextWidth(Paint paint, String text, float textSize) {
+ paint.setTextSize(textSize);
+ return (int)getLabelWidth(text, paint);
+ }
+
+ // Layout locale language name on spacebar.
+ private String layoutLanguageOnSpacebar(Paint paint, Locale locale, int width,
+ float origTextSize) {
+ paint.setTextAlign(Align.CENTER);
+ paint.setTypeface(Typeface.DEFAULT);
+ // Estimate appropriate language name text size to fit in maxTextWidth.
+ String language = Utils.getFullDisplayName(locale, true);
+ int textWidth = getTextWidth(paint, language, origTextSize);
+ // Assuming text width and text size are proportional to each other.
+ float textSize = origTextSize * Math.min(width / textWidth, 1.0f);
+ // allow variable text size
+ textWidth = getTextWidth(paint, language, textSize);
+ // If text size goes too small or text does not fit, use middle or short name
+ final boolean useMiddleName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME)
+ || (textWidth > width);
+
+ final boolean useShortName;
+ if (useMiddleName) {
+ language = Utils.getMiddleDisplayLanguage(locale);
+ textWidth = getTextWidth(paint, language, origTextSize);
+ textSize = origTextSize * Math.min(width / textWidth, 1.0f);
+ useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME)
+ || (textWidth > width);
+ } else {
+ useShortName = false;
+ }
+
+ if (useShortName) {
+ language = Utils.getShortDisplayLanguage(locale);
+ textWidth = getTextWidth(paint, language, origTextSize);
+ textSize = origTextSize * Math.min(width / textWidth, 1.0f);
+ }
+ paint.setTextSize(textSize);
+
+ return language;
+ }
+
+ private void drawSpacebar(Key key, Canvas canvas, Paint paint) {
+ final int width = key.mWidth;
+ final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : key.mHeight;
+
+ // If application locales are explicitly selected.
+ if (mNeedsToDisplayLanguage) {
+ final String language = layoutLanguageOnSpacebar(paint, mSpacebarLocale, width,
+ mSpacebarTextSize);
+ // Draw language text with shadow
+ // In case there is no space icon, we will place the language text at the center of
+ // spacebar.
+ final float descent = paint.descent();
+ final float textHeight = -paint.ascent() + descent;
+ final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE
+ : height / 2 + textHeight / 2;
+ paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor));
+ canvas.drawText(language, width / 2, baseline - descent - 1, paint);
+ paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor));
+ canvas.drawText(language, width / 2, baseline - descent, paint);
+ }
+
+ // Draw the spacebar icon at the bottom
+ if (mAutoCorrectionSpacebarLedOn) {
+ final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100;
+ final int iconHeight = mAutoCorrectionSpacebarLedIcon.getIntrinsicHeight();
+ int x = (width - iconWidth) / 2;
+ int y = height - iconHeight;
+ drawIcon(canvas, mAutoCorrectionSpacebarLedIcon, x, y, iconWidth, iconHeight);
+ } else if (mSpaceIcon != null) {
+ final int iconWidth = mSpaceIcon.getIntrinsicWidth();
+ final int iconHeight = mSpaceIcon.getIntrinsicHeight();
+ int x = (width - iconWidth) / 2;
+ int y = height - iconHeight;
+ drawIcon(canvas, mSpaceIcon, x, y, iconWidth, iconHeight);
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
index d20204611..742ee98d7 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.keyboard;
-import java.util.List;
-
public class MoreKeysDetector extends KeyDetector {
private final int mSlideAllowanceSquare;
private final int mSlideAllowanceSquareTop;
@@ -41,24 +39,23 @@ public class MoreKeysDetector extends KeyDetector {
}
@Override
- public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
- final List<Key> keys = getKeyboard().mKeys;
+ public Key getKeyAndNearbyCodes(int x, int y, final int[] allCodes) {
final int touchX = getTouchX(x);
final int touchY = getTouchY(y);
- int nearestIndex = NOT_A_KEY;
+ Key nearestKey = null;
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
- final int keyCount = keys.size();
- for (int index = 0; index < keyCount; index++) {
- final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY);
+ for (final Key key : getKeyboard().mKeys) {
+ final int dist = key.squaredDistanceToEdge(touchX, touchY);
if (dist < nearestDist) {
- nearestIndex = index;
+ nearestKey = key;
nearestDist = dist;
}
}
- if (allCodes != null && nearestIndex != NOT_A_KEY)
- allCodes[0] = keys.get(nearestIndex).mCode;
- return nearestIndex;
+ if (allCodes != null && nearestKey != null) {
+ allCodes[0] = nearestKey.mCode;
+ }
+ return nearestKey;
}
-} \ No newline at end of file
+}
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index ac9290bfd..1597b1ebb 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -18,15 +18,13 @@ package com.android.inputmethod.keyboard;
import android.graphics.Paint;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.KeyboardParams;
-import com.android.inputmethod.keyboard.internal.MoreKeySpecParser;
+import com.android.inputmethod.keyboard.internal.KeySpecParser;
import com.android.inputmethod.latin.R;
-public class MiniKeyboard extends Keyboard {
+public class MoreKeysKeyboard extends Keyboard {
private final int mDefaultKeyCoordX;
- private MiniKeyboard(Builder.MiniKeyboardParams params) {
+ MoreKeysKeyboard(Builder.MoreKeysKeyboardParams params) {
super(params);
mDefaultKeyCoordX = params.getDefaultKeyCoordX() + params.mDefaultKeyWidth / 2;
}
@@ -35,21 +33,21 @@ public class MiniKeyboard extends Keyboard {
return mDefaultKeyCoordX;
}
- public static class Builder extends KeyboardBuilder<Builder.MiniKeyboardParams> {
- private final CharSequence[] mMoreKeys;
+ public static class Builder extends Keyboard.Builder<Builder.MoreKeysKeyboardParams> {
+ private final String[] mMoreKeys;
- public static class MiniKeyboardParams extends KeyboardParams {
+ public static class MoreKeysKeyboardParams extends Keyboard.Params {
/* package */int mTopRowAdjustment;
public int mNumRows;
public int mNumColumns;
public int mLeftKeys;
public int mRightKeys; // includes default key.
- public MiniKeyboardParams() {
+ public MoreKeysKeyboardParams() {
super();
}
- /* package for test */MiniKeyboardParams(int numKeys, int maxColumns, int keyWidth,
+ /* package for test */MoreKeysKeyboardParams(int numKeys, int maxColumns, int keyWidth,
int rowHeight, int coordXInParent, int parentKeyboardWidth) {
super();
setParameters(numKeys, maxColumns, keyWidth, rowHeight, coordXInParent,
@@ -57,21 +55,21 @@ public class MiniKeyboard extends Keyboard {
}
/**
- * Set keyboard parameters of mini keyboard.
+ * Set keyboard parameters of more keys keyboard.
*
- * @param numKeys number of keys in this mini keyboard.
- * @param maxColumns number of maximum columns of this mini keyboard.
- * @param keyWidth mini keyboard key width in pixel, including horizontal gap.
- * @param rowHeight mini keyboard row height in pixel, including vertical gap.
- * @param coordXInParent coordinate x of the popup key in parent keyboard.
+ * @param numKeys number of keys in this more keys keyboard.
+ * @param maxColumns number of maximum columns of this more keys keyboard.
+ * @param keyWidth more keys keyboard key width in pixel, including horizontal gap.
+ * @param rowHeight more keys keyboard row height in pixel, including vertical gap.
+ * @param coordXInParent coordinate x of the key preview in parent keyboard.
* @param parentKeyboardWidth parent keyboard width in pixel.
*/
public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
int coordXInParent, int parentKeyboardWidth) {
if (parentKeyboardWidth / keyWidth < maxColumns) {
throw new IllegalArgumentException(
- "Keyboard is too small to hold mini keyboard: " + parentKeyboardWidth
- + " " + keyWidth + " " + maxColumns);
+ "Keyboard is too small to hold more keys keyboard: "
+ + parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
}
mDefaultKeyWidth = keyWidth;
mDefaultRowHeight = rowHeight;
@@ -83,29 +81,29 @@ public class MiniKeyboard extends Keyboard {
final int numLeftKeys = (numColumns - 1) / 2;
final int numRightKeys = numColumns - numLeftKeys; // including default key.
+ // Maximum number of keys we can layout both side of the parent key
final int maxLeftKeys = coordXInParent / keyWidth;
- final int maxRightKeys = Math.max(1, (parentKeyboardWidth - coordXInParent)
- / keyWidth);
+ final int maxRightKeys = (parentKeyboardWidth - coordXInParent) / keyWidth;
int leftKeys, rightKeys;
if (numLeftKeys > maxLeftKeys) {
leftKeys = maxLeftKeys;
- rightKeys = numColumns - maxLeftKeys;
- } else if (numRightKeys > maxRightKeys) {
- leftKeys = numColumns - maxRightKeys;
- rightKeys = maxRightKeys;
+ rightKeys = numColumns - leftKeys;
+ } else if (numRightKeys > maxRightKeys + 1) {
+ rightKeys = maxRightKeys + 1; // include default key
+ leftKeys = numColumns - rightKeys;
} else {
leftKeys = numLeftKeys;
rightKeys = numRightKeys;
}
- // Shift right if the left edge of mini keyboard is on the edge of parent keyboard
- // unless the parent key is on the left edge.
- if (leftKeys * keyWidth >= coordXInParent && leftKeys > 0) {
+ // If the left keys fill the left side of the parent key, entire more keys keyboard
+ // should be shifted to the right unless the parent key is on the left edge.
+ if (maxLeftKeys == leftKeys && leftKeys > 0) {
leftKeys--;
rightKeys++;
}
- // Shift left if the right edge of mini keyboard is on the edge of parent keyboard
- // unless the parent key is on the right edge.
- if (rightKeys * keyWidth + coordXInParent >= parentKeyboardWidth && rightKeys > 1) {
+ // If the right keys fill the right side of the parent key, entire more keys
+ // should be shifted to the left unless the parent key is on the right edge.
+ if (maxRightKeys == rightKeys - 1 && rightKeys > 1) {
leftKeys++;
rightKeys--;
}
@@ -113,8 +111,7 @@ public class MiniKeyboard extends Keyboard {
mRightKeys = rightKeys;
// Centering of the top row.
- final boolean onEdge = (leftKeys == 0 || rightKeys == 1);
- if (numRows < 2 || onEdge || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
+ if (numRows < 2 || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
mTopRowAdjustment = 0;
} else if (mLeftKeys < mRightKeys - 1) {
mTopRowAdjustment = 1;
@@ -206,20 +203,20 @@ public class MiniKeyboard extends Keyboard {
}
public Builder(KeyboardView view, int xmlId, Key parentKey, Keyboard parentKeyboard) {
- super(view.getContext(), new MiniKeyboardParams());
- load(parentKeyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId));
+ super(view.getContext(), new MoreKeysKeyboardParams());
+ load(xmlId, parentKeyboard.mId);
- // TODO: Mini keyboard's vertical gap is currently calculated heuristically.
+ // TODO: More keys keyboard's vertical gap is currently calculated heuristically.
// Should revise the algorithm.
mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2;
- mParams.mIsRtlKeyboard = parentKeyboard.mIsRtlKeyboard;
mMoreKeys = parentKey.mMoreKeys;
final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth;
final int previewHeight = view.mKeyPreviewDrawParams.mPreviewBackgroundHeight;
final int width, height;
- // Use pre-computed width and height if these values are available and mini keyboard
- // has only one key to mitigate visual flicker between key preview and mini keyboard.
+ // Use pre-computed width and height if these values are available and more keys
+ // keyboard has only one key to mitigate visual flicker between key preview and more
+ // keys keyboard.
if (view.isKeyPreviewPopupEnabled() && mMoreKeys.length == 1 && previewWidth > 0
&& previewHeight > 0) {
width = previewWidth;
@@ -229,19 +226,17 @@ public class MiniKeyboard extends Keyboard {
height = parentKeyboard.mMostCommonKeyHeight;
}
mParams.setParameters(mMoreKeys.length, parentKey.mMaxMoreKeysColumn, width, height,
- parentKey.mX + (mParams.mDefaultKeyWidth - width) / 2, view.getMeasuredWidth());
+ parentKey.mX + parentKey.mWidth / 2, view.getMeasuredWidth());
}
- private static int getMaxKeyWidth(KeyboardView view, CharSequence[] moreKeys,
- int minKeyWidth) {
+ private static int getMaxKeyWidth(KeyboardView view, String[] moreKeys, int minKeyWidth) {
final int padding = (int) view.getContext().getResources()
- .getDimension(R.dimen.mini_keyboard_key_horizontal_padding);
+ .getDimension(R.dimen.more_keys_keyboard_key_horizontal_padding);
Paint paint = null;
int maxWidth = minKeyWidth;
- for (CharSequence moreKeySpec : moreKeys) {
- final CharSequence label = MoreKeySpecParser.getLabel(moreKeySpec.toString());
- // If the label is single letter, minKeyWidth is enough to hold
- // the label.
+ for (String moreKeySpec : moreKeys) {
+ final String label = KeySpecParser.getLabel(moreKeySpec);
+ // If the label is single letter, minKeyWidth is enough to hold the label.
if (label != null && label.length() > 1) {
if (paint == null) {
paint = new Paint();
@@ -257,17 +252,17 @@ public class MiniKeyboard extends Keyboard {
}
@Override
- public MiniKeyboard build() {
- final MiniKeyboardParams params = mParams;
+ public MoreKeysKeyboard build() {
+ final MoreKeysKeyboardParams params = mParams;
for (int n = 0; n < mMoreKeys.length; n++) {
- final String moreKeySpec = mMoreKeys[n].toString();
+ final String moreKeySpec = mMoreKeys[n];
final int row = n / params.mNumColumns;
final Key key = new Key(mResources, params, moreKeySpec, params.getX(n, row),
params.getY(row), params.mDefaultKeyWidth, params.mDefaultRowHeight);
params.markAsEdgeKey(key, row);
params.onAddKey(key);
}
- return new MiniKeyboard(params);
+ return new MoreKeysKeyboard(params);
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index f2c5b7b49..b030dd95a 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -28,10 +28,10 @@ import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.latin.R;
/**
- * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting
- * key presses and touch movements.
+ * A view that renders a virtual {@link MoreKeysKeyboard}. It handles rendering of keys and
+ * detecting key presses and touch movements.
*/
-public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel {
+public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
private final int[] mCoordinates = new int[2];
private final KeyDetector mKeyDetector;
@@ -43,7 +43,7 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel {
private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter();
- private final KeyboardActionListener mMiniKeyboardListener =
+ private final KeyboardActionListener mMoreKeysKeyboardListener =
new KeyboardActionListener.Adapter() {
@Override
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
@@ -61,25 +61,26 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel {
}
@Override
- public void onPress(int primaryCode, boolean withSliding) {
- mListener.onPress(primaryCode, withSliding);
+ public void onPressKey(int primaryCode) {
+ mListener.onPressKey(primaryCode);
}
+
@Override
- public void onRelease(int primaryCode, boolean withSliding) {
- mListener.onRelease(primaryCode, withSliding);
+ public void onReleaseKey(int primaryCode, boolean withSliding) {
+ mListener.onReleaseKey(primaryCode, withSliding);
}
};
- public MiniKeyboardView(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.miniKeyboardViewStyle);
+ public MoreKeysKeyboardView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
- public MiniKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ public MoreKeysKeyboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final Resources res = context.getResources();
mKeyDetector = new MoreKeysDetector(
- res.getDimension(R.dimen.mini_keyboard_slide_allowance));
+ res.getDimension(R.dimen.more_keys_keyboard_slide_allowance));
setKeyPreviewPopupEnabled(false, 0);
}
@@ -109,7 +110,7 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel {
@Override
public KeyboardActionListener getKeyboardActionListener() {
- return mMiniKeyboardListener;
+ return mMoreKeysKeyboardListener;
}
@Override
@@ -124,32 +125,24 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel {
@Override
public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
- // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a
+ // More keys keyboard needs no pop-up key preview displayed, so we pass always false with a
// delay of 0. The delay does not matter actually since the popup is not shown anyway.
super.setKeyPreviewPopupEnabled(false, 0);
}
@Override
- public void setShifted(boolean shifted) {
- final Keyboard keyboard = getKeyboard();
- if (keyboard.setShifted(shifted)) {
- invalidateAllKeys();
- }
- }
-
- @Override
public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
PopupWindow window, KeyboardActionListener listener) {
mController = controller;
mListener = listener;
final View container = (View)getParent();
- final MiniKeyboard miniKeyboard = (MiniKeyboard)getKeyboard();
+ final MoreKeysKeyboard moreKeysKeyboard = (MoreKeysKeyboard)getKeyboard();
parentView.getLocationInWindow(mCoordinates);
- final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX()
+ final int moreKeysKeyboardLeft = pointX - moreKeysKeyboard.getDefaultCoordX()
+ parentView.getPaddingLeft();
- final int x = wrapUp(Math.max(0, Math.min(miniKeyboardLeft,
- parentView.getWidth() - miniKeyboard.mOccupiedWidth))
+ final int x = wrapUp(Math.max(0, Math.min(moreKeysKeyboardLeft,
+ parentView.getWidth() - moreKeysKeyboard.mOccupiedWidth))
- container.getPaddingLeft() + mCoordinates[0],
container.getMeasuredWidth(), 0, parentView.getWidth());
final int y = pointY
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
index 6314a99db..f9a196d24 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
@@ -24,8 +24,6 @@ public interface MoreKeysPanel extends PointerTracker.KeyEventHandler {
public boolean dismissMoreKeysPanel();
}
- public void setShifted(boolean shifted);
-
/**
* Show more keys panel.
*
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 198e06aab..110f7f6ae 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -16,19 +16,17 @@
package com.android.inputmethod.keyboard;
-import android.content.Context;
-import android.content.res.Resources;
+import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
+import java.util.Set;
public class PointerTracker {
private static final String TAG = PointerTracker.class.getSimpleName();
@@ -67,37 +65,46 @@ public class PointerTracker {
public interface DrawingProxy extends MoreKeysPanel.Controller {
public void invalidateKey(Key key);
public TextView inflateKeyPreviewText();
- public void showKeyPreview(int keyIndex, PointerTracker tracker);
- public void cancelShowKeyPreview(PointerTracker tracker);
+ public void showKeyPreview(PointerTracker tracker);
public void dismissKeyPreview(PointerTracker tracker);
}
public interface TimerProxy {
- public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker);
- public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker);
+ public void startKeyTypedTimer();
+ public boolean isTyping();
+ public void startKeyRepeatTimer(PointerTracker tracker);
+ public void startLongPressTimer(PointerTracker tracker);
+ public void startLongPressTimer(int code);
public void cancelLongPressTimer();
+ public void startDoubleTapTimer();
+ public boolean isInDoubleTapTimeout();
public void cancelKeyTimers();
public static class Adapter implements TimerProxy {
@Override
- public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ public void startKeyTypedTimer() {}
@Override
- public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ public boolean isTyping() { return false; }
+ @Override
+ public void startKeyRepeatTimer(PointerTracker tracker) {}
+ @Override
+ public void startLongPressTimer(PointerTracker tracker) {}
+ @Override
+ public void startLongPressTimer(int code) {}
@Override
public void cancelLongPressTimer() {}
@Override
+ public void startDoubleTapTimer() {}
+ @Override
+ public boolean isInDoubleTapTimeout() { return false; }
+ @Override
public void cancelKeyTimers() {}
}
}
private static KeyboardSwitcher sKeyboardSwitcher;
- private static boolean sConfigSlidingKeyInputEnabled;
- // Timing constants
- private static int sDelayBeforeKeyRepeatStart;
- private static int sLongPressKeyTimeout;
- private static int sLongPressShiftKeyTimeout;
- private static int sLongPressSpaceKeyTimeout;
- private static int sTouchNoiseThresholdMillis;
+ // Parameters for pointer handling.
+ private static LatinKeyboardView.PointerTrackerParams sParams;
private static int sTouchNoiseThresholdDistanceSquared;
private static final List<PointerTracker> sTrackers = new ArrayList<PointerTracker>();
@@ -111,7 +118,7 @@ public class PointerTracker {
private KeyboardActionListener mListener = EMPTY_LISTENER;
private Keyboard mKeyboard;
- private List<Key> mKeys;
+ private Set<Key> mKeys;
private int mKeyQuarterWidthSquared;
private final TextView mKeyPreviewText;
@@ -119,9 +126,9 @@ public class PointerTracker {
private long mDownTime;
private long mUpTime;
- // The current key index where this pointer is.
- private int mKeyIndex = KeyDetector.NOT_A_KEY;
- // The position where mKeyIndex was recognized for the first time.
+ // The current key where this pointer is.
+ private Key mCurrentKey = null;
+ // The position where the current key was recognized for the first time.
private int mKeyX;
private int mKeyY;
@@ -154,27 +161,23 @@ public class PointerTracker {
private static final KeyboardActionListener EMPTY_LISTENER =
new KeyboardActionListener.Adapter();
- public static void init(boolean hasDistinctMultitouch, Context context) {
+ public static void init(boolean hasDistinctMultitouch) {
if (hasDistinctMultitouch) {
sPointerTrackerQueue = new PointerTrackerQueue();
} else {
sPointerTrackerQueue = null;
}
- final Resources res = context.getResources();
- sConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
- sDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
- sLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout);
- sLongPressShiftKeyTimeout = res.getInteger(R.integer.config_long_press_shift_key_timeout);
- sLongPressSpaceKeyTimeout = res.getInteger(R.integer.config_long_press_space_key_timeout);
- sTouchNoiseThresholdMillis = res.getInteger(R.integer.config_touch_noise_threshold_millis);
- final float touchNoiseThresholdDistance = res.getDimension(
- R.dimen.config_touch_noise_threshold_distance);
- sTouchNoiseThresholdDistanceSquared = (int)(
- touchNoiseThresholdDistance * touchNoiseThresholdDistance);
+ setParameters(LatinKeyboardView.PointerTrackerParams.DEFAULT);
sKeyboardSwitcher = KeyboardSwitcher.getInstance();
}
+ public static void setParameters(LatinKeyboardView.PointerTrackerParams params) {
+ sParams = params;
+ sTouchNoiseThresholdDistanceSquared = (int)(
+ params.mTouchNoiseThresholdDistance * params.mTouchNoiseThresholdDistance);
+ }
+
public static PointerTracker getPointerTracker(final int id, KeyEventHandler handler) {
final List<PointerTracker> trackers = sTrackers;
@@ -207,7 +210,7 @@ public class PointerTracker {
public static void dismissAllKeyPreviews() {
for (final PointerTracker tracker : sTrackers) {
- tracker.setReleasedKeyGraphics(tracker.mKeyIndex);
+ tracker.setReleasedKeyGraphics(tracker.mCurrentKey);
}
}
@@ -227,15 +230,18 @@ public class PointerTracker {
}
// Returns true if keyboard has been changed by this callback.
- private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key, boolean withSliding) {
- final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode);
- if (DEBUG_LISTENER)
- Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding
- + " ignoreModifier=" + ignoreModifierKey);
- if (ignoreModifierKey)
+ private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key) {
+ final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, "onPress : " + KeyDetector.printableCode(key)
+ + " ignoreModifier=" + ignoreModifierKey
+ + " enabled=" + key.isEnabled());
+ }
+ if (ignoreModifierKey) {
return false;
+ }
if (key.isEnabled()) {
- mListener.onPress(key.mCode, withSliding);
+ mListener.onPressKey(key.mCode);
final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
mKeyboardLayoutHasBeenChanged = false;
return keyboardLayoutHasBeenChanged;
@@ -246,35 +252,45 @@ public class PointerTracker {
// Note that we need primaryCode argument because the keyboard may in shifted state and the
// primaryCode is different from {@link Key#mCode}.
private void callListenerOnCodeInput(Key key, int primaryCode, int[] keyCodes, int x, int y) {
- final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode);
- if (DEBUG_LISTENER)
- Log.d(TAG, "onCodeInput: " + keyCodePrintable(primaryCode)
- + " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y
- + " ignoreModifier=" + ignoreModifierKey);
- if (ignoreModifierKey)
+ final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
+ final boolean alterCode = key.altCodeWhileTyping() && mTimerProxy.isTyping();
+ final int code = alterCode ? key.mAltCode : primaryCode;
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, "onCodeInput: " + Keyboard.printableCode(code) + " text=" + key.mOutputText
+ + " codes="+ KeyDetector.printableCodes(keyCodes) + " x=" + x + " y=" + y
+ + " ignoreModifier=" + ignoreModifierKey + " alterCode=" + alterCode
+ + " enabled=" + key.isEnabled());
+ }
+ if (ignoreModifierKey) {
return;
- if (key.isEnabled())
- mListener.onCodeInput(primaryCode, keyCodes, x, y);
- }
-
- private void callListenerOnTextInput(Key key) {
- if (DEBUG_LISTENER)
- Log.d(TAG, "onTextInput: text=" + key.mOutputText);
- if (key.isEnabled())
- mListener.onTextInput(key.mOutputText);
+ }
+ if (key.isEnabled()) {
+ if (code == Keyboard.CODE_OUTPUT_TEXT) {
+ mListener.onTextInput(key.mOutputText);
+ } else if (code != Keyboard.CODE_UNSPECIFIED) {
+ mListener.onCodeInput(code, keyCodes, x, y);
+ }
+ if (!key.altCodeWhileTyping() && !key.isModifier()) {
+ mTimerProxy.startKeyTypedTimer();
+ }
+ }
}
// Note that we need primaryCode argument because the keyboard may in shifted state and the
// primaryCode is different from {@link Key#mCode}.
private void callListenerOnRelease(Key key, int primaryCode, boolean withSliding) {
- final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode);
- if (DEBUG_LISTENER)
- Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding="
- + withSliding + " ignoreModifier=" + ignoreModifierKey);
- if (ignoreModifierKey)
+ final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, "onRelease : " + Keyboard.printableCode(primaryCode)
+ + " sliding=" + withSliding + " ignoreModifier=" + ignoreModifierKey
+ + " enabled="+ key.isEnabled());
+ }
+ if (ignoreModifierKey) {
return;
- if (key.isEnabled())
- mListener.onRelease(primaryCode, withSliding);
+ }
+ if (key.isEnabled()) {
+ mListener.onReleaseKey(primaryCode, withSliding);
+ }
}
private void callListenerOnCancelInput() {
@@ -295,71 +311,69 @@ public class PointerTracker {
return mIsInSlidingKeyInput;
}
- private boolean isValidKeyIndex(int keyIndex) {
- return keyIndex >= 0 && keyIndex < mKeys.size();
- }
-
- public Key getKey(int keyIndex) {
- return isValidKeyIndex(keyIndex) ? mKeys.get(keyIndex) : null;
- }
-
- private static boolean isModifierCode(int primaryCode) {
- return primaryCode == Keyboard.CODE_SHIFT
- || primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
- }
-
- private boolean isModifierInternal(int keyIndex) {
- final Key key = getKey(keyIndex);
- return key == null ? false : isModifierCode(key.mCode);
+ public Key getKey() {
+ return mCurrentKey;
}
public boolean isModifier() {
- return isModifierInternal(mKeyIndex);
- }
-
- private boolean isOnModifierKey(int x, int y) {
- return isModifierInternal(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
+ return mCurrentKey != null && mCurrentKey.isModifier();
}
- public boolean isOnShiftKey(int x, int y) {
- final Key key = getKey(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
- return key != null && key.mCode == Keyboard.CODE_SHIFT;
+ public Key getKeyOn(int x, int y) {
+ return mKeyDetector.getKeyAndNearbyCodes(x, y, null);
}
- public int getKeyIndexOn(int x, int y) {
- return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
- }
-
- private void setReleasedKeyGraphics(int keyIndex) {
+ private void setReleasedKeyGraphics(Key key) {
mDrawingProxy.dismissKeyPreview(this);
- final Key key = getKey(keyIndex);
if (key != null && key.isEnabled()) {
key.onReleased();
mDrawingProxy.invalidateKey(key);
+
+ if (key.isShift()) {
+ for (final Key shiftKey : mKeyboard.mShiftKeys) {
+ if (shiftKey != key) {
+ shiftKey.onReleased();
+ mDrawingProxy.invalidateKey(shiftKey);
+ }
+ }
+ }
+
+ if (key.altCodeWhileTyping()) {
+ final Key altKey = mKeyboard.getKey(key.mAltCode);
+ if (altKey != null) {
+ altKey.onReleased();
+ mDrawingProxy.invalidateKey(altKey);
+ }
+ }
}
}
- private void setPressedKeyGraphics(int keyIndex) {
- final Key key = getKey(keyIndex);
+ private void setPressedKeyGraphics(Key key) {
if (key != null && key.isEnabled()) {
- if (isKeyPreviewRequired(key)) {
- mDrawingProxy.showKeyPreview(keyIndex, this);
+ if (!key.noKeyPreview()) {
+ mDrawingProxy.showKeyPreview(this);
}
key.onPressed();
mDrawingProxy.invalidateKey(key);
- }
- }
- // The modifier key, such as shift key, should not show its key preview.
- private static boolean isKeyPreviewRequired(Key key) {
- final int code = key.mCode;
- // TODO: Stop hard-coding these key codes here, and add a new key attribute of a key.
- if (code == Keyboard.CODE_SPACE || code == Keyboard.CODE_ENTER
- || code == Keyboard.CODE_DELETE || isModifierCode(code)
- || code == Keyboard.CODE_SETTINGS || code == Keyboard.CODE_SHORTCUT) {
- return false;
+ if (key.isShift()) {
+ for (final Key shiftKey : mKeyboard.mShiftKeys) {
+ if (shiftKey != key) {
+ shiftKey.onPressed();
+ mDrawingProxy.invalidateKey(shiftKey);
+ }
+ }
+ }
+
+ if (key.altCodeWhileTyping() && mTimerProxy.isTyping()) {
+ final Key altKey = mKeyboard.getKey(key.mAltCode);
+ if (altKey != null) {
+ // TODO: Show altKey's preview.
+ altKey.onPressed();
+ mDrawingProxy.invalidateKey(altKey);
+ }
+ }
}
- return true;
}
public int getLastX() {
@@ -374,31 +388,31 @@ public class PointerTracker {
return mDownTime;
}
- private int onDownKey(int x, int y, long eventTime) {
+ private Key onDownKey(int x, int y, long eventTime) {
mDownTime = eventTime;
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
}
- private int onMoveKeyInternal(int x, int y) {
+ private Key onMoveKeyInternal(int x, int y) {
mLastX = x;
mLastY = y;
- return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
+ return mKeyDetector.getKeyAndNearbyCodes(x, y, null);
}
- private int onMoveKey(int x, int y) {
+ private Key onMoveKey(int x, int y) {
return onMoveKeyInternal(x, y);
}
- private int onMoveToNewKey(int keyIndex, int x, int y) {
- mKeyIndex = keyIndex;
+ private Key onMoveToNewKey(Key newKey, int x, int y) {
+ mCurrentKey = newKey;
mKeyX = x;
mKeyY = y;
- return keyIndex;
+ return newKey;
}
- private int onUpKey(int x, int y, long eventTime) {
+ private Key onUpKey(int x, int y, long eventTime) {
mUpTime = eventTime;
- mKeyIndex = KeyDetector.NOT_A_KEY;
+ mCurrentKey = null;
return onMoveKeyInternal(x, y);
}
@@ -432,7 +446,7 @@ public class PointerTracker {
setKeyDetectorInner(handler.getKeyDetector());
// Naive up-to-down noise filter.
final long deltaT = eventTime - mUpTime;
- if (deltaT < sTouchNoiseThresholdMillis) {
+ if (deltaT < sParams.mTouchNoiseThresholdTime) {
final int dx = x - mLastX;
final int dy = y - mLastY;
final int distanceSquared = (dx * dx + dy * dy);
@@ -447,7 +461,8 @@ public class PointerTracker {
final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
- if (isOnModifierKey(x, y)) {
+ final Key key = getKeyOn(x, y);
+ if (key != null && key.isModifier()) {
// Before processing a down event of modifier key, all pointers already being
// tracked should be released.
queue.releaseAllPointers(eventTime);
@@ -458,32 +473,35 @@ public class PointerTracker {
}
private void onDownEventInternal(int x, int y, long eventTime) {
- int keyIndex = onDownKey(x, y, eventTime);
+ Key key = onDownKey(x, y, eventTime);
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
// from modifier key, or 3) this pointer's KeyDetector always allows sliding input.
- mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
+ mIsAllowedSlidingKeyInput = sParams.mSlidingKeyInputEnabled
+ || (key != null && key.isModifier())
|| mKeyDetector.alwaysAllowsSlidingInput();
mKeyboardLayoutHasBeenChanged = false;
mKeyAlreadyProcessed = false;
mIsRepeatableKey = false;
mIsInSlidingKeyInput = false;
mIgnoreModifierKey = false;
- if (isValidKeyIndex(keyIndex)) {
+ if (key != null) {
// This onPress call may have changed keyboard layout. Those cases are detected at
- // {@link #setKeyboard}. In those cases, we should update keyIndex according to the new
+ // {@link #setKeyboard}. In those cases, we should update key according to the new
// keyboard layout.
- if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), false))
- keyIndex = onDownKey(x, y, eventTime);
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(key)) {
+ key = onDownKey(x, y, eventTime);
+ }
- startRepeatKey(keyIndex);
- startLongPressTimer(keyIndex);
- setPressedKeyGraphics(keyIndex);
+ startRepeatKey(key);
+ startLongPressTimer(key);
+ setPressedKeyGraphics(key);
}
}
private void startSlidingKeyInput(Key key) {
- if (!mIsInSlidingKeyInput)
- mIgnoreModifierKey = isModifierCode(key.mCode);
+ if (!mIsInSlidingKeyInput) {
+ mIgnoreModifierKey = key.isModifier();
+ }
mIsInSlidingKeyInput = true;
}
@@ -495,39 +513,40 @@ public class PointerTracker {
final int lastX = mLastX;
final int lastY = mLastY;
- final int oldKeyIndex = mKeyIndex;
- final Key oldKey = getKey(oldKeyIndex);
- int keyIndex = onMoveKey(x, y);
- if (isValidKeyIndex(keyIndex)) {
+ final Key oldKey = mCurrentKey;
+ Key key = onMoveKey(x, y);
+ if (key != null) {
if (oldKey == null) {
// The pointer has been slid in to the new key, but the finger was not on any keys.
// In this case, we must call onPress() to notify that the new key is being pressed.
// This onPress call may have changed keyboard layout. Those cases are detected at
- // {@link #setKeyboard}. In those cases, we should update keyIndex according to the
+ // {@link #setKeyboard}. In those cases, we should update key according to the
// new keyboard layout.
- if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), true))
- keyIndex = onMoveKey(x, y);
- onMoveToNewKey(keyIndex, x, y);
- startLongPressTimer(keyIndex);
- setPressedKeyGraphics(keyIndex);
- } else if (isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) {
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(key)) {
+ key = onMoveKey(x, y);
+ }
+ onMoveToNewKey(key, x, y);
+ startLongPressTimer(key);
+ setPressedKeyGraphics(key);
+ } else if (isMajorEnoughMoveToBeOnNewKey(x, y, key)) {
// The pointer has been slid in to the new key from the previous key, we must call
// onRelease() first to notify that the previous key has been released, then call
// onPress() to notify that the new key is being pressed.
- setReleasedKeyGraphics(oldKeyIndex);
+ setReleasedKeyGraphics(oldKey);
callListenerOnRelease(oldKey, oldKey.mCode, true);
startSlidingKeyInput(oldKey);
mTimerProxy.cancelKeyTimers();
- startRepeatKey(keyIndex);
+ startRepeatKey(key);
if (mIsAllowedSlidingKeyInput) {
// This onPress call may have changed keyboard layout. Those cases are detected
- // at {@link #setKeyboard}. In those cases, we should update keyIndex according
+ // at {@link #setKeyboard}. In those cases, we should update key according
// to the new keyboard layout.
- if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), true))
- keyIndex = onMoveKey(x, y);
- onMoveToNewKey(keyIndex, x, y);
- startLongPressTimer(keyIndex);
- setPressedKeyGraphics(keyIndex);
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(key)) {
+ key = onMoveKey(x, y);
+ }
+ onMoveToNewKey(key, x, y);
+ startLongPressTimer(key);
+ setPressedKeyGraphics(key);
} else {
// HACK: On some devices, quick successive touches may be translated to sudden
// move by touch panel firmware. This hack detects the case and translates the
@@ -543,20 +562,20 @@ public class PointerTracker {
onDownEventInternal(x, y, eventTime);
} else {
mKeyAlreadyProcessed = true;
- setReleasedKeyGraphics(oldKeyIndex);
+ setReleasedKeyGraphics(oldKey);
}
}
}
} else {
- if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) {
+ if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, key)) {
// The pointer has been slid out from the previous key, we must call onRelease() to
// notify that the previous key has been released.
- setReleasedKeyGraphics(oldKeyIndex);
+ setReleasedKeyGraphics(oldKey);
callListenerOnRelease(oldKey, oldKey.mCode, true);
startSlidingKeyInput(oldKey);
mTimerProxy.cancelLongPressTimer();
if (mIsAllowedSlidingKeyInput) {
- onMoveToNewKey(keyIndex, x, y);
+ onMoveToNewKey(key, x, y);
} else {
mKeyAlreadyProcessed = true;
}
@@ -570,7 +589,7 @@ public class PointerTracker {
final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
- if (isModifier()) {
+ if (mCurrentKey != null && mCurrentKey.isModifier()) {
// Before processing an up event of modifier key, all pointers already being
// tracked should be released.
queue.releaseAllPointersExcept(this, eventTime);
@@ -594,7 +613,6 @@ public class PointerTracker {
private void onUpEventInternal(int x, int y, long eventTime) {
mTimerProxy.cancelKeyTimers();
- mDrawingProxy.cancelShowKeyPreview(this);
mIsInSlidingKeyInput = false;
final int keyX, keyY;
if (isMajorEnoughMoveToBeOnNewKey(x, y, onMoveKey(x, y))) {
@@ -605,8 +623,8 @@ public class PointerTracker {
keyX = mKeyX;
keyY = mKeyY;
}
- final int keyIndex = onUpKey(keyX, keyY, eventTime);
- setReleasedKeyGraphics(keyIndex);
+ final Key key = onUpKey(keyX, keyY, eventTime);
+ setReleasedKeyGraphics(key);
if (mIsShowingMoreKeysPanel) {
mDrawingProxy.dismissMoreKeysPanel();
mIsShowingMoreKeysPanel = false;
@@ -614,19 +632,19 @@ public class PointerTracker {
if (mKeyAlreadyProcessed)
return;
if (!mIsRepeatableKey) {
- detectAndSendKey(keyIndex, keyX, keyY);
+ detectAndSendKey(key, keyX, keyY);
}
}
- public void onShowMoreKeysPanel(int x, int y, long eventTime, KeyEventHandler handler) {
+ public void onShowMoreKeysPanel(int x, int y, KeyEventHandler handler) {
onLongPressed();
- onDownEvent(x, y, eventTime, handler);
+ onDownEvent(x, y, SystemClock.uptimeMillis(), handler);
mIsShowingMoreKeysPanel = true;
}
public void onLongPressed() {
mKeyAlreadyProcessed = true;
- setReleasedKeyGraphics(mKeyIndex);
+ setReleasedKeyGraphics(mCurrentKey);
final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
queue.remove(this);
@@ -647,8 +665,7 @@ public class PointerTracker {
private void onCancelEventInternal() {
mTimerProxy.cancelKeyTimers();
- mDrawingProxy.cancelShowKeyPreview(this);
- setReleasedKeyGraphics(mKeyIndex);
+ setReleasedKeyGraphics(mCurrentKey);
mIsInSlidingKeyInput = false;
if (mIsShowingMoreKeysPanel) {
mDrawingProxy.dismissMoreKeysPanel();
@@ -656,108 +673,71 @@ public class PointerTracker {
}
}
- private void startRepeatKey(int keyIndex) {
- final Key key = getKey(keyIndex);
- if (key != null && key.mRepeatable) {
- onRepeatKey(keyIndex);
- mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, keyIndex, this);
+ private void startRepeatKey(Key key) {
+ if (key != null && key.isRepeatable()) {
+ onRepeatKey(key);
+ mTimerProxy.startKeyRepeatTimer(this);
mIsRepeatableKey = true;
} else {
mIsRepeatableKey = false;
}
}
- public void onRepeatKey(int keyIndex) {
- Key key = getKey(keyIndex);
+ public void onRepeatKey(Key key) {
if (key != null) {
- detectAndSendKey(keyIndex, key.mX, key.mY);
+ detectAndSendKey(key, key.mX, key.mY);
}
}
- private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, int newKey) {
+ private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, Key newKey) {
if (mKeys == null || mKeyDetector == null)
throw new NullPointerException("keyboard and/or key detector not set");
- int curKey = mKeyIndex;
+ Key curKey = mCurrentKey;
if (newKey == curKey) {
return false;
- } else if (isValidKeyIndex(curKey)) {
- return mKeys.get(curKey).squaredDistanceToEdge(x, y)
+ } else if (curKey != null) {
+ return curKey.squaredDistanceToEdge(x, y)
>= mKeyDetector.getKeyHysteresisDistanceSquared();
} else {
return true;
}
}
- private void startLongPressTimer(int keyIndex) {
- Key key = getKey(keyIndex);
- if (key == null) return;
- if (key.mCode == Keyboard.CODE_SHIFT) {
- if (sLongPressShiftKeyTimeout > 0) {
- mTimerProxy.startLongPressTimer(sLongPressShiftKeyTimeout, keyIndex, this);
- }
- } else if (key.mCode == Keyboard.CODE_SPACE) {
- if (sLongPressSpaceKeyTimeout > 0) {
- mTimerProxy.startLongPressTimer(sLongPressSpaceKeyTimeout, keyIndex, this);
- }
- } else if (key.hasUppercaseLetter() && mKeyboard.isManualTemporaryUpperCase()) {
- // We need not start long press timer on the key which has manual temporary upper case
- // code defined and the keyboard is in manual temporary upper case mode.
- return;
- } else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
- // We use longer timeout for sliding finger input started from the symbols mode key.
- mTimerProxy.startLongPressTimer(sLongPressKeyTimeout * 3, keyIndex, this);
- } else {
- mTimerProxy.startLongPressTimer(sLongPressKeyTimeout, keyIndex, this);
+ private void startLongPressTimer(Key key) {
+ if (key != null && key.isLongPressEnabled()) {
+ mTimerProxy.startLongPressTimer(this);
}
}
- private void detectAndSendKey(int index, int x, int y) {
- final Key key = getKey(index);
+ private void detectAndSendKey(Key key, int x, int y) {
if (key == null) {
callListenerOnCancelInput();
return;
}
- if (key.mOutputText != null) {
- callListenerOnTextInput(key);
- callListenerOnRelease(key, key.mCode, false);
- } else {
- int code = key.mCode;
- final int[] codes = mKeyDetector.newCodeArray();
- mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
-
- // If keyboard is in manual temporary upper case state and key has manual temporary
- // uppercase letter as key hint letter, alternate character code should be sent.
- if (mKeyboard.isManualTemporaryUpperCase() && key.hasUppercaseLetter()) {
- code = key.mHintLabel.charAt(0);
- codes[0] = code;
- }
- // Swap the first and second values in the codes array if the primary code is not the
- // first value but the second value in the array. This happens when key debouncing is
- // in effect.
- if (codes.length >= 2 && codes[0] != code && codes[1] == code) {
- codes[1] = codes[0];
- codes[0] = code;
- }
- callListenerOnCodeInput(key, code, codes, x, y);
- callListenerOnRelease(key, code, false);
+ int code = key.mCode;
+ final int[] codes = mKeyDetector.newCodeArray();
+ mKeyDetector.getKeyAndNearbyCodes(x, y, codes);
+
+ // Swap the first and second values in the codes array if the primary code is not the
+ // first value but the second value in the array. This happens when key debouncing is
+ // in effect.
+ if (codes.length >= 2 && codes[0] != code && codes[1] == code) {
+ codes[1] = codes[0];
+ codes[0] = code;
}
+ callListenerOnCodeInput(key, code, codes, x, y);
+ callListenerOnRelease(key, code, false);
}
private long mPreviousEventTime;
private void printTouchEvent(String title, int x, int y, long eventTime) {
- final int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
- final Key key = getKey(keyIndex);
- final String code = (key == null) ? "----" : keyCodePrintable(key.mCode);
+ final Key key = mKeyDetector.getKeyAndNearbyCodes(x, y, null);
+ final String code = KeyDetector.printableCode(key);
final long delta = eventTime - mPreviousEventTime;
- Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %3d(%s)", title,
- (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, keyIndex, code));
+ Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %s", title,
+ (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, code));
mPreviousEventTime = eventTime;
}
-
- private static String keyCodePrintable(int primaryCode) {
- final String modifier = isModifierCode(primaryCode) ? " modifier" : "";
- return String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode) + modifier;
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 2a25d0ca7..41e7ef435 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -18,19 +18,22 @@ package com.android.inputmethod.keyboard;
import android.graphics.Rect;
-import com.android.inputmethod.keyboard.internal.KeyboardParams.TouchPositionCorrection;
+import com.android.inputmethod.keyboard.Keyboard.Params.TouchPositionCorrection;
import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class ProximityInfo {
public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
/** Number of key widths from current touch point to search for nearest keys. */
private static float SEARCH_DISTANCE = 1.2f;
- private static final int[] EMPTY_INT_ARRAY = new int[0];
+ private static final Key[] EMPTY_KEY_ARRAY = new Key[0];
private final int mKeyHeight;
private final int mGridWidth;
@@ -41,10 +44,11 @@ public class ProximityInfo {
// TODO: Find a proper name for mKeyboardMinWidth
private final int mKeyboardMinWidth;
private final int mKeyboardHeight;
- private final int[][] mGridNeighbors;
+ private final Key[][] mGridNeighbors;
ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
- int keyHeight, List<Key> keys, TouchPositionCorrection touchPositionCorrection) {
+ int keyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection,
+ Map<Integer, List<Integer>> additionalProximityChars) {
mGridWidth = gridWidth;
mGridHeight = gridHeight;
mGridSize = mGridWidth * mGridHeight;
@@ -53,49 +57,51 @@ public class ProximityInfo {
mKeyboardMinWidth = minWidth;
mKeyboardHeight = height;
mKeyHeight = keyHeight;
- mGridNeighbors = new int[mGridSize][];
+ mGridNeighbors = new Key[mGridSize][];
if (minWidth == 0 || height == 0) {
- // No proximity required. Keyboard might be mini keyboard.
+ // No proximity required. Keyboard might be more keys keyboard.
return;
}
- computeNearestNeighbors(keyWidth, keys, touchPositionCorrection);
+ computeNearestNeighbors(keyWidth, keys, touchPositionCorrection, additionalProximityChars);
}
public static ProximityInfo createDummyProximityInfo() {
- return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key>emptyList(), null);
+ return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key> emptySet(),
+ null, Collections.<Integer, List<Integer>> emptyMap());
}
- public static ProximityInfo createSpellCheckerProximityInfo() {
+ public static ProximityInfo createSpellCheckerProximityInfo(final int[] proximity) {
final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo();
spellCheckerProximityInfo.mNativeProximityInfo =
spellCheckerProximityInfo.setProximityInfoNative(
- SpellCheckerProximityInfo.ROW_SIZE,
- 480, 300, 10, 3, SpellCheckerProximityInfo.PROXIMITY,
- 0, null, null, null, null, null, null, null, null);
+ SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, proximity, 0,
+ null, null, null, null, null, null, null, null);
return spellCheckerProximityInfo;
}
- private int mNativeProximityInfo;
+ private long mNativeProximityInfo;
static {
Utils.loadNativeLibrary();
}
- private native int setProximityInfoNative(int maxProximityCharsSize, int displayWidth,
+
+ private native long setProximityInfoNative(int maxProximityCharsSize, int displayWidth,
int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray,
int keyCount, int[] keyXCoordinates, int[] keyYCoordinates,
int[] keyWidths, int[] keyHeights, int[] keyCharCodes,
float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii);
- private native void releaseProximityInfoNative(int nativeProximityInfo);
- private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
- int keyboardHeight, List<Key> keys,
+ private native void releaseProximityInfoNative(long nativeProximityInfo);
+
+ private final void setProximityInfo(Key[][] gridNeighborKeys, int keyboardWidth,
+ int keyboardHeight, Set<Key> keys,
TouchPositionCorrection touchPositionCorrection) {
- int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
+ final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
for (int i = 0; i < mGridSize; ++i) {
- final int proximityCharsLength = gridNeighborKeyIndexes[i].length;
+ final int proximityCharsLength = gridNeighborKeys[i].length;
for (int j = 0; j < proximityCharsLength; ++j) {
proximityCharsArray[i * MAX_PROXIMITY_CHARS_SIZE + j] =
- keys.get(gridNeighborKeyIndexes[i][j]).mCode;
+ gridNeighborKeys[i][j].mCode;
}
}
final int keyCount = keys.size();
@@ -104,25 +110,45 @@ public class ProximityInfo {
final int[] keyWidths = new int[keyCount];
final int[] keyHeights = new int[keyCount];
final int[] keyCharCodes = new int[keyCount];
- for (int i = 0; i < keyCount; ++i) {
- final Key key = keys.get(i);
+ final float[] sweetSpotCenterXs;
+ final float[] sweetSpotCenterYs;
+ final float[] sweetSpotRadii;
+ final boolean calculateSweetSpotParams;
+ if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
+ sweetSpotCenterXs = new float[keyCount];
+ sweetSpotCenterYs = new float[keyCount];
+ sweetSpotRadii = new float[keyCount];
+ calculateSweetSpotParams = true;
+ } else {
+ sweetSpotCenterXs = sweetSpotCenterYs = sweetSpotRadii = null;
+ calculateSweetSpotParams = false;
+ }
+
+ int i = 0;
+ for (final Key key : keys) {
keyXCoordinates[i] = key.mX;
keyYCoordinates[i] = key.mY;
keyWidths[i] = key.mWidth;
keyHeights[i] = key.mHeight;
keyCharCodes[i] = key.mCode;
- }
-
- float[] sweetSpotCenterXs = null;
- float[] sweetSpotCenterYs = null;
- float[] sweetSpotRadii = null;
-
- if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
- sweetSpotCenterXs = new float[keyCount];
- sweetSpotCenterYs = new float[keyCount];
- sweetSpotRadii = new float[keyCount];
- calculateSweetSpot(keys, touchPositionCorrection,
- sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
+ if (calculateSweetSpotParams) {
+ final Rect hitBox = key.mHitBox;
+ final int row = hitBox.top / mKeyHeight;
+ if (row < touchPositionCorrection.mRadii.length) {
+ final float hitBoxCenterX = (hitBox.left + hitBox.right) * 0.5f;
+ final float hitBoxCenterY = (hitBox.top + hitBox.bottom) * 0.5f;
+ final float hitBoxWidth = hitBox.right - hitBox.left;
+ final float hitBoxHeight = hitBox.bottom - hitBox.top;
+ final float x = touchPositionCorrection.mXs[row];
+ final float y = touchPositionCorrection.mYs[row];
+ final float radius = touchPositionCorrection.mRadii[row];
+ sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth;
+ sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight;
+ sweetSpotRadii[i] = radius * (float) Math.sqrt(
+ hitBoxWidth * hitBoxWidth + hitBoxHeight * hitBoxHeight);
+ }
+ }
+ i++;
}
mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE,
@@ -131,33 +157,7 @@ public class ProximityInfo {
sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
}
- private void calculateSweetSpot(List<Key> keys, TouchPositionCorrection touchPositionCorrection,
- float[] sweetSpotCenterXs, float[] sweetSpotCenterYs, float[] sweetSpotRadii) {
- final int keyCount = keys.size();
- final float[] xs = touchPositionCorrection.mXs;
- final float[] ys = touchPositionCorrection.mYs;
- final float[] radii = touchPositionCorrection.mRadii;
- for (int i = 0; i < keyCount; ++i) {
- final Key key = keys.get(i);
- final Rect hitBox = key.mHitBox;
- final int row = hitBox.top / mKeyHeight;
- if (row < radii.length) {
- final float hitBoxCenterX = (hitBox.left + hitBox.right) * 0.5f;
- final float hitBoxCenterY = (hitBox.top + hitBox.bottom) * 0.5f;
- final float hitBoxWidth = hitBox.right - hitBox.left;
- final float hitBoxHeight = hitBox.bottom - hitBox.top;
- final float x = xs[row];
- final float y = ys[row];
- final float radius = radii[row];
- sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth;
- sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight;
- sweetSpotRadii[i] = radius
- * (float)Math.sqrt(hitBoxWidth * hitBoxWidth + hitBoxHeight * hitBoxHeight);
- }
- }
- }
-
- public int getNativeProximityInfo() {
+ public long getNativeProximityInfo() {
return mNativeProximityInfo;
}
@@ -173,12 +173,17 @@ public class ProximityInfo {
}
}
- private void computeNearestNeighbors(int defaultWidth, List<Key> keys,
- TouchPositionCorrection touchPositionCorrection) {
+ private void computeNearestNeighbors(int defaultWidth, Set<Key> keys,
+ TouchPositionCorrection touchPositionCorrection,
+ Map<Integer, List<Integer>> additionalProximityChars) {
+ final Map<Integer, Key> keyCodeMap = new HashMap<Integer, Key>();
+ for (final Key key : keys) {
+ keyCodeMap.put(key.mCode, key);
+ }
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
final int threshold = thresholdBase * thresholdBase;
// Round-up so we don't have any pixels outside the grid
- final int[] indices = new int[keys.size()];
+ final Key[] neighborKeys = new Key[keys.size()];
final int gridWidth = mGridWidth * mCellWidth;
final int gridHeight = mGridHeight * mCellHeight;
for (int x = 0; x < gridWidth; x += mCellWidth) {
@@ -186,31 +191,51 @@ public class ProximityInfo {
final int centerX = x + mCellWidth / 2;
final int centerY = y + mCellHeight / 2;
int count = 0;
- for (int i = 0; i < keys.size(); i++) {
- final Key key = keys.get(i);
+ for (final Key key : keys) {
if (key.isSpacer()) continue;
- if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
- indices[count++] = i;
+ if (key.squaredDistanceToEdge(centerX, centerY) < threshold) {
+ neighborKeys[count++] = key;
+ }
+ }
+ int currentCodesSize = count;
+ for (int i = 0; i < currentCodesSize; ++i) {
+ final int c = neighborKeys[i].mCode;
+ final List<Integer> additionalChars = additionalProximityChars.get(c);
+ if (additionalChars == null || additionalChars.size() == 0) {
+ continue;
+ }
+ for (int j = 0; j < additionalChars.size(); ++j) {
+ final int additionalChar = additionalChars.get(j);
+ boolean contains = false;
+ for (int k = 0; k < count; ++k) {
+ if(additionalChar == neighborKeys[k].mCode) {
+ contains = true;
+ break;
+ }
+ }
+ if (!contains) {
+ neighborKeys[count++] = keyCodeMap.get(additionalChar);
+ }
+ }
}
- final int[] cell = new int[count];
- System.arraycopy(indices, 0, cell, 0, count);
- mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
+ mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] =
+ Arrays.copyOfRange(neighborKeys, 0, count);
}
}
setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys,
touchPositionCorrection);
}
- public int[] getNearestKeys(int x, int y) {
+ public Key[] getNearestKeys(int x, int y) {
if (mGridNeighbors == null) {
- return EMPTY_INT_ARRAY;
+ return EMPTY_KEY_ARRAY;
}
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
- int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
+ int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
if (index < mGridSize) {
return mGridNeighbors[index];
}
}
- return EMPTY_INT_ARRAY;
+ return EMPTY_KEY_ARRAY;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java
index 28a53cedc..5712df1fc 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java
@@ -18,29 +18,27 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
+public class AlphabetShiftState {
+ private static final String TAG = AlphabetShiftState.class.getSimpleName();
+ private static final boolean DEBUG = false;
-public class KeyboardShiftState {
- private static final String TAG = KeyboardShiftState.class.getSimpleName();
- private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
-
- private static final int NORMAL = 0;
+ private static final int UNSHIFTED = 0;
private static final int MANUAL_SHIFTED = 1;
private static final int MANUAL_SHIFTED_FROM_AUTO = 2;
- private static final int AUTO_SHIFTED = 3;
+ private static final int AUTOMATIC_SHIFTED = 3;
private static final int SHIFT_LOCKED = 4;
private static final int SHIFT_LOCK_SHIFTED = 5;
- private int mState = NORMAL;
+ private int mState = UNSHIFTED;
- public boolean setShifted(boolean newShiftState) {
+ public void setShifted(boolean newShiftState) {
final int oldState = mState;
if (newShiftState) {
switch (oldState) {
- case NORMAL:
+ case UNSHIFTED:
mState = MANUAL_SHIFTED;
break;
- case AUTO_SHIFTED:
+ case AUTOMATIC_SHIFTED:
mState = MANUAL_SHIFTED_FROM_AUTO;
break;
case SHIFT_LOCKED:
@@ -51,8 +49,8 @@ public class KeyboardShiftState {
switch (oldState) {
case MANUAL_SHIFTED:
case MANUAL_SHIFTED_FROM_AUTO:
- case AUTO_SHIFTED:
- mState = NORMAL;
+ case AUTOMATIC_SHIFTED:
+ mState = UNSHIFTED;
break;
case SHIFT_LOCK_SHIFTED:
mState = SHIFT_LOCKED;
@@ -61,42 +59,36 @@ public class KeyboardShiftState {
}
if (DEBUG)
Log.d(TAG, "setShifted(" + newShiftState + "): " + toString(oldState) + " > " + this);
- return mState != oldState;
}
public void setShiftLocked(boolean newShiftLockState) {
final int oldState = mState;
if (newShiftLockState) {
switch (oldState) {
- case NORMAL:
+ case UNSHIFTED:
case MANUAL_SHIFTED:
case MANUAL_SHIFTED_FROM_AUTO:
- case AUTO_SHIFTED:
+ case AUTOMATIC_SHIFTED:
mState = SHIFT_LOCKED;
break;
}
} else {
- switch (oldState) {
- case SHIFT_LOCKED:
- case SHIFT_LOCK_SHIFTED:
- mState = NORMAL;
- break;
- }
+ mState = UNSHIFTED;
}
if (DEBUG)
Log.d(TAG, "setShiftLocked(" + newShiftLockState + "): " + toString(oldState)
+ " > " + this);
}
- public void setAutomaticTemporaryUpperCase() {
+ public void setAutomaticShifted() {
final int oldState = mState;
- mState = AUTO_SHIFTED;
+ mState = AUTOMATIC_SHIFTED;
if (DEBUG)
- Log.d(TAG, "setAutomaticTemporaryUpperCase: " + toString(oldState) + " > " + this);
+ Log.d(TAG, "setAutomaticShifted: " + toString(oldState) + " > " + this);
}
public boolean isShiftedOrShiftLocked() {
- return mState != NORMAL;
+ return mState != UNSHIFTED;
}
public boolean isShiftLocked() {
@@ -107,16 +99,16 @@ public class KeyboardShiftState {
return mState == SHIFT_LOCK_SHIFTED;
}
- public boolean isAutomaticTemporaryUpperCase() {
- return mState == AUTO_SHIFTED;
+ public boolean isAutomaticShifted() {
+ return mState == AUTOMATIC_SHIFTED;
}
- public boolean isManualTemporaryUpperCase() {
+ public boolean isManualShifted() {
return mState == MANUAL_SHIFTED || mState == MANUAL_SHIFTED_FROM_AUTO
|| mState == SHIFT_LOCK_SHIFTED;
}
- public boolean isManualTemporaryUpperCaseFromAuto() {
+ public boolean isManualShiftedFromAutomaticShifted() {
return mState == MANUAL_SHIFTED_FROM_AUTO;
}
@@ -127,13 +119,13 @@ public class KeyboardShiftState {
private static String toString(int state) {
switch (state) {
- case NORMAL: return "NORMAL";
+ case UNSHIFTED: return "UNSHIFTED";
case MANUAL_SHIFTED: return "MANUAL_SHIFTED";
case MANUAL_SHIFTED_FROM_AUTO: return "MANUAL_SHIFTED_FROM_AUTO";
- case AUTO_SHIFTED: return "AUTO_SHIFTED";
+ case AUTOMATIC_SHIFTED: return "AUTOMATIC_SHIFTED";
case SHIFT_LOCKED: return "SHIFT_LOCKED";
case SHIFT_LOCK_SHIFTED: return "SHIFT_LOCK_SHIFTED";
- default: return "UKNOWN";
+ default: return "UNKNOWN";
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
new file mode 100644
index 000000000..1626a140b
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2010 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 android.content.res.Resources;
+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.Utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * String parser of moreKeys attribute of Key.
+ * The string is comma separated texts each of which represents one "more key".
+ * - String resource can be embedded into specification @string/name. This is done before parsing
+ * comma.
+ * 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)
+ * 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.
+ */
+public class KeySpecParser {
+ private static final boolean DEBUG = LatinImeLogger.sDBG;
+
+ private static final int MAX_STRING_REFERENCE_INDIRECTION = 10;
+
+ // Constants for parsing.
+ private static int COMMA = ',';
+ private static final char ESCAPE_CHAR = '\\';
+ private static final char PREFIX_AT = '@';
+ private static final char SUFFIX_SLASH = '/';
+ 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 ADDITIONAL_MORE_KEY_MARKER = "%";
+
+ private KeySpecParser() {
+ // Intentional empty constructor for utility class.
+ }
+
+ private static boolean hasIcon(String moreKeySpec) {
+ if (moreKeySpec.startsWith(PREFIX_ICON)) {
+ final int end = indexOfLabelEnd(moreKeySpec, 0);
+ if (end > 0) {
+ return true;
+ }
+ throw new KeySpecParserError("outputText or code not specified: " + moreKeySpec);
+ }
+ return false;
+ }
+
+ private static boolean hasCode(String moreKeySpec) {
+ final int end = indexOfLabelEnd(moreKeySpec, 0);
+ if (end > 0 && end + 1 < moreKeySpec.length()
+ && moreKeySpec.substring(end + 1).startsWith(PREFIX_CODE)) {
+ return true;
+ }
+ return false;
+ }
+
+ private static String parseEscape(String text) {
+ if (text.indexOf(ESCAPE_CHAR) < 0) {
+ return text;
+ }
+ final int length = text.length();
+ final StringBuilder sb = new StringBuilder();
+ for (int pos = 0; pos < length; pos++) {
+ final char c = text.charAt(pos);
+ if (c == ESCAPE_CHAR && pos + 1 < length) {
+ // Skip escape char
+ pos++;
+ sb.append(text.charAt(pos));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static int indexOfLabelEnd(String moreKeySpec, int start) {
+ if (moreKeySpec.indexOf(ESCAPE_CHAR, start) < 0) {
+ final int end = moreKeySpec.indexOf(LABEL_END, start);
+ if (end == 0) {
+ throw new KeySpecParserError(LABEL_END + " at " + start + ": " + moreKeySpec);
+ }
+ return end;
+ }
+ final int length = moreKeySpec.length();
+ for (int pos = start; pos < length; pos++) {
+ final char c = moreKeySpec.charAt(pos);
+ if (c == ESCAPE_CHAR && pos + 1 < length) {
+ // Skip escape char
+ pos++;
+ } else if (c == LABEL_END) {
+ return pos;
+ }
+ }
+ return -1;
+ }
+
+ public static String getLabel(String moreKeySpec) {
+ if (hasIcon(moreKeySpec)) {
+ return null;
+ }
+ final int end = indexOfLabelEnd(moreKeySpec, 0);
+ final String label = (end > 0) ? parseEscape(moreKeySpec.substring(0, end))
+ : parseEscape(moreKeySpec);
+ if (TextUtils.isEmpty(label)) {
+ throw new KeySpecParserError("Empty label: " + moreKeySpec);
+ }
+ return label;
+ }
+
+ private static String getOutputTextInternal(String moreKeySpec) {
+ final int end = indexOfLabelEnd(moreKeySpec, 0);
+ if (end <= 0) {
+ return null;
+ }
+ if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0) {
+ throw new KeySpecParserError("Multiple " + LABEL_END + ": " + moreKeySpec);
+ }
+ return parseEscape(moreKeySpec.substring(end + /* LABEL_END */1));
+ }
+
+ public static String getOutputText(String moreKeySpec) {
+ if (hasCode(moreKeySpec)) {
+ return null;
+ }
+ final String outputText = getOutputTextInternal(moreKeySpec);
+ if (outputText != null) {
+ if (Utils.codePointCount(outputText) == 1) {
+ // If output text is one code point, it should be treated as a code.
+ // See {@link #getCode(Resources, String)}.
+ return null;
+ }
+ if (!TextUtils.isEmpty(outputText)) {
+ return outputText;
+ }
+ throw new KeySpecParserError("Empty outputText: " + moreKeySpec);
+ }
+ final String label = getLabel(moreKeySpec);
+ if (label == null) {
+ throw new KeySpecParserError("Empty label: " + moreKeySpec);
+ }
+ // Code is automatically generated for one letter label. See {@link getCode()}.
+ return (Utils.codePointCount(label) == 1) ? null : label;
+ }
+
+ public static int getCode(Resources res, String moreKeySpec) {
+ 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;
+ }
+ final String outputText = getOutputTextInternal(moreKeySpec);
+ if (outputText != null) {
+ // If output text is one code point, it should be treated as a code.
+ // See {@link #getOutputText(String)}.
+ if (Utils.codePointCount(outputText) == 1) {
+ return outputText.codePointAt(0);
+ }
+ return Keyboard.CODE_OUTPUT_TEXT;
+ }
+ final String label = getLabel(moreKeySpec);
+ // Code is automatically generated for one letter label.
+ if (Utils.codePointCount(label) == 1) {
+ return label.codePointAt(0);
+ }
+ return Keyboard.CODE_OUTPUT_TEXT;
+ }
+
+ public 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);
+ return KeyboardIconsSet.getIconId(name);
+ }
+ return KeyboardIconsSet.ICON_UNDEFINED;
+ }
+
+ public static String[] insertAddtionalMoreKeys(String[] moreKeys, String[] additionalMoreKeys) {
+ final int moreKeysCount = (moreKeys != null) ? moreKeys.length : 0;
+ final int additionalCount = (additionalMoreKeys != null) ? additionalMoreKeys.length : 0;
+ ArrayList<String> out = null;
+ int additionalIndex = 0;
+ for (int moreKeyIndex = 0; moreKeyIndex < moreKeysCount; moreKeyIndex++) {
+ final String moreKeySpec = moreKeys[moreKeyIndex];
+ if (moreKeySpec.equals(ADDITIONAL_MORE_KEY_MARKER)) {
+ if (additionalIndex < additionalCount) {
+ // Replace '%' marker with additional more key specification.
+ final String additionalMoreKey = additionalMoreKeys[additionalIndex];
+ if (out != null) {
+ out.add(additionalMoreKey);
+ } else {
+ moreKeys[moreKeyIndex] = additionalMoreKey;
+ }
+ additionalIndex++;
+ } else {
+ // Filter out excessive '%' marker.
+ if (out == null) {
+ out = new ArrayList<String>(moreKeyIndex);
+ for (int i = 0; i < moreKeyIndex; i++) {
+ out.add(moreKeys[i]);
+ }
+ }
+ }
+ } else {
+ if (out != null) {
+ out.add(moreKeySpec);
+ }
+ }
+ }
+ if (additionalCount > 0 && additionalIndex == 0) {
+ // No '%' marker is found in more keys.
+ // Insert all additional more keys to the head of more keys.
+ if (DEBUG && out != null) {
+ throw new RuntimeException("Internal logic error:"
+ + " moreKeys=" + Arrays.toString(moreKeys)
+ + " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
+ }
+ out = new ArrayList<String>(additionalCount + moreKeysCount);
+ for (int i = additionalIndex; i < additionalCount; i++) {
+ out.add(additionalMoreKeys[i]);
+ }
+ for (int i = 0; i < moreKeysCount; i++) {
+ out.add(moreKeys[i]);
+ }
+ } else if (additionalIndex < additionalCount) {
+ // The number of '%' markers are less than additional more keys.
+ // Append remained additional more keys to the tail of more keys.
+ if (DEBUG && out != null) {
+ throw new RuntimeException("Internal logic error:"
+ + " moreKeys=" + Arrays.toString(moreKeys)
+ + " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
+ }
+ out = new ArrayList<String>(moreKeysCount);
+ for (int i = 0; i < moreKeysCount; i++) {
+ out.add(moreKeys[i]);
+ }
+ for (int i = additionalIndex; i < additionalCount; i++) {
+ out.add(additionalMoreKeys[additionalIndex]);
+ }
+ }
+ if (out != null) {
+ return out.size() > 0 ? out.toArray(new String[out.size()]) : null;
+ } else {
+ return moreKeys;
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class KeySpecParserError extends RuntimeException {
+ public KeySpecParserError(String message) {
+ super(message);
+ }
+ }
+
+ private static int getResourceId(Resources res, String name, int packageNameResId) {
+ String packageName = res.getResourcePackageName(packageNameResId);
+ int resId = res.getIdentifier(name, null, packageName);
+ if (resId == 0) {
+ throw new RuntimeException("Unknown resource: " + name);
+ }
+ return resId;
+ }
+
+ private static String resolveStringResource(String rawText, Resources res,
+ int packageNameResId) {
+ int level = 0;
+ String text = rawText;
+ StringBuilder sb;
+ do {
+ level++;
+ if (level >= MAX_STRING_REFERENCE_INDIRECTION) {
+ throw new RuntimeException("too many @string/resource indirection: " + text);
+ }
+
+ final int size = text.length();
+ if (size < PREFIX_STRING.length()) {
+ return text;
+ }
+
+ sb = null;
+ for (int pos = 0; pos < size; pos++) {
+ final char c = text.charAt(pos);
+ if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) {
+ if (sb == null) {
+ sb = new StringBuilder(text.substring(0, pos));
+ }
+ final int end = searchResourceNameEnd(text, pos + PREFIX_STRING.length());
+ final String resName = text.substring(pos + 1, end);
+ final int resId = getResourceId(res, resName, packageNameResId);
+ sb.append(res.getString(resId));
+ pos = end - 1;
+ } else if (c == ESCAPE_CHAR) {
+ if (sb != null) {
+ // Append both escape character and escaped character.
+ sb.append(text.substring(pos, Math.min(pos + 2, size)));
+ }
+ pos++;
+ } else if (sb != null) {
+ sb.append(c);
+ }
+ }
+
+ if (sb != null) {
+ text = sb.toString();
+ }
+ } while (sb != null);
+
+ return text;
+ }
+
+ private static int searchResourceNameEnd(String text, int start) {
+ final int size = text.length();
+ for (int pos = start; pos < size; pos++) {
+ final char c = text.charAt(pos);
+ // String resource name should be consisted of [a-z_0-9].
+ if ((c >= 'a' && c <= 'z') || c == '_' || (c >= '0' && c <= '9')) {
+ continue;
+ }
+ return pos;
+ }
+ return size;
+ }
+
+ public static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
+ final String text = resolveStringResource(rawText, res, packageNameResId);
+ final int size = text.length();
+ if (size == 0) {
+ return null;
+ }
+ if (Utils.codePointCount(text) == 1) {
+ return text.codePointAt(0) == COMMA ? null : new String[] { text };
+ }
+
+ ArrayList<String> list = null;
+ int start = 0;
+ for (int pos = 0; pos < size; pos++) {
+ final char c = text.charAt(pos);
+ if (c == COMMA) {
+ // Skip empty entry.
+ if (pos - start > 0) {
+ if (list == null) {
+ list = new ArrayList<String>();
+ }
+ list.add(text.substring(start, pos));
+ }
+ // Skip comma
+ start = pos + 1;
+ } else if (c == ESCAPE_CHAR) {
+ // Skip escape character and escaped character.
+ pos++;
+ }
+ }
+ final String remain = (size - start > 0) ? text.substring(start) : null;
+ if (list == null) {
+ return remain != null ? new String[] { remain } : null;
+ } else {
+ if (remain != null) {
+ list.add(remain);
+ }
+ return list.toArray(new String[list.size()]);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index b385b7a04..12a9c51f2 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -19,16 +19,17 @@ package com.android.inputmethod.keyboard.internal;
import android.content.res.TypedArray;
import android.util.Log;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder.ParseException;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.XmlParseUtils;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
-import java.util.ArrayList;
import java.util.HashMap;
public class KeyStyles {
- private static final String TAG = "KeyStyles";
+ private static final String TAG = KeyStyles.class.getSimpleName();
private static final boolean DEBUG = false;
private final HashMap<String, DeclaredKeyStyle> mStyles =
@@ -36,26 +37,21 @@ public class KeyStyles {
private static final KeyStyle EMPTY_KEY_STYLE = new EmptyKeyStyle();
public interface KeyStyle {
- public CharSequence[] getTextArray(TypedArray a, int index);
- public CharSequence getText(TypedArray a, int index);
+ public String[] getStringArray(TypedArray a, int index);
+ public String getString(TypedArray a, int index);
public int getInt(TypedArray a, int index, int defaultValue);
- public int getFlag(TypedArray a, int index, int defaultValue);
- public boolean getBoolean(TypedArray a, int index, boolean defaultValue);
+ public int getFlag(TypedArray a, int index);
}
- /* package */ static class EmptyKeyStyle implements KeyStyle {
- private EmptyKeyStyle() {
- // Nothing to do.
- }
-
+ static class EmptyKeyStyle implements KeyStyle {
@Override
- public CharSequence[] getTextArray(TypedArray a, int index) {
- return parseTextArray(a, index);
+ public String[] getStringArray(TypedArray a, int index) {
+ return KeyStyles.parseStringArray(a, index);
}
@Override
- public CharSequence getText(TypedArray a, int index) {
- return a.getText(index);
+ public String getString(TypedArray a, int index) {
+ return a.getString(index);
}
@Override
@@ -64,170 +60,127 @@ public class KeyStyles {
}
@Override
- public int getFlag(TypedArray a, int index, int defaultValue) {
- return a.getInt(index, defaultValue);
- }
-
- @Override
- public boolean getBoolean(TypedArray a, int index, boolean defaultValue) {
- return a.getBoolean(index, defaultValue);
- }
-
- protected static CharSequence[] parseTextArray(TypedArray a, int index) {
- if (!a.hasValue(index))
- return null;
- final CharSequence text = a.getText(index);
- return parseCsvText(text);
- }
-
- /* package */ static CharSequence[] parseCsvText(CharSequence text) {
- final int size = text.length();
- if (size == 0) return null;
- if (size == 1) return new CharSequence[] { text };
- final StringBuilder sb = new StringBuilder();
- ArrayList<CharSequence> list = null;
- int start = 0;
- for (int pos = 0; pos < size; pos++) {
- final char c = text.charAt(pos);
- if (c == ',') {
- if (list == null) list = new ArrayList<CharSequence>();
- if (sb.length() == 0) {
- list.add(text.subSequence(start, pos));
- } else {
- list.add(sb.toString());
- sb.setLength(0);
- }
- start = pos + 1;
- continue;
- } else if (c == '\\') {
- if (start == pos) {
- // Skip escape character at the beginning of the value.
- start++;
- pos++;
- } else {
- if (start < pos && sb.length() == 0)
- sb.append(text.subSequence(start, pos));
- pos++;
- if (pos < size)
- sb.append(text.charAt(pos));
- }
- } else if (sb.length() > 0) {
- sb.append(c);
- }
- }
- if (list == null) {
- return new CharSequence[] { sb.length() > 0 ? sb : text.subSequence(start, size) };
- } else {
- list.add(sb.length() > 0 ? sb : text.subSequence(start, size));
- return list.toArray(new CharSequence[list.size()]);
- }
+ public int getFlag(TypedArray a, int index) {
+ return a.getInt(index, 0);
}
}
- private static class DeclaredKeyStyle extends EmptyKeyStyle {
- private final HashMap<Integer, Object> mAttributes = new HashMap<Integer, Object>();
+ static class DeclaredKeyStyle implements KeyStyle {
+ private final HashMap<Integer, Object> mStyleAttributes = new HashMap<Integer, Object>();
@Override
- public CharSequence[] getTextArray(TypedArray a, int index) {
- return a.hasValue(index)
- ? super.getTextArray(a, index) : (CharSequence[])mAttributes.get(index);
+ public String[] getStringArray(TypedArray a, int index) {
+ if (a.hasValue(index)) {
+ return parseStringArray(a, index);
+ }
+ return (String[])mStyleAttributes.get(index);
}
@Override
- public CharSequence getText(TypedArray a, int index) {
- return a.hasValue(index)
- ? super.getText(a, index) : (CharSequence)mAttributes.get(index);
+ public String getString(TypedArray a, int index) {
+ if (a.hasValue(index)) {
+ return a.getString(index);
+ }
+ return (String)mStyleAttributes.get(index);
}
@Override
public int getInt(TypedArray a, int index, int defaultValue) {
- final Integer value = (Integer)mAttributes.get(index);
- return super.getInt(a, index, (value != null) ? value : defaultValue);
- }
-
- @Override
- public int getFlag(TypedArray a, int index, int defaultValue) {
- final Integer value = (Integer)mAttributes.get(index);
- return super.getFlag(a, index, defaultValue) | (value != null ? value : 0);
+ if (a.hasValue(index)) {
+ return a.getInt(index, defaultValue);
+ }
+ final Integer styleValue = (Integer)mStyleAttributes.get(index);
+ return styleValue != null ? styleValue : defaultValue;
}
@Override
- public boolean getBoolean(TypedArray a, int index, boolean defaultValue) {
- final Boolean value = (Boolean)mAttributes.get(index);
- return super.getBoolean(a, index, (value != null) ? value : defaultValue);
- }
-
- private DeclaredKeyStyle() {
- super();
+ public int getFlag(TypedArray a, int index) {
+ final int value = a.getInt(index, 0);
+ final Integer styleValue = (Integer)mStyleAttributes.get(index);
+ return (styleValue != null ? styleValue : 0) | value;
}
- private void parseKeyStyleAttributes(TypedArray keyAttr) {
+ void readKeyAttributes(TypedArray keyAttr) {
// TODO: Currently not all Key attributes can be declared as style.
readInt(keyAttr, R.styleable.Keyboard_Key_code);
- readText(keyAttr, R.styleable.Keyboard_Key_keyLabel);
- readText(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
- readText(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
- readTextArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
- readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelOption);
+ readInt(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);
+ readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
+ readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
+ readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
readInt(keyAttr, R.styleable.Keyboard_Key_keyIcon);
+ readInt(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
readInt(keyAttr, R.styleable.Keyboard_Key_keyIconPreview);
- readInt(keyAttr, R.styleable.Keyboard_Key_keyIconShifted);
readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
- readBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable);
- readBoolean(keyAttr, R.styleable.Keyboard_Key_enabled);
+ readFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
}
- private void readText(TypedArray a, int index) {
- if (a.hasValue(index))
- mAttributes.put(index, a.getText(index));
+ private void readString(TypedArray a, int index) {
+ if (a.hasValue(index)) {
+ mStyleAttributes.put(index, a.getString(index));
+ }
}
private void readInt(TypedArray a, int index) {
- if (a.hasValue(index))
- mAttributes.put(index, a.getInt(index, 0));
+ if (a.hasValue(index)) {
+ mStyleAttributes.put(index, a.getInt(index, 0));
+ }
}
private void readFlag(TypedArray a, int index) {
- final Integer value = (Integer)mAttributes.get(index);
- if (a.hasValue(index))
- mAttributes.put(index, a.getInt(index, 0) | (value != null ? value : 0));
+ final Integer value = (Integer)mStyleAttributes.get(index);
+ if (a.hasValue(index)) {
+ mStyleAttributes.put(index, a.getInt(index, 0) | (value != null ? value : 0));
+ }
}
- private void readBoolean(TypedArray a, int index) {
- if (a.hasValue(index))
- mAttributes.put(index, a.getBoolean(index, false));
+ private void readStringArray(TypedArray a, int index) {
+ final String[] value = parseStringArray(a, index);
+ if (value != null) {
+ mStyleAttributes.put(index, value);
+ }
}
- private void readTextArray(TypedArray a, int index) {
- final CharSequence[] value = parseTextArray(a, index);
- if (value != null)
- mAttributes.put(index, value);
+ void addParentStyleAttributes(DeclaredKeyStyle parentStyle) {
+ mStyleAttributes.putAll(parentStyle.mStyleAttributes);
}
+ }
- private void addParent(DeclaredKeyStyle parentStyle) {
- mAttributes.putAll(parentStyle.mAttributes);
+ static String[] parseStringArray(TypedArray a, int index) {
+ if (a.hasValue(index)) {
+ return KeySpecParser.parseCsvString(
+ a.getString(index), a.getResources(), R.string.english_ime_name);
}
+ return null;
}
public void parseKeyStyleAttributes(TypedArray keyStyleAttr, TypedArray keyAttrs,
- XmlPullParser parser) {
+ XmlPullParser parser) throws XmlPullParserException {
final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
- if (DEBUG) Log.d(TAG, String.format("<%s styleName=%s />",
- KeyboardBuilder.TAG_KEY_STYLE, styleName));
- if (mStyles.containsKey(styleName))
- throw new ParseException("duplicate key style declared: " + styleName, parser);
+ if (DEBUG) {
+ Log.d(TAG, String.format("<%s styleName=%s />",
+ Keyboard.Builder.TAG_KEY_STYLE, styleName));
+ }
+ if (mStyles.containsKey(styleName)) {
+ throw new XmlParseUtils.ParseException(
+ "duplicate key style declared: " + styleName, parser);
+ }
final DeclaredKeyStyle style = new DeclaredKeyStyle();
if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
final String parentStyle = keyStyleAttr.getString(
R.styleable.Keyboard_KeyStyle_parentStyle);
final DeclaredKeyStyle parent = mStyles.get(parentStyle);
- if (parent == null)
- throw new ParseException("Unknown parentStyle " + parentStyle, parser);
- style.addParent(parent);
+ if (parent == null) {
+ throw new XmlParseUtils.ParseException(
+ "Unknown parentStyle " + parentStyle, parser);
+ }
+ style.addParentStyleAttributes(parent);
}
- style.parseKeyStyleAttributes(keyAttrs);
+ style.readKeyAttributes(keyAttrs);
mStyles.put(styleName, style);
}
@@ -235,7 +188,7 @@ public class KeyStyles {
return mStyles.get(styleName);
}
- public KeyStyle getEmptyKeyStyle() {
+ public static KeyStyle getEmptyKeyStyle() {
return EMPTY_KEY_STYLE;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
deleted file mode 100644
index de64639b0..000000000
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
-import android.util.Xml;
-import android.view.InflateException;
-
-import com.android.inputmethod.compat.EditorInfoCompatUtils;
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-/**
- * Keyboard Building helper.
- *
- * This class parses Keyboard XML file and eventually build a Keyboard.
- * The Keyboard XML file looks like:
- * <pre>
- * &gt;!-- xml/keyboard.xml --&lt;
- * &gt;Keyboard keyboard_attributes*&lt;
- * &gt;!-- Keyboard Content --&lt;
- * &gt;Row row_attributes*&lt;
- * &gt;!-- Row Content --&lt;
- * &gt;Key key_attributes* /&lt;
- * &gt;Spacer horizontalGap="0.2in" /&lt;
- * &gt;include keyboardLayout="@xml/other_keys"&lt;
- * ...
- * &gt;/Row&lt;
- * &gt;include keyboardLayout="@xml/other_rows"&lt;
- * ...
- * &gt;/Keyboard&lt;
- * </pre>
- * The XML file which is included in other file must have &gt;merge&lt; as root element, such as:
- * <pre>
- * &gt;!-- xml/other_keys.xml --&lt;
- * &gt;merge&lt;
- * &gt;Key key_attributes* /&lt;
- * ...
- * &gt;/merge&lt;
- * </pre>
- * and
- * <pre>
- * &gt;!-- xml/other_rows.xml --&lt;
- * &gt;merge&lt;
- * &gt;Row row_attributes*&lt;
- * &gt;Key key_attributes* /&lt;
- * &gt;/Row&lt;
- * ...
- * &gt;/merge&lt;
- * </pre>
- * You can also use switch-case-default tags to select Rows and Keys.
- * <pre>
- * &gt;switch&lt;
- * &gt;case case_attribute*&lt;
- * &gt;!-- Any valid tags at switch position --&lt;
- * &gt;/case&lt;
- * ...
- * &gt;default&lt;
- * &gt;!-- Any valid tags at switch position --&lt;
- * &gt;/default&lt;
- * &gt;/switch&lt;
- * </pre>
- * You can declare Key style and specify styles within Key tags.
- * <pre>
- * &gt;switch&lt;
- * &gt;case mode="email"&lt;
- * &gt;key-style styleName="f1-key" parentStyle="modifier-key"
- * keyLabel=".com"
- * /&lt;
- * &gt;/case&lt;
- * &gt;case mode="url"&lt;
- * &gt;key-style styleName="f1-key" parentStyle="modifier-key"
- * keyLabel="http://"
- * /&lt;
- * &gt;/case&lt;
- * &gt;/switch&lt;
- * ...
- * &gt;Key keyStyle="shift-key" ... /&lt;
- * </pre>
- */
-
-public class KeyboardBuilder<KP extends KeyboardParams> {
- private static final String TAG = KeyboardBuilder.class.getSimpleName();
- private static final boolean DEBUG = false;
-
- // Keyboard XML Tags
- private static final String TAG_KEYBOARD = "Keyboard";
- private static final String TAG_ROW = "Row";
- private static final String TAG_KEY = "Key";
- 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";
- public static final String TAG_KEY_STYLE = "key-style";
-
- private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
- private static final int DEFAULT_KEYBOARD_ROWS = 4;
-
- protected final KP mParams;
- protected final Context mContext;
- protected final Resources mResources;
- private final DisplayMetrics mDisplayMetrics;
-
- private int mCurrentY = 0;
- private Row mCurrentRow = null;
- private boolean mLeftEdge;
- private boolean mTopEdge;
- private Key mRightEdgeKey = null;
- private final KeyStyles mKeyStyles = new KeyStyles();
-
- /**
- * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
- * Some of the key size defaults can be overridden per row from what the {@link Keyboard}
- * defines.
- */
- public static class Row {
- // keyWidth enum constants
- private static final int KEYWIDTH_NOT_ENUM = 0;
- private static final int KEYWIDTH_FILL_RIGHT = -1;
- private static final int KEYWIDTH_FILL_BOTH = -2;
-
- private final KeyboardParams mParams;
- /** Default width of a key in this row. */
- public final float mDefaultKeyWidth;
- /** Default height of a key in this row. */
- public final int mRowHeight;
-
- private final int mCurrentY;
- // Will be updated by {@link Key}'s constructor.
- private float mCurrentX;
-
- public Row(Resources res, KeyboardParams params, XmlPullParser parser, int y) {
- mParams = params;
- TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
- mRowHeight = (int)KeyboardBuilder.getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_rowHeight, params.mBaseHeight, params.mDefaultRowHeight);
- keyboardAttr.recycle();
- TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
- mDefaultKeyWidth = KeyboardBuilder.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, params.mBaseWidth, params.mDefaultKeyWidth);
- keyAttr.recycle();
-
- mCurrentY = y;
- mCurrentX = 0.0f;
- }
-
- public void setXPos(float keyXPos) {
- mCurrentX = keyXPos;
- }
-
- public void advanceXPos(float width) {
- mCurrentX += width;
- }
-
- public int getKeyY() {
- return mCurrentY;
- }
-
- public float getKeyX(TypedArray keyAttr) {
- final int widthType = KeyboardBuilder.getEnumValue(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
- if (widthType == KEYWIDTH_FILL_BOTH) {
- // If keyWidth is fillBoth, the key width should start right after the nearest key
- // on the left hand side.
- return mCurrentX;
- }
-
- final int keyboardRightEdge = mParams.mOccupiedWidth - mParams.mHorizontalEdgesPadding;
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
- final float keyXPos = KeyboardBuilder.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyXPos, mParams.mBaseWidth, 0);
- if (keyXPos < 0) {
- // If keyXPos is negative, the actual x-coordinate will be
- // keyboardWidth + keyXPos.
- // keyXPos shouldn't be less than mCurrentX because drawable area for this key
- // starts at mCurrentX. Or, this key will overlaps the adjacent key on its left
- // hand side.
- return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
- } else {
- return keyXPos + mParams.mHorizontalEdgesPadding;
- }
- }
- return mCurrentX;
- }
-
- public float getKeyWidth(TypedArray keyAttr, float keyXPos) {
- final int widthType = KeyboardBuilder.getEnumValue(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
- switch (widthType) {
- case KEYWIDTH_FILL_RIGHT:
- case KEYWIDTH_FILL_BOTH:
- final int keyboardRightEdge =
- mParams.mOccupiedWidth - mParams.mHorizontalEdgesPadding;
- // If keyWidth is fillRight, the actual key width will be determined to fill out the
- // area up to the right edge of the keyboard.
- // If keyWidth is fillBoth, the actual key width will be determined to fill out the
- // area between the nearest key on the left hand side and the right edge of the
- // keyboard.
- return keyboardRightEdge - keyXPos;
- default: // KEYWIDTH_NOT_ENUM
- return KeyboardBuilder.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, mParams.mBaseWidth, mDefaultKeyWidth);
- }
- }
- }
-
- public KeyboardBuilder(Context context, KP params) {
- mContext = context;
- final Resources res = context.getResources();
- mResources = res;
- mDisplayMetrics = res.getDisplayMetrics();
-
- mParams = params;
-
- setTouchPositionCorrectionData(context, params);
-
- params.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
- params.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
- }
-
- private static void setTouchPositionCorrectionData(Context context, KeyboardParams params) {
- final TypedArray a = context.obtainStyledAttributes(
- null, R.styleable.Keyboard, R.attr.keyboardStyle, 0);
- params.mThemeId = a.getInt(R.styleable.Keyboard_themeId, 0);
- final int resourceId = a.getResourceId(R.styleable.Keyboard_touchPositionCorrectionData, 0);
- a.recycle();
- if (resourceId == 0) {
- if (LatinImeLogger.sDBG)
- throw new RuntimeException("touchPositionCorrectionData is not defined");
- return;
- }
-
- final String[] data = context.getResources().getStringArray(resourceId);
- params.mTouchPositionCorrection.load(data);
- }
-
- public KeyboardBuilder<KP> load(KeyboardId id) {
- mParams.mId = id;
- final XmlResourceParser parser = mResources.getXml(id.getXmlId());
- try {
- parseKeyboard(parser);
- } catch (XmlPullParserException e) {
- Log.w(TAG, "keyboard XML parse error: " + e);
- throw new IllegalArgumentException(e);
- } catch (IOException e) {
- Log.w(TAG, "keyboard XML parse error: " + e);
- throw new RuntimeException(e);
- } finally {
- parser.close();
- }
- return this;
- }
-
- public void setTouchPositionCorrectionEnabled(boolean enabled) {
- mParams.mTouchPositionCorrection.setEnabled(enabled);
- }
-
- public Keyboard build() {
- return new Keyboard(mParams);
- }
-
- private void parseKeyboard(XmlResourceParser parser)
- throws XmlPullParserException, IOException {
- if (DEBUG) Log.d(TAG, String.format("<%s> %s", TAG_KEYBOARD, mParams.mId));
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_KEYBOARD.equals(tag)) {
- parseKeyboardAttributes(parser);
- startKeyboard();
- parseKeyboardContent(parser, false);
- break;
- } else {
- throw new IllegalStartTag(parser, TAG_KEYBOARD);
- }
- }
- }
- }
-
- public static String parseKeyboardLocale(
- Context context, int resId) throws XmlPullParserException, IOException {
- final Resources res = context.getResources();
- final XmlPullParser parser = res.getXml(resId);
- if (parser == null) return "";
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_KEYBOARD.equals(tag)) {
- final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
- final String locale = keyboardAttr.getString(
- R.styleable.Keyboard_keyboardLocale);
- keyboardAttr.recycle();
- return locale;
- } else {
- throw new IllegalStartTag(parser, TAG_KEYBOARD);
- }
- }
- }
- return "";
- }
-
- private void parseKeyboardAttributes(XmlPullParser parser) {
- final int displayWidth = mDisplayMetrics.widthPixels;
- final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
- Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
- R.style.Keyboard);
- final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
- try {
- final int displayHeight = mDisplayMetrics.heightPixels;
- final int keyboardHeight = (int)keyboardAttr.getDimension(
- R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
- final int maxKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- int minKeyboardHeight = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
- if (minKeyboardHeight < 0) {
- // Specified fraction was negative, so it should be calculated against display
- // width.
- minKeyboardHeight = -(int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
- }
- final KeyboardParams params = mParams;
- // Keyboard height will not exceed maxKeyboardHeight and will not be less than
- // minKeyboardHeight.
- params.mOccupiedHeight = Math.max(
- Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
- params.mOccupiedWidth = params.mId.mWidth;
- params.mTopPadding = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyboardTopPadding, params.mOccupiedHeight, 0);
- params.mBottomPadding = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyboardBottomPadding, params.mOccupiedHeight, 0);
- params.mHorizontalEdgesPadding = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyboardHorizontalEdgesPadding, mParams.mOccupiedWidth, 0);
-
- params.mBaseWidth = params.mOccupiedWidth - params.mHorizontalEdgesPadding * 2
- - params.mHorizontalCenterPadding;
- params.mDefaultKeyWidth = (int)getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, params.mBaseWidth,
- params.mBaseWidth / DEFAULT_KEYBOARD_COLUMNS);
- params.mHorizontalGap = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_horizontalGap, params.mBaseWidth, 0);
- params.mVerticalGap = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_verticalGap, params.mOccupiedHeight, 0);
- params.mBaseHeight = params.mOccupiedHeight - params.mTopPadding
- - params.mBottomPadding + params.mVerticalGap;
- params.mDefaultRowHeight = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_rowHeight, params.mBaseHeight,
- params.mBaseHeight / DEFAULT_KEYBOARD_ROWS);
-
- params.mIsRtlKeyboard = keyboardAttr.getBoolean(
- R.styleable.Keyboard_isRtlKeyboard, false);
- params.mMoreKeysTemplate = keyboardAttr.getResourceId(
- R.styleable.Keyboard_moreKeysTemplate, 0);
- params.mMaxMiniKeyboardColumn = keyAttr.getInt(
- R.styleable.Keyboard_Key_maxMoreKeysColumn, 5);
-
- params.mIconsSet.loadIcons(keyboardAttr);
- } finally {
- keyAttr.recycle();
- keyboardAttr.recycle();
- }
- }
-
- private void parseKeyboardContent(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_ROW.equals(tag)) {
- Row row = parseRowAttributes(parser);
- if (DEBUG) Log.d(TAG, String.format("<%s>", TAG_ROW));
- if (!skip)
- startRow(row);
- parseRowContent(parser, row, skip);
- } else if (TAG_INCLUDE.equals(tag)) {
- parseIncludeKeyboardContent(parser, skip);
- } else if (TAG_SWITCH.equals(tag)) {
- parseSwitchKeyboardContent(parser, skip);
- } else if (TAG_KEY_STYLE.equals(tag)) {
- parseKeyStyle(parser, skip);
- } else {
- throw new IllegalStartTag(parser, TAG_ROW);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (TAG_KEYBOARD.equals(tag)) {
- endKeyboard();
- break;
- } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
- || TAG_MERGE.equals(tag)) {
- if (DEBUG) Log.d(TAG, String.format("</%s>", tag));
- break;
- } else if (TAG_KEY_STYLE.equals(tag)) {
- continue;
- } else {
- throw new IllegalEndTag(parser, TAG_ROW);
- }
- }
- }
- }
-
- private Row parseRowAttributes(XmlPullParser parser) {
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
- try {
- if (a.hasValue(R.styleable.Keyboard_horizontalGap))
- throw new IllegalAttribute(parser, "horizontalGap");
- if (a.hasValue(R.styleable.Keyboard_verticalGap))
- throw new IllegalAttribute(parser, "verticalGap");
- return new Row(mResources, mParams, parser, mCurrentY);
- } finally {
- a.recycle();
- }
- }
-
- private void parseRowContent(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_KEY.equals(tag)) {
- parseKey(parser, row, skip);
- } else if (TAG_SPACER.equals(tag)) {
- parseSpacer(parser, row, skip);
- } else if (TAG_INCLUDE.equals(tag)) {
- parseIncludeRowContent(parser, row, skip);
- } else if (TAG_SWITCH.equals(tag)) {
- parseSwitchRowContent(parser, row, skip);
- } else if (TAG_KEY_STYLE.equals(tag)) {
- parseKeyStyle(parser, skip);
- } else {
- throw new IllegalStartTag(parser, TAG_KEY);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (TAG_ROW.equals(tag)) {
- if (DEBUG) Log.d(TAG, String.format("</%s>", TAG_ROW));
- if (!skip)
- endRow(row);
- break;
- } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
- || TAG_MERGE.equals(tag)) {
- if (DEBUG) Log.d(TAG, String.format("</%s>", tag));
- break;
- } else if (TAG_KEY_STYLE.equals(tag)) {
- continue;
- } else {
- throw new IllegalEndTag(parser, TAG_KEY);
- }
- }
- }
- }
-
- private void parseKey(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (skip) {
- checkEndTag(TAG_KEY, parser);
- } else {
- final Key key = new Key(mResources, mParams, row, parser, mKeyStyles);
- if (DEBUG) Log.d(TAG, String.format("<%s%s keyLabel=%s code=%d moreKeys=%s />",
- TAG_KEY, (key.isEnabled() ? "" : " disabled"), key.mLabel, key.mCode,
- Arrays.toString(key.mMoreKeys)));
- checkEndTag(TAG_KEY, parser);
- endKey(key);
- }
- }
-
- private void parseSpacer(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (skip) {
- checkEndTag(TAG_SPACER, parser);
- } else {
- final Key.Spacer spacer = new Key.Spacer(mResources, mParams, row, parser, mKeyStyles);
- if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER));
- checkEndTag(TAG_SPACER, parser);
- endKey(spacer);
- }
- }
-
- private void parseIncludeKeyboardContent(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- parseIncludeInternal(parser, null, skip);
- }
-
- private void parseIncludeRowContent(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- parseIncludeInternal(parser, row, skip);
- }
-
- private void parseIncludeInternal(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (skip) {
- checkEndTag(TAG_INCLUDE, parser);
- } else {
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Include);
- final int keyboardLayout = a.getResourceId(
- R.styleable.Keyboard_Include_keyboardLayout, 0);
- a.recycle();
-
- checkEndTag(TAG_INCLUDE, parser);
- if (keyboardLayout == 0)
- throw new ParseException("No keyboardLayout attribute in <include/>", parser);
- if (DEBUG) Log.d(TAG, String.format("<%s keyboardLayout=%s />",
- TAG_INCLUDE, mResources.getResourceEntryName(keyboardLayout)));
- final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout);
- try {
- parseMerge(parserForInclude, row, skip);
- } finally {
- parserForInclude.close();
- }
- }
- }
-
- private void parseMerge(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_MERGE.equals(tag)) {
- if (row == null) {
- parseKeyboardContent(parser, skip);
- } else {
- parseRowContent(parser, row, skip);
- }
- break;
- } else {
- throw new ParseException(
- "Included keyboard layout must have <merge> root element", parser);
- }
- }
- }
- }
-
- private void parseSwitchKeyboardContent(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- parseSwitchInternal(parser, null, skip);
- }
-
- private void parseSwitchRowContent(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- parseSwitchInternal(parser, row, skip);
- }
-
- private void parseSwitchInternal(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (DEBUG) Log.d(TAG, String.format("<%s> %s", TAG_SWITCH, mParams.mId));
- boolean selected = false;
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_CASE.equals(tag)) {
- selected |= parseCase(parser, row, selected ? true : skip);
- } else if (TAG_DEFAULT.equals(tag)) {
- selected |= parseDefault(parser, row, selected ? true : skip);
- } else {
- throw new IllegalStartTag(parser, TAG_KEY);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (TAG_SWITCH.equals(tag)) {
- if (DEBUG) Log.d(TAG, String.format("</%s>", TAG_SWITCH));
- break;
- } else {
- throw new IllegalEndTag(parser, TAG_KEY);
- }
- }
- }
- }
-
- private boolean parseCase(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- final boolean selected = parseCaseCondition(parser);
- if (row == null) {
- // Processing Rows.
- parseKeyboardContent(parser, selected ? skip : true);
- } else {
- // Processing Keys.
- parseRowContent(parser, row, selected ? skip : true);
- }
- return selected;
- }
-
- private boolean parseCaseCondition(XmlPullParser parser) {
- final KeyboardId id = mParams.mId;
- if (id == null)
- return true;
-
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Case);
- try {
- final boolean modeMatched = matchTypedValue(a,
- R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
- final boolean navigateActionMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_navigateAction, id.mNavigateAction);
- final boolean passwordInputMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_passwordInput, id.mPasswordInput);
- final boolean hasSettingsKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_hasSettingsKey, id.mHasSettingsKey);
- final boolean f2KeyModeMatched = matchInteger(a,
- R.styleable.Keyboard_Case_f2KeyMode, id.mF2KeyMode);
- final boolean clobberSettingsKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
- final boolean shortcutKeyEnabledMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
- final boolean hasShortcutKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
- // As noted at {@link KeyboardId} class, we are interested only in enum value masked by
- // {@link android.view.inputmethod.EditorInfo#IME_MASK_ACTION} and
- // {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_ENTER_ACTION}. So matching
- // this attribute with id.mImeOptions as integer value is enough for our purpose.
- final boolean imeActionMatched = matchInteger(a,
- R.styleable.Keyboard_Case_imeAction, id.mImeAction);
- final boolean localeCodeMatched = matchString(a,
- R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
- final boolean languageCodeMatched = matchString(a,
- R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
- final boolean countryCodeMatched = matchString(a,
- R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
- final boolean selected = modeMatched && navigateActionMatched && passwordInputMatched
- && hasSettingsKeyMatched && f2KeyModeMatched && clobberSettingsKeyMatched
- && shortcutKeyEnabledMatched && hasShortcutKeyMatched && imeActionMatched &&
- localeCodeMatched && languageCodeMatched && countryCodeMatched;
-
- if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
- textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
- booleanAttr(a, R.styleable.Keyboard_Case_navigateAction, "navigateAction"),
- booleanAttr(a, R.styleable.Keyboard_Case_passwordInput, "passwordInput"),
- booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"),
- textAttr(KeyboardId.f2KeyModeName(
- a.getInt(R.styleable.Keyboard_Case_f2KeyMode, -1)), "f2KeyMode"),
- booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
- "clobberSettingsKey"),
- booleanAttr(
- a, R.styleable.Keyboard_Case_shortcutKeyEnabled, "shortcutKeyEnabled"),
- booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey, "hasShortcutKey"),
- textAttr(EditorInfoCompatUtils.imeOptionsName(
- a.getInt(R.styleable.Keyboard_Case_imeAction, -1)), "imeAction"),
- textAttr(a.getString(R.styleable.Keyboard_Case_localeCode), "localeCode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_languageCode), "languageCode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"),
- Boolean.toString(selected)));
-
- return selected;
- } finally {
- a.recycle();
- }
- }
-
- private static boolean matchInteger(TypedArray a, int index, int value) {
- // If <case> does not have "index" attribute, that means this <case> is wild-card for the
- // attribute.
- return !a.hasValue(index) || a.getInt(index, 0) == value;
- }
-
- private static boolean matchBoolean(TypedArray a, int index, boolean value) {
- // If <case> does not have "index" attribute, that means this <case> is wild-card for the
- // attribute.
- return !a.hasValue(index) || a.getBoolean(index, false) == value;
- }
-
- private static boolean matchString(TypedArray a, int index, String value) {
- // If <case> does not have "index" attribute, that means this <case> is wild-card for the
- // attribute.
- return !a.hasValue(index) || stringArrayContains(a.getString(index).split("\\|"), value);
- }
-
- private static boolean matchTypedValue(TypedArray a, int index, int intValue, String strValue) {
- // If <case> does not have "index" attribute, that means this <case> is wild-card for the
- // attribute.
- final TypedValue v = a.peekValue(index);
- if (v == null)
- return true;
-
- if (isIntegerValue(v)) {
- return intValue == a.getInt(index, 0);
- } else if (isStringValue(v)) {
- return stringArrayContains(a.getString(index).split("\\|"), strValue);
- }
- return false;
- }
-
- private static boolean stringArrayContains(String[] array, String value) {
- for (final String elem : array) {
- if (elem.equals(value))
- return true;
- }
- return false;
- }
-
- private boolean parseDefault(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (DEBUG) Log.d(TAG, String.format("<%s>", TAG_DEFAULT));
- if (row == null) {
- parseKeyboardContent(parser, skip);
- } else {
- parseRowContent(parser, row, skip);
- }
- return true;
- }
-
- private void parseKeyStyle(XmlPullParser parser, boolean skip) {
- TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_KeyStyle);
- TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
- try {
- if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName))
- throw new ParseException("<" + TAG_KEY_STYLE
- + "/> needs styleName attribute", parser);
- if (!skip)
- mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser);
- } finally {
- keyStyleAttr.recycle();
- keyAttrs.recycle();
- }
- }
-
- private static void checkEndTag(String tag, XmlPullParser parser)
- throws XmlPullParserException, IOException {
- if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName()))
- return;
- throw new NonEmptyTag(tag, parser);
- }
-
- private void startKeyboard() {
- mCurrentY += mParams.mTopPadding;
- mTopEdge = true;
- }
-
- private void startRow(Row row) {
- addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
- mCurrentRow = row;
- mLeftEdge = true;
- mRightEdgeKey = null;
- }
-
- private void endRow(Row row) {
- if (mCurrentRow == null)
- throw new InflateException("orphant end row tag");
- if (mRightEdgeKey != null) {
- mRightEdgeKey.markAsRightEdge(mParams);
- mRightEdgeKey = null;
- }
- addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
- mCurrentY += row.mRowHeight;
- mCurrentRow = null;
- mTopEdge = false;
- }
-
- private void endKey(Key key) {
- mParams.onAddKey(key);
- if (mLeftEdge) {
- key.markAsLeftEdge(mParams);
- mLeftEdge = false;
- }
- if (mTopEdge) {
- key.markAsTopEdge(mParams);
- }
- mRightEdgeKey = key;
- }
-
- private void endKeyboard() {
- }
-
- private void addEdgeSpace(float width, Row row) {
- row.advanceXPos(width);
- mLeftEdge = false;
- mRightEdgeKey = null;
- }
-
- public static float getDimensionOrFraction(TypedArray a, int index, int base, float defValue) {
- final TypedValue value = a.peekValue(index);
- if (value == null)
- return defValue;
- if (isFractionValue(value)) {
- return a.getFraction(index, base, base, defValue);
- } else if (isDimensionValue(value)) {
- return a.getDimension(index, defValue);
- }
- return defValue;
- }
-
- public static int getEnumValue(TypedArray a, int index, int defValue) {
- final TypedValue value = a.peekValue(index);
- if (value == null)
- return defValue;
- if (isIntegerValue(value)) {
- return a.getInt(index, defValue);
- }
- return defValue;
- }
-
- private static boolean isFractionValue(TypedValue v) {
- return v.type == TypedValue.TYPE_FRACTION;
- }
-
- private static boolean isDimensionValue(TypedValue v) {
- return v.type == TypedValue.TYPE_DIMENSION;
- }
-
- private static boolean isIntegerValue(TypedValue v) {
- return v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT;
- }
-
- private static boolean isStringValue(TypedValue v) {
- return v.type == TypedValue.TYPE_STRING;
- }
-
- @SuppressWarnings("serial")
- public static class ParseException extends InflateException {
- public ParseException(String msg, XmlPullParser parser) {
- super(msg + " at line " + parser.getLineNumber());
- }
- }
-
- @SuppressWarnings("serial")
- private static class IllegalStartTag extends ParseException {
- public IllegalStartTag(XmlPullParser parser, String parent) {
- super("Illegal start tag " + parser.getName() + " in " + parent, parser);
- }
- }
-
- @SuppressWarnings("serial")
- private static class IllegalEndTag extends ParseException {
- public IllegalEndTag(XmlPullParser parser, String parent) {
- super("Illegal end tag " + parser.getName() + " in " + parent, parser);
- }
- }
-
- @SuppressWarnings("serial")
- private static class IllegalAttribute extends ParseException {
- public IllegalAttribute(XmlPullParser parser, String attribute) {
- super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser);
- }
- }
-
- @SuppressWarnings("serial")
- private static class NonEmptyTag extends ParseException {
- public NonEmptyTag(String tag, XmlPullParser parser) {
- super(tag + " must be empty tag", parser);
- }
- }
-
- private static String textAttr(String value, String name) {
- return value != null ? String.format(" %s=%s", name, value) : "";
- }
-
- private static String booleanAttr(TypedArray a, int index, String name) {
- return a.hasValue(index) ? String.format(" %s=%s", name, a.getBoolean(index, false)) : "";
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index faa5f86f2..162e96d06 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -23,86 +23,92 @@ import android.util.Log;
import com.android.inputmethod.latin.R;
+import java.util.HashMap;
+import java.util.Map;
+
public class KeyboardIconsSet {
private static final String TAG = KeyboardIconsSet.class.getSimpleName();
public static final int ICON_UNDEFINED = 0;
+ // The value should be aligned with the enum value of Key.keyIcon.
+ public static final int ICON_SPACE = 4;
+ private static final int NUM_ICONS = 13;
+
+ private final Drawable[] mIcons = new Drawable[NUM_ICONS + 1];
- // This should be aligned with Keyboard.keyIcon enum.
- private static final int ICON_SHIFT_KEY = 1;
- private static final int ICON_DELETE_KEY = 2;
- private static final int ICON_SETTINGS_KEY = 3; // This is also represented as "@icon/3" in XML.
- private static final int ICON_SPACE_KEY = 4;
- private static final int ICON_RETURN_KEY = 5;
- private static final int ICON_SEARCH_KEY = 6;
- private static final int ICON_TAB_KEY = 7; // This is also represented as "@icon/7" in XML.
- private static final int ICON_SHORTCUT_KEY = 8;
- private static final int ICON_SHORTCUT_FOR_LABEL = 9;
- // This should be aligned with Keyboard.keyIconShifted enum.
- private static final int ICON_SHIFTED_SHIFT_KEY = 10;
- // This should be aligned with Keyboard.keyIconPreview enum.
- private static final int ICON_PREVIEW_TAB_KEY = 11;
-
- private static final int ICON_LAST = 11;
-
- private final Drawable mIcons[] = new Drawable[ICON_LAST + 1];
-
- private static final int getIconId(final int attrIndex) {
- switch (attrIndex) {
- case R.styleable.Keyboard_iconShiftKey:
- return ICON_SHIFT_KEY;
- case R.styleable.Keyboard_iconDeleteKey:
- return ICON_DELETE_KEY;
- case R.styleable.Keyboard_iconSettingsKey:
- return ICON_SETTINGS_KEY;
- case R.styleable.Keyboard_iconSpaceKey:
- return ICON_SPACE_KEY;
- case R.styleable.Keyboard_iconReturnKey:
- return ICON_RETURN_KEY;
- case R.styleable.Keyboard_iconSearchKey:
- return ICON_SEARCH_KEY;
- case R.styleable.Keyboard_iconTabKey:
- return ICON_TAB_KEY;
- case R.styleable.Keyboard_iconShortcutKey:
- return ICON_SHORTCUT_KEY;
- case R.styleable.Keyboard_iconShortcutForLabel:
- return ICON_SHORTCUT_FOR_LABEL;
- case R.styleable.Keyboard_iconShiftedShiftKey:
- return ICON_SHIFTED_SHIFT_KEY;
- case R.styleable.Keyboard_iconPreviewTabKey:
- return ICON_PREVIEW_TAB_KEY;
- default:
- return ICON_UNDEFINED;
+ private static final Map<Integer, Integer> ATTR_ID_TO_ICON_ID = new HashMap<Integer, Integer>();
+ private static final Map<String, Integer> NAME_TO_ICON_ID = new HashMap<String, Integer>();
+ private static final String[] ICON_NAMES = new String[NUM_ICONS + 1];
+
+ private static final int ATTR_UNDEFINED = 0;
+ static {
+ // The key value should be aligned with the enum value of Key.keyIcon.
+ addIconIdMap(0, "undefined", ATTR_UNDEFINED);
+ addIconIdMap(1, "shiftKey", R.styleable.Keyboard_iconShiftKey);
+ addIconIdMap(2, "deleteKey", R.styleable.Keyboard_iconDeleteKey);
+ addIconIdMap(3, "settingsKey", R.styleable.Keyboard_iconSettingsKey);
+ addIconIdMap(4, "spaceKey", R.styleable.Keyboard_iconSpaceKey);
+ addIconIdMap(5, "returnKey", R.styleable.Keyboard_iconReturnKey);
+ addIconIdMap(6, "searchKey", R.styleable.Keyboard_iconSearchKey);
+ addIconIdMap(7, "tabKey", R.styleable.Keyboard_iconTabKey);
+ addIconIdMap(8, "shortcutKey", R.styleable.Keyboard_iconShortcutKey);
+ addIconIdMap(9, "shortcutForLabel", R.styleable.Keyboard_iconShortcutForLabel);
+ addIconIdMap(10, "spaceKeyForNumberLayout",
+ R.styleable.Keyboard_iconSpaceKeyForNumberLayout);
+ addIconIdMap(11, "shiftKeyShifted", R.styleable.Keyboard_iconShiftKeyShifted);
+ addIconIdMap(12, "disabledShortcurKey", R.styleable.Keyboard_iconDisabledShortcutKey);
+ addIconIdMap(13, "previewTabKey", R.styleable.Keyboard_iconPreviewTabKey);
+ }
+
+ private static void addIconIdMap(int iconId, String name, int attrId) {
+ if (attrId != ATTR_UNDEFINED) {
+ ATTR_ID_TO_ICON_ID.put(attrId, iconId);
}
+ NAME_TO_ICON_ID.put(name, iconId);
+ ICON_NAMES[iconId] = name;
}
public void loadIcons(final TypedArray keyboardAttrs) {
- final int count = keyboardAttrs.getIndexCount();
- for (int i = 0; i < count; i++) {
- final int attrIndex = keyboardAttrs.getIndex(i);
- final int iconId = getIconId(attrIndex);
- if (iconId != ICON_UNDEFINED) {
- try {
- mIcons[iconId] = setDefaultBounds(keyboardAttrs.getDrawable(attrIndex));
- } catch (Resources.NotFoundException e) {
- Log.w(TAG, "Drawable resource for icon #" + iconId + " not found");
- }
+ for (final Integer attrId : ATTR_ID_TO_ICON_ID.keySet()) {
+ try {
+ final Drawable icon = keyboardAttrs.getDrawable(attrId);
+ setDefaultBounds(icon);
+ final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
+ mIcons[iconId] = icon;
+ } catch (Resources.NotFoundException e) {
+ Log.w(TAG, "Drawable resource for icon #"
+ + keyboardAttrs.getResources().getResourceEntryName(attrId)
+ + " not found");
}
}
}
- public Drawable getIcon(final int iconId) {
- if (iconId == ICON_UNDEFINED)
- return null;
- if (iconId < 0 || iconId >= mIcons.length)
- throw new IllegalArgumentException("icon id is out of range: " + iconId);
- return mIcons[iconId];
+ private static boolean isValidIconId(final int iconId) {
+ return iconId >= 0 && iconId < ICON_NAMES.length;
+ }
+
+ public static String getIconName(final int iconId) {
+ return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
+ }
+
+ public static int getIconId(final String name) {
+ final Integer iconId = NAME_TO_ICON_ID.get(name);
+ if (iconId != null) {
+ return iconId;
+ }
+ throw new RuntimeException("unknown icon name: " + name);
+ }
+
+ public Drawable getIconDrawable(final int iconId) {
+ if (isValidIconId(iconId)) {
+ return mIcons[iconId];
+ }
+ throw new RuntimeException("unknown icon id: " + getIconName(iconId));
}
- private static Drawable setDefaultBounds(final Drawable icon) {
+ private static void setDefaultBounds(final Drawable icon) {
if (icon != null) {
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
}
- return icon;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
deleted file mode 100644
index 64cd37c4b..000000000
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.graphics.drawable.Drawable;
-
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.latin.LatinImeLogger;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class KeyboardParams {
- public KeyboardId mId;
- public int mThemeId;
-
- /** Total height and width of the keyboard, including the paddings and keys */
- public int mOccupiedHeight;
- public int mOccupiedWidth;
-
- /** Base height and width of the keyboard used to calculate rows' or keys' heights and widths */
- public int mBaseHeight;
- public int mBaseWidth;
-
- public int mTopPadding;
- public int mBottomPadding;
- public int mHorizontalEdgesPadding;
- public int mHorizontalCenterPadding;
-
- public int mDefaultRowHeight;
- public int mDefaultKeyWidth;
- public int mHorizontalGap;
- public int mVerticalGap;
-
- public boolean mIsRtlKeyboard;
- public int mMoreKeysTemplate;
- public int mMaxMiniKeyboardColumn;
-
- public int GRID_WIDTH;
- public int GRID_HEIGHT;
-
- public final List<Key> mKeys = new ArrayList<Key>();
- public final List<Key> mShiftKeys = new ArrayList<Key>();
- public final Set<Key> mShiftLockKeys = new HashSet<Key>();
- public final Map<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>();
- public final Map<Key, Drawable> mUnshiftedIcons = new HashMap<Key, Drawable>();
- public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
-
- public int mMostCommonKeyHeight = 0;
- public int mMostCommonKeyWidth = 0;
-
- public final TouchPositionCorrection mTouchPositionCorrection = new TouchPositionCorrection();
-
- public static class TouchPositionCorrection {
- private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
-
- public boolean mEnabled;
- public float[] mXs;
- public float[] mYs;
- public float[] mRadii;
-
- public void load(String[] data) {
- final int dataLength = data.length;
- if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
- if (LatinImeLogger.sDBG)
- throw new RuntimeException(
- "the size of touch position correction data is invalid");
- return;
- }
-
- final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
- mXs = new float[length];
- mYs = new float[length];
- mRadii = new float[length];
- try {
- for (int i = 0; i < dataLength; ++i) {
- final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
- final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
- final float value = Float.parseFloat(data[i]);
- if (type == 0) {
- mXs[index] = value;
- } else if (type == 1) {
- mYs[index] = value;
- } else {
- mRadii[index] = value;
- }
- }
- } catch (NumberFormatException e) {
- if (LatinImeLogger.sDBG) {
- throw new RuntimeException(
- "the number format for touch position correction data is invalid");
- }
- mXs = null;
- mYs = null;
- mRadii = null;
- }
- }
-
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- }
-
- public boolean isValid() {
- return mEnabled && mXs != null && mYs != null && mRadii != null
- && mXs.length > 0 && mYs.length > 0 && mRadii.length > 0;
- }
- }
-
- protected void clearKeys() {
- mKeys.clear();
- mShiftKeys.clear();
- mShiftLockKeys.clear();
- mShiftedIcons.clear();
- mUnshiftedIcons.clear();
- clearHistogram();
- }
-
- public void onAddKey(Key key) {
- mKeys.add(key);
- updateHistogram(key);
- if (key.mCode == Keyboard.CODE_SHIFT) {
- mShiftKeys.add(key);
- if (key.isSticky()) {
- mShiftLockKeys.add(key);
- }
- }
- }
-
- public void addShiftedIcon(Key key, Drawable icon) {
- mUnshiftedIcons.put(key, key.getIcon());
- mShiftedIcons.put(key, icon);
- }
-
- private int mMaxHeightCount = 0;
- private int mMaxWidthCount = 0;
- private final Map<Integer, Integer> mHeightHistogram = new HashMap<Integer, Integer>();
- private final Map<Integer, Integer> mWidthHistogram = new HashMap<Integer, Integer>();
-
- private void clearHistogram() {
- mMostCommonKeyHeight = 0;
- mMaxHeightCount = 0;
- mHeightHistogram.clear();
-
- mMaxWidthCount = 0;
- mMostCommonKeyWidth = 0;
- mWidthHistogram.clear();
- }
-
- private static int updateHistogramCounter(Map<Integer, Integer> histogram, Integer key) {
- final int count = (histogram.containsKey(key) ? histogram.get(key) : 0) + 1;
- histogram.put(key, count);
- return count;
- }
-
- private void updateHistogram(Key key) {
- final Integer height = key.mHeight + key.mVerticalGap;
- final int heightCount = updateHistogramCounter(mHeightHistogram, height);
- if (heightCount > mMaxHeightCount) {
- mMaxHeightCount = heightCount;
- mMostCommonKeyHeight = height;
- }
-
- final Integer width = key.mWidth + key.mHorizontalGap;
- final int widthCount = updateHistogramCounter(mWidthHistogram, width);
- if (widthCount > mMaxWidthCount) {
- mMaxWidthCount = widthCount;
- mMostCommonKeyWidth = width;
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
new file mode 100644
index 000000000..cb8b4f05c
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2011 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 android.text.TextUtils;
+import android.util.Log;
+
+import com.android.inputmethod.keyboard.Keyboard;
+
+/**
+ * Keyboard state machine.
+ *
+ * This class contains all keyboard state transition logic.
+ *
+ * The input events are {@link #onLoadKeyboard(String)}, {@link #onSaveKeyboardState()},
+ * {@link #onPressKey(int)}, {@link #onReleaseKey(int, boolean)},
+ * {@link #onCodeInput(int, boolean, boolean)}, {@link #onCancelInput(boolean)},
+ * {@link #onUpdateShiftState(boolean)}, {@link #onLongPressTimeout(int)}.
+ *
+ * The actions are {@link SwitchActions}'s methods.
+ */
+public class KeyboardState {
+ private static final String TAG = KeyboardState.class.getSimpleName();
+ private static final boolean DEBUG_EVENT = false;
+ private static final boolean DEBUG_ACTION = false;
+
+ public interface SwitchActions {
+ public void setAlphabetKeyboard();
+ public void setAlphabetManualShiftedKeyboard();
+ public void setAlphabetAutomaticShiftedKeyboard();
+ public void setAlphabetShiftLockedKeyboard();
+ public void setAlphabetShiftLockShiftedKeyboard();
+ public void setSymbolsKeyboard();
+ public void setSymbolsShiftedKeyboard();
+
+ /**
+ * Request to call back {@link KeyboardState#onUpdateShiftState(boolean)}.
+ */
+ public void requestUpdatingShiftState();
+
+ public void startDoubleTapTimer();
+ public boolean isInDoubleTapTimeout();
+ public void startLongPressTimer(int code);
+ public void hapticAndAudioFeedback(int code);
+ }
+
+ private final SwitchActions mSwitchActions;
+
+ private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
+ private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
+
+ // TODO: Merge {@link #mSwitchState}, {@link #mIsAlphabetMode}, {@link #mAlphabetShiftState},
+ // {@link #mIsSymbolShifted}, {@link #mPrevMainKeyboardWasShiftLocked}, and
+ // {@link #mPrevSymbolsKeyboardWasShifted} into single state variable.
+ private static final int SWITCH_STATE_ALPHA = 0;
+ private static final int SWITCH_STATE_SYMBOL_BEGIN = 1;
+ private static final int SWITCH_STATE_SYMBOL = 2;
+ private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 3;
+ private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 4;
+ private int mSwitchState = SWITCH_STATE_ALPHA;
+ private String mLayoutSwitchBackSymbols;
+
+ private boolean mIsAlphabetMode;
+ private AlphabetShiftState mAlphabetShiftState = new AlphabetShiftState();
+ private boolean mIsSymbolShifted;
+ private boolean mPrevMainKeyboardWasShiftLocked;
+ private boolean mPrevSymbolsKeyboardWasShifted;
+
+ // For handling double tap.
+ private boolean mIsInAlphabetUnshiftedFromShifted;
+ private boolean mIsInDoubleTapShiftKey;
+
+ private final SavedKeyboardState mSavedKeyboardState = new SavedKeyboardState();
+
+ static class SavedKeyboardState {
+ public boolean mIsValid;
+ public boolean mIsAlphabetMode;
+ public boolean mIsAlphabetShiftLocked;
+ public boolean mIsShifted;
+
+ @Override
+ public String toString() {
+ if (!mIsValid) return "INVALID";
+ if (mIsAlphabetMode) {
+ if (mIsAlphabetShiftLocked) return "ALPHABET_SHIFT_LOCKED";
+ return mIsShifted ? "ALPHABET_SHIFTED" : "ALPHABET";
+ } else {
+ return mIsShifted ? "SYMBOLS_SHIFTED" : "SYMBOLS";
+ }
+ }
+ }
+
+ public KeyboardState(SwitchActions switchActions) {
+ mSwitchActions = switchActions;
+ }
+
+ public void onLoadKeyboard(String layoutSwitchBackSymbols) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onLoadKeyboard: " + this);
+ }
+ mLayoutSwitchBackSymbols = layoutSwitchBackSymbols;
+ // Reset alphabet shift state.
+ mAlphabetShiftState.setShiftLocked(false);
+ mPrevMainKeyboardWasShiftLocked = false;
+ mPrevSymbolsKeyboardWasShifted = false;
+ mShiftKeyState.onRelease();
+ mSymbolKeyState.onRelease();
+ onRestoreKeyboardState();
+ }
+
+ public void onSaveKeyboardState() {
+ final SavedKeyboardState state = mSavedKeyboardState;
+ state.mIsAlphabetMode = mIsAlphabetMode;
+ if (mIsAlphabetMode) {
+ state.mIsAlphabetShiftLocked = mAlphabetShiftState.isShiftLocked();
+ state.mIsShifted = !state.mIsAlphabetShiftLocked
+ && mAlphabetShiftState.isShiftedOrShiftLocked();
+ } else {
+ state.mIsAlphabetShiftLocked = mPrevMainKeyboardWasShiftLocked;
+ state.mIsShifted = mIsSymbolShifted;
+ }
+ state.mIsValid = true;
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onSaveKeyboardState: saved=" + state + " " + this);
+ }
+ }
+
+ private void onRestoreKeyboardState() {
+ final SavedKeyboardState state = mSavedKeyboardState;
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onRestoreKeyboardState: saved=" + state + " " + this);
+ }
+ if (!state.mIsValid || state.mIsAlphabetMode) {
+ setAlphabetKeyboard();
+ } else {
+ if (state.mIsShifted) {
+ setSymbolsShiftedKeyboard();
+ } else {
+ setSymbolsKeyboard();
+ }
+ }
+
+ if (!state.mIsValid) return;
+ state.mIsValid = false;
+
+ if (state.mIsAlphabetMode) {
+ setShiftLocked(state.mIsAlphabetShiftLocked);
+ if (!state.mIsAlphabetShiftLocked) {
+ setShifted(state.mIsShifted ? MANUAL_SHIFT : UNSHIFT);
+ }
+ } else {
+ mPrevMainKeyboardWasShiftLocked = state.mIsAlphabetShiftLocked;
+ }
+ }
+
+ private static final int UNSHIFT = 0;
+ private static final int MANUAL_SHIFT = 1;
+ private static final int AUTOMATIC_SHIFT = 2;
+ private static final int SHIFT_LOCK_SHIFTED = 3;
+
+ private void setShifted(int shiftMode) {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setShifted: shiftMode=" + shiftModeToString(shiftMode) + " " + this);
+ }
+ if (!mIsAlphabetMode) return;
+ final int prevShiftMode;
+ if (mAlphabetShiftState.isAutomaticShifted()) {
+ prevShiftMode = AUTOMATIC_SHIFT;
+ } else if (mAlphabetShiftState.isManualShifted()) {
+ prevShiftMode = MANUAL_SHIFT;
+ } else {
+ prevShiftMode = UNSHIFT;
+ }
+ switch (shiftMode) {
+ case AUTOMATIC_SHIFT:
+ mAlphabetShiftState.setAutomaticShifted();
+ if (shiftMode != prevShiftMode) {
+ mSwitchActions.setAlphabetAutomaticShiftedKeyboard();
+ }
+ break;
+ case MANUAL_SHIFT:
+ mAlphabetShiftState.setShifted(true);
+ if (shiftMode != prevShiftMode) {
+ mSwitchActions.setAlphabetManualShiftedKeyboard();
+ }
+ break;
+ case UNSHIFT:
+ mAlphabetShiftState.setShifted(false);
+ if (shiftMode != prevShiftMode) {
+ mSwitchActions.setAlphabetKeyboard();
+ }
+ break;
+ case SHIFT_LOCK_SHIFTED:
+ mAlphabetShiftState.setShifted(true);
+ mSwitchActions.setAlphabetShiftLockShiftedKeyboard();
+ break;
+ }
+ }
+
+ private void setShiftLocked(boolean shiftLocked) {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setShiftLocked: shiftLocked=" + shiftLocked + " " + this);
+ }
+ if (!mIsAlphabetMode) return;
+ if (shiftLocked && (!mAlphabetShiftState.isShiftLocked()
+ || mAlphabetShiftState.isShiftLockShifted())) {
+ mSwitchActions.setAlphabetShiftLockedKeyboard();
+ }
+ if (!shiftLocked && mAlphabetShiftState.isShiftLocked()) {
+ mSwitchActions.setAlphabetKeyboard();
+ }
+ mAlphabetShiftState.setShiftLocked(shiftLocked);
+ }
+
+ private void toggleAlphabetAndSymbols() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "toggleAlphabetAndSymbols: " + this);
+ }
+ if (mIsAlphabetMode) {
+ mPrevMainKeyboardWasShiftLocked = mAlphabetShiftState.isShiftLocked();
+ if (mPrevSymbolsKeyboardWasShifted) {
+ setSymbolsShiftedKeyboard();
+ } else {
+ setSymbolsKeyboard();
+ }
+ mPrevSymbolsKeyboardWasShifted = false;
+ } else {
+ mPrevSymbolsKeyboardWasShifted = mIsSymbolShifted;
+ setAlphabetKeyboard();
+ if (mPrevMainKeyboardWasShiftLocked) {
+ setShiftLocked(true);
+ }
+ mPrevMainKeyboardWasShiftLocked = false;
+ }
+ }
+
+ private void toggleShiftInSymbols() {
+ if (mIsSymbolShifted) {
+ setSymbolsKeyboard();
+ } else {
+ setSymbolsShiftedKeyboard();
+ }
+ }
+
+ private void setAlphabetKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setAlphabetKeyboard");
+ }
+ mSwitchActions.setAlphabetKeyboard();
+ mIsAlphabetMode = true;
+ mIsSymbolShifted = false;
+ mSwitchState = SWITCH_STATE_ALPHA;
+ mSwitchActions.requestUpdatingShiftState();
+ }
+
+ private void setSymbolsKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setSymbolsKeyboard");
+ }
+ mSwitchActions.setSymbolsKeyboard();
+ mIsAlphabetMode = false;
+ mIsSymbolShifted = false;
+ // Reset alphabet shift state.
+ mAlphabetShiftState.setShiftLocked(false);
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
+ }
+
+ private void setSymbolsShiftedKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setSymbolsShiftedKeyboard");
+ }
+ mSwitchActions.setSymbolsShiftedKeyboard();
+ mIsAlphabetMode = false;
+ mIsSymbolShifted = true;
+ // Reset alphabet shift state.
+ mAlphabetShiftState.setShiftLocked(false);
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
+ }
+
+ public void onPressKey(int code) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onPressKey: code=" + Keyboard.printableCode(code) + " " + this);
+ }
+ if (code == Keyboard.CODE_SHIFT) {
+ onPressShift();
+ } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ onPressSymbol();
+ } else {
+ mShiftKeyState.onOtherKeyPressed();
+ mSymbolKeyState.onOtherKeyPressed();
+ }
+ }
+
+ public void onReleaseKey(int code, boolean withSliding) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onReleaseKey: code=" + Keyboard.printableCode(code)
+ + " sliding=" + withSliding + " " + this);
+ }
+ if (code == Keyboard.CODE_SHIFT) {
+ onReleaseShift(withSliding);
+ } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ onReleaseSymbol(withSliding);
+ }
+ }
+
+ private void onPressSymbol() {
+ toggleAlphabetAndSymbols();
+ mSymbolKeyState.onPress();
+ mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
+ }
+
+ private void onReleaseSymbol(boolean withSliding) {
+ if (mSymbolKeyState.isChording()) {
+ // Switch back to the previous keyboard mode if the user chords the mode change key and
+ // another key, then releases the mode change key.
+ toggleAlphabetAndSymbols();
+ } else if (!withSliding) {
+ // If the mode change key is being released without sliding, we should forget the
+ // previous symbols keyboard shift state and simply switch back to symbols layout
+ // (never symbols shifted) next time the mode gets changed to symbols layout.
+ mPrevSymbolsKeyboardWasShifted = false;
+ }
+ mSymbolKeyState.onRelease();
+ }
+
+ public void onLongPressTimeout(int code) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onLongPressTimeout: code=" + Keyboard.printableCode(code) + " " + this);
+ }
+ if (mIsAlphabetMode && code == Keyboard.CODE_SHIFT) {
+ if (mAlphabetShiftState.isShiftLocked()) {
+ setShiftLocked(false);
+ // Shift key is long pressed while shift locked state, we will toggle back to normal
+ // state. And mark as if shift key is released.
+ mShiftKeyState.onRelease();
+ } else {
+ // Shift key is long pressed while shift unloked state.
+ setShiftLocked(true);
+ }
+ mSwitchActions.hapticAndAudioFeedback(code);
+ }
+ }
+
+ public void onUpdateShiftState(boolean autoCaps) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + " " + this);
+ }
+ updateAlphabetShiftState(autoCaps);
+ }
+
+ private void updateAlphabetShiftState(boolean autoCaps) {
+ if (!mIsAlphabetMode) return;
+ if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
+ if (mShiftKeyState.isReleasing() && autoCaps) {
+ // Only when shift key is releasing, automatic temporary upper case will be set.
+ setShifted(AUTOMATIC_SHIFT);
+ } else {
+ setShifted(mShiftKeyState.isChording() ? MANUAL_SHIFT : UNSHIFT);
+ }
+ }
+ }
+
+ private void onPressShift() {
+ if (mIsAlphabetMode) {
+ mIsInDoubleTapShiftKey = mSwitchActions.isInDoubleTapTimeout();
+ if (!mIsInDoubleTapShiftKey) {
+ // This is first tap.
+ mSwitchActions.startDoubleTapTimer();
+ }
+ if (mIsInDoubleTapShiftKey) {
+ if (mAlphabetShiftState.isManualShifted() || mIsInAlphabetUnshiftedFromShifted) {
+ // Shift key has been double tapped while in manual shifted or automatic
+ // shifted state.
+ setShiftLocked(true);
+ } else {
+ // Shift key has been double tapped while in normal state. This is the second
+ // tap to disable shift locked state, so just ignore this.
+ }
+ } else {
+ if (mAlphabetShiftState.isShiftLocked()) {
+ // Shift key is pressed while shift locked state, we will treat this state as
+ // shift lock shifted state and mark as if shift key pressed while normal state.
+ setShifted(SHIFT_LOCK_SHIFTED);
+ mShiftKeyState.onPress();
+ } else if (mAlphabetShiftState.isAutomaticShifted()) {
+ // Shift key is pressed while automatic shifted, we have to move to manual
+ // shifted.
+ setShifted(MANUAL_SHIFT);
+ mShiftKeyState.onPress();
+ } else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
+ // In manual shifted state, we just record shift key has been pressing while
+ // shifted state.
+ mShiftKeyState.onPressOnShifted();
+ } else {
+ // In base layout, chording or manual shifted mode is started.
+ setShifted(MANUAL_SHIFT);
+ mShiftKeyState.onPress();
+ }
+ mSwitchActions.startLongPressTimer(Keyboard.CODE_SHIFT);
+ }
+ } else {
+ // In symbol mode, just toggle symbol and symbol more keyboard.
+ toggleShiftInSymbols();
+ mSwitchState = SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
+ mShiftKeyState.onPress();
+ }
+ }
+
+ private void onReleaseShift(boolean withSliding) {
+ if (mIsAlphabetMode) {
+ final boolean isShiftLocked = mAlphabetShiftState.isShiftLocked();
+ mIsInAlphabetUnshiftedFromShifted = false;
+ if (mIsInDoubleTapShiftKey) {
+ // Double tap shift key has been handled in {@link #onPressShift}, so that just
+ // ignore this release shift key here.
+ mIsInDoubleTapShiftKey = false;
+ } else if (mShiftKeyState.isChording()) {
+ if (mAlphabetShiftState.isShiftLockShifted()) {
+ // After chording input while shift locked state.
+ setShiftLocked(true);
+ } else {
+ // After chording input while normal state.
+ setShifted(UNSHIFT);
+ }
+ } else if (mAlphabetShiftState.isShiftLockShifted() && withSliding) {
+ // In shift locked state, shift has been pressed and slid out to other key.
+ setShiftLocked(true);
+ } else if (isShiftLocked && !mAlphabetShiftState.isShiftLockShifted()
+ && (mShiftKeyState.isPressing() || mShiftKeyState.isPressingOnShifted())
+ && !withSliding) {
+ // Shift has been long pressed, ignore this release.
+ } else if (isShiftLocked && !mShiftKeyState.isIgnoring() && !withSliding) {
+ // Shift has been pressed without chording while shift locked state.
+ setShiftLocked(false);
+ } else if (mAlphabetShiftState.isShiftedOrShiftLocked()
+ && mShiftKeyState.isPressingOnShifted() && !withSliding) {
+ // Shift has been pressed without chording while shifted state.
+ setShifted(UNSHIFT);
+ mIsInAlphabetUnshiftedFromShifted = true;
+ } else if (mAlphabetShiftState.isManualShiftedFromAutomaticShifted()
+ && mShiftKeyState.isPressing() && !withSliding) {
+ // Shift has been pressed without chording while manual shifted transited from
+ // automatic shifted
+ setShifted(UNSHIFT);
+ mIsInAlphabetUnshiftedFromShifted = true;
+ }
+ } else {
+ // In symbol mode, switch back to the previous keyboard mode if the user chords the
+ // shift key and another key, then releases the shift key.
+ if (mShiftKeyState.isChording()) {
+ toggleShiftInSymbols();
+ }
+ }
+ mShiftKeyState.onRelease();
+ }
+
+ public void onCancelInput(boolean isSinglePointer) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onCancelInput: single=" + isSinglePointer + " " + this);
+ }
+ // Switch back to the previous keyboard mode if the user cancels sliding input.
+ if (isSinglePointer) {
+ if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) {
+ toggleAlphabetAndSymbols();
+ } else if (mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE) {
+ toggleShiftInSymbols();
+ }
+ }
+ }
+
+ public boolean isInMomentarySwitchState() {
+ return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL
+ || mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
+ }
+
+ private static boolean isSpaceCharacter(int c) {
+ return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER;
+ }
+
+ private boolean isLayoutSwitchBackCharacter(int c) {
+ if (TextUtils.isEmpty(mLayoutSwitchBackSymbols)) return false;
+ if (mLayoutSwitchBackSymbols.indexOf(c) >= 0) return true;
+ return false;
+ }
+
+ public void onCodeInput(int code, boolean isSinglePointer, boolean autoCaps) {
+ if (DEBUG_EVENT) {
+ Log.d(TAG, "onCodeInput: code=" + Keyboard.printableCode(code)
+ + " single=" + isSinglePointer
+ + " autoCaps=" + autoCaps + " " + this);
+ }
+
+ switch (mSwitchState) {
+ case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
+ if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ // Detected only the mode change key has been pressed, and then released.
+ if (mIsAlphabetMode) {
+ mSwitchState = SWITCH_STATE_ALPHA;
+ } else {
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
+ }
+ } else if (isSinglePointer) {
+ // Switch back to the previous keyboard mode if the user pressed the mode change key
+ // and slid to other key, then released the finger.
+ // If the user cancels the sliding input, switching back to the previous keyboard
+ // mode is handled by {@link #onCancelInput}.
+ toggleAlphabetAndSymbols();
+ }
+ break;
+ case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
+ if (code == Keyboard.CODE_SHIFT) {
+ // Detected only the shift key has been pressed on symbol layout, and then released.
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
+ } else if (isSinglePointer) {
+ // Switch back to the previous keyboard mode if the user pressed the shift key on
+ // symbol mode and slid to other key, then released the finger.
+ toggleShiftInSymbols();
+ mSwitchState = SWITCH_STATE_SYMBOL;
+ }
+ break;
+ case SWITCH_STATE_SYMBOL_BEGIN:
+ if (!isSpaceCharacter(code) && (Keyboard.isLetterCode(code)
+ || code == Keyboard.CODE_OUTPUT_TEXT)) {
+ mSwitchState = SWITCH_STATE_SYMBOL;
+ }
+ // Switch back to alpha keyboard mode immediately if user types a quote character.
+ if (isLayoutSwitchBackCharacter(code)) {
+ toggleAlphabetAndSymbols();
+ }
+ break;
+ case SWITCH_STATE_SYMBOL:
+ // Switch back to alpha keyboard mode if user types one or more non-space/enter
+ // characters followed by a space/enter or a quote character.
+ if (isSpaceCharacter(code) || isLayoutSwitchBackCharacter(code)) {
+ toggleAlphabetAndSymbols();
+ }
+ break;
+ }
+
+ // If the code is a letter, update keyboard shift state.
+ if (Keyboard.isLetterCode(code)) {
+ updateAlphabetShiftState(autoCaps);
+ }
+ }
+
+ private static String shiftModeToString(int shiftMode) {
+ switch (shiftMode) {
+ case UNSHIFT: return "UNSHIFT";
+ case MANUAL_SHIFT: return "MANUAL";
+ case AUTOMATIC_SHIFT: return "AUTOMATIC";
+ default: return null;
+ }
+ }
+
+ private static String switchStateToString(int switchState) {
+ switch (switchState) {
+ case SWITCH_STATE_ALPHA: return "ALPHA";
+ case SWITCH_STATE_SYMBOL_BEGIN: return "SYMBOL-BEGIN";
+ case SWITCH_STATE_SYMBOL: return "SYMBOL";
+ case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL: return "MOMENTARY-ALPHA-SYMBOL";
+ case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE: return "MOMENTARY-SYMBOL-MORE";
+ default: return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "[keyboard=" + (mIsAlphabetMode ? mAlphabetShiftState.toString()
+ : (mIsSymbolShifted ? "SYMBOLS_SHIFTED" : "SYMBOLS"))
+ + " shift=" + mShiftKeyState
+ + " symbol=" + mSymbolKeyState
+ + " switch=" + switchStateToString(mSwitchState) + "]";
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
index dae73c4e4..b39b97720 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
@@ -18,15 +18,13 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-
-public class ModifierKeyState {
- protected static final String TAG = "ModifierKeyState";
- protected static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
+/* package */ class ModifierKeyState {
+ protected static final String TAG = ModifierKeyState.class.getSimpleName();
+ protected static final boolean DEBUG = false;
protected static final int RELEASING = 0;
protected static final int PRESSING = 1;
- protected static final int MOMENTARY = 2;
+ protected static final int CHORDING = 2;
protected final String mName;
protected int mState = RELEASING;
@@ -52,7 +50,7 @@ public class ModifierKeyState {
public void onOtherKeyPressed() {
final int oldState = mState;
if (oldState == PRESSING)
- mState = MOMENTARY;
+ mState = CHORDING;
if (DEBUG)
Log.d(TAG, mName + ".onOtherKeyPressed: " + toString(oldState) + " > " + this);
}
@@ -65,8 +63,8 @@ public class ModifierKeyState {
return mState == RELEASING;
}
- public boolean isMomentary() {
- return mState == MOMENTARY;
+ public boolean isChording() {
+ return mState == CHORDING;
}
@Override
@@ -78,7 +76,7 @@ public class ModifierKeyState {
switch (state) {
case RELEASING: return "RELEASING";
case PRESSING: return "PRESSING";
- case MOMENTARY: return "MOMENTARY";
+ case CHORDING: return "CHORDING";
default: return "UNKNOWN";
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpecParser.java
deleted file mode 100644
index a490b0ad6..000000000
--- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpecParser.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.content.res.Resources;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.R;
-
-import java.util.ArrayList;
-
-/**
- * String parser of moreKeys attribute of Key.
- * The string is comma separated texts each of which represents one "more key".
- * 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_number|@integer/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_number.
- */
-public class MoreKeySpecParser {
- private static final String TAG = MoreKeySpecParser.class.getSimpleName();
-
- private static final char ESCAPE = '\\';
- private static final String LABEL_END = "|";
- private static final String PREFIX_AT = "@";
- private static final String PREFIX_ICON = PREFIX_AT + "icon/";
- private static final String PREFIX_CODE = PREFIX_AT + "integer/";
-
- private MoreKeySpecParser() {
- // Intentional empty constructor for utility class.
- }
-
- private static boolean hasIcon(String moreKeySpec) {
- if (moreKeySpec.startsWith(PREFIX_ICON)) {
- final int end = indexOfLabelEnd(moreKeySpec, 0);
- if (end > 0)
- return true;
- throw new MoreKeySpecParserError("outputText or code not specified: " + moreKeySpec);
- }
- return false;
- }
-
- private static boolean hasCode(String moreKeySpec) {
- final int end = indexOfLabelEnd(moreKeySpec, 0);
- if (end > 0 && end + 1 < moreKeySpec.length()
- && moreKeySpec.substring(end + 1).startsWith(PREFIX_CODE)) {
- return true;
- }
- return false;
- }
-
- private static String parseEscape(String text) {
- if (text.indexOf(ESCAPE) < 0)
- return text;
- final int length = text.length();
- final StringBuilder sb = new StringBuilder();
- for (int pos = 0; pos < length; pos++) {
- final char c = text.charAt(pos);
- if (c == ESCAPE && pos + 1 < length) {
- sb.append(text.charAt(++pos));
- } else {
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
- private static int indexOfLabelEnd(String moreKeySpec, int start) {
- if (moreKeySpec.indexOf(ESCAPE, start) < 0) {
- final int end = moreKeySpec.indexOf(LABEL_END, start);
- if (end == 0)
- throw new MoreKeySpecParserError(LABEL_END + " at " + start + ": " + moreKeySpec);
- return end;
- }
- final int length = moreKeySpec.length();
- for (int pos = start; pos < length; pos++) {
- final char c = moreKeySpec.charAt(pos);
- if (c == ESCAPE && pos + 1 < length) {
- pos++;
- } else if (moreKeySpec.startsWith(LABEL_END, pos)) {
- return pos;
- }
- }
- return -1;
- }
-
- public static String getLabel(String moreKeySpec) {
- if (hasIcon(moreKeySpec))
- return null;
- final int end = indexOfLabelEnd(moreKeySpec, 0);
- final String label = (end > 0) ? parseEscape(moreKeySpec.substring(0, end))
- : parseEscape(moreKeySpec);
- if (TextUtils.isEmpty(label))
- throw new MoreKeySpecParserError("Empty label: " + moreKeySpec);
- return label;
- }
-
- public static String getOutputText(String moreKeySpec) {
- if (hasCode(moreKeySpec))
- return null;
- final int end = indexOfLabelEnd(moreKeySpec, 0);
- if (end > 0) {
- if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0)
- throw new MoreKeySpecParserError("Multiple " + LABEL_END + ": "
- + moreKeySpec);
- final String outputText = parseEscape(moreKeySpec.substring(end + LABEL_END.length()));
- if (!TextUtils.isEmpty(outputText))
- return outputText;
- throw new MoreKeySpecParserError("Empty outputText: " + moreKeySpec);
- }
- final String label = getLabel(moreKeySpec);
- if (label == null)
- throw new MoreKeySpecParserError("Empty label: " + moreKeySpec);
- // Code is automatically generated for one letter label. See {@link getCode()}.
- if (label.length() == 1)
- return null;
- return label;
- }
-
- public static int getCode(Resources res, String moreKeySpec) {
- if (hasCode(moreKeySpec)) {
- final int end = indexOfLabelEnd(moreKeySpec, 0);
- if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0)
- throw new MoreKeySpecParserError("Multiple " + LABEL_END + ": " + moreKeySpec);
- final int resId = getResourceId(res,
- moreKeySpec.substring(end + LABEL_END.length() + PREFIX_AT.length()));
- final int code = res.getInteger(resId);
- return code;
- }
- if (indexOfLabelEnd(moreKeySpec, 0) > 0)
- return Keyboard.CODE_DUMMY;
- final String label = getLabel(moreKeySpec);
- // Code is automatically generated for one letter label.
- if (label != null && label.length() == 1)
- return label.charAt(0);
- return Keyboard.CODE_DUMMY;
- }
-
- public static int getIconId(String moreKeySpec) {
- if (hasIcon(moreKeySpec)) {
- int end = moreKeySpec.indexOf(LABEL_END, PREFIX_ICON.length() + 1);
- final String iconId = moreKeySpec.substring(PREFIX_ICON.length(), end);
- try {
- return Integer.valueOf(iconId);
- } catch (NumberFormatException e) {
- Log.w(TAG, "illegal icon id specified: " + iconId);
- return KeyboardIconsSet.ICON_UNDEFINED;
- }
- }
- return KeyboardIconsSet.ICON_UNDEFINED;
- }
-
- private static int getResourceId(Resources res, String name) {
- String packageName = res.getResourcePackageName(R.string.english_ime_name);
- int resId = res.getIdentifier(name, null, packageName);
- if (resId == 0)
- throw new MoreKeySpecParserError("Unknown resource: " + name);
- return resId;
- }
-
- @SuppressWarnings("serial")
- public static class MoreKeySpecParserError extends RuntimeException {
- public MoreKeySpecParserError(String message) {
- super(message);
- }
- }
-
- public interface CodeFilter {
- public boolean shouldFilterOut(int code);
- }
-
- public static final CodeFilter DIGIT_FILTER = new CodeFilter() {
- @Override
- public boolean shouldFilterOut(int code) {
- return Character.isDigit(code);
- }
- };
-
- public static CharSequence[] filterOut(Resources res, CharSequence[] moreKeys,
- CodeFilter filter) {
- if (moreKeys == null || moreKeys.length < 1) {
- return null;
- }
- if (moreKeys.length == 1
- && filter.shouldFilterOut(getCode(res, moreKeys[0].toString()))) {
- return null;
- }
- ArrayList<CharSequence> filtered = null;
- for (int i = 0; i < moreKeys.length; i++) {
- final CharSequence moreKeySpec = moreKeys[i];
- if (filter.shouldFilterOut(getCode(res, moreKeySpec.toString()))) {
- if (filtered == null) {
- filtered = new ArrayList<CharSequence>();
- for (int j = 0; j < i; j++) {
- filtered.add(moreKeys[j]);
- }
- }
- } else if (filtered != null) {
- filtered.add(moreKeySpec);
- }
- }
- if (filtered == null) {
- return moreKeys;
- }
- if (filtered.size() == 0) {
- return null;
- }
- return filtered.toArray(new CharSequence[filtered.size()]);
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index 08e7a7a4e..d9181f786 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard.internal;
import com.android.inputmethod.keyboard.PointerTracker;
+import java.util.Iterator;
import java.util.LinkedList;
public class PointerTrackerQueue {
@@ -27,18 +28,23 @@ public class PointerTrackerQueue {
mQueue.add(tracker);
}
+ public synchronized void remove(PointerTracker tracker) {
+ mQueue.remove(tracker);
+ }
+
public synchronized void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) {
- if (mQueue.lastIndexOf(tracker) < 0) {
+ if (!mQueue.contains(tracker)) {
return;
}
- final LinkedList<PointerTracker> queue = mQueue;
- int oldestPos = 0;
- for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) {
- if (t.isModifier()) {
- oldestPos++;
- } else {
+ final Iterator<PointerTracker> it = mQueue.iterator();
+ while (it.hasNext()) {
+ final PointerTracker t = it.next();
+ if (t == tracker) {
+ break;
+ }
+ if (!t.isModifier()) {
t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime);
- queue.remove(oldestPos);
+ it.remove();
}
}
}
@@ -48,22 +54,16 @@ public class PointerTrackerQueue {
}
public synchronized void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
- for (PointerTracker t : mQueue) {
- if (t == tracker) {
- continue;
+ final Iterator<PointerTracker> it = mQueue.iterator();
+ while (it.hasNext()) {
+ final PointerTracker t = it.next();
+ if (t != tracker) {
+ t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime);
+ it.remove();
}
- t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime);
- }
- mQueue.clear();
- if (tracker != null) {
- mQueue.add(tracker);
}
}
- public synchronized void remove(PointerTracker tracker) {
- mQueue.remove(tracker);
- }
-
public synchronized boolean isAnyInSlidingKeyInput() {
for (final PointerTracker tracker : mQueue) {
if (tracker.isInSlidingKeyInput()) {
@@ -75,13 +75,12 @@ public class PointerTrackerQueue {
@Override
public String toString() {
- StringBuilder sb = new StringBuilder("[");
- for (PointerTracker tracker : mQueue) {
- if (sb.length() > 1)
+ final StringBuilder sb = new StringBuilder();
+ for (final PointerTracker tracker : mQueue) {
+ if (sb.length() > 0)
sb.append(" ");
- sb.append(String.format("%d", tracker.mPointerId));
+ sb.append(tracker.mPointerId);
}
- sb.append("]");
- return sb.toString();
+ return "[" + sb + "]";
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
index 6617b917f..edb40c8e7 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
-public class ShiftKeyState extends ModifierKeyState {
+/* package */ class ShiftKeyState extends ModifierKeyState {
private static final int PRESSING_ON_SHIFTED = 3; // both temporary shifted & shift locked
private static final int IGNORING = 4;
@@ -30,7 +30,7 @@ public class ShiftKeyState extends ModifierKeyState {
public void onOtherKeyPressed() {
int oldState = mState;
if (oldState == PRESSING) {
- mState = MOMENTARY;
+ mState = CHORDING;
} else if (oldState == PRESSING_ON_SHIFTED) {
mState = IGNORING;
}
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
index 485ec511f..bcb78919d 100644
--- a/java/src/com/android/inputmethod/latin/AutoCorrection.java
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -74,6 +74,14 @@ public class AutoCorrection {
for (final String key : dictionaries.keySet()) {
if (key.equals(Suggest.DICT_KEY_WHITELIST)) continue;
final Dictionary dictionary = dictionaries.get(key);
+ // It's unclear how realistically 'dictionary' can be null, but the monkey is somehow
+ // managing to get null in here. Presumably the language is changing to a language with
+ // no main dictionary and the monkey manages to type a whole word before the thread
+ // that reads the dictionary is started or something?
+ // Ideally the passed map would come out of a {@link java.util.concurrent.Future} and
+ // would be immutable once it's finished initializing, but concretely a null test is
+ // probably good enough for the time being.
+ if (null == dictionary) continue;
if (dictionary.isValidWord(word)
|| (ignoreCase && dictionary.isValidWord(lowerCasedWord))) {
return true;
@@ -98,7 +106,7 @@ public class AutoCorrection {
return whiteListedWord != null;
}
- private boolean hasAutoCorrectionForTypedWord(Map<String, Dictionary> dictionaries,
+ private static boolean hasAutoCorrectionForTypedWord(Map<String, Dictionary> dictionaries,
WordComposer wordComposer, ArrayList<CharSequence> suggestions, CharSequence typedWord,
int correctionMode) {
if (TextUtils.isEmpty(typedWord)) return false;
@@ -118,8 +126,9 @@ public class AutoCorrection {
final int autoCorrectionSuggestionScore = sortedScores[0];
// TODO: when the normalized score of the first suggestion is nearly equals to
// the normalized score of the second suggestion, behave less aggressive.
- mNormalizedScore = Utils.calcNormalizedScore(
- typedWord,autoCorrectionSuggestion, autoCorrectionSuggestionScore);
+ mNormalizedScore = BinaryDictionary.calcNormalizedScore(
+ typedWord.toString(), autoCorrectionSuggestion.toString(),
+ autoCorrectionSuggestionScore);
if (DBG) {
Log.d(TAG, "Normalized " + typedWord + "," + autoCorrectionSuggestion + ","
+ autoCorrectionSuggestionScore + ", " + mNormalizedScore
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index b9fd57434..b82400046 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -46,7 +46,7 @@ public class BinaryDictionary extends Dictionary {
private static final int TYPED_LETTER_MULTIPLIER = 2;
private int mDicTypeId;
- private int mNativeDict;
+ private long mNativeDict;
private final int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_PROXIMITY_CHARS_SIZE];
private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS];
@@ -107,17 +107,21 @@ public class BinaryDictionary extends Dictionary {
Utils.loadNativeLibrary();
}
- private native int openNative(String sourceDir, long dictOffset, long dictSize,
+ private native long openNative(String sourceDir, long dictOffset, long dictSize,
int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength,
int maxWords, int maxAlternatives);
- private native void closeNative(int dict);
- private native boolean isValidWordNative(int nativeData, char[] word, int wordLength);
- private native int getSuggestionsNative(int dict, int proximityInfo, int[] xCoordinates,
+ private native void closeNative(long dict);
+ private native boolean isValidWordNative(long dict, char[] word, int wordLength);
+ private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates,
int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars,
int[] scores);
- private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength,
+ private native int getBigramsNative(long dict, char[] prevWord, int prevWordLength,
int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores,
int maxWordLength, int maxBigrams, int maxAlternatives);
+ private static native double calcNormalizedScoreNative(
+ char[] before, int beforeLength, char[] after, int afterLength, int score);
+ private static native int editDistanceNative(
+ char[] before, int beforeLength, char[] after, int afterLength);
private final void loadDictionary(String path, long startOffset, long length) {
mNativeDict = openNative(path, startOffset, length,
@@ -158,7 +162,7 @@ public class BinaryDictionary extends Dictionary {
}
if (len > 0) {
callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j],
- mDicTypeId, DataType.BIGRAM);
+ mDicTypeId, Dictionary.BIGRAM);
}
}
}
@@ -178,7 +182,7 @@ public class BinaryDictionary extends Dictionary {
}
if (len > 0) {
callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId,
- DataType.UNIGRAM);
+ Dictionary.UNIGRAM);
}
}
}
@@ -211,6 +215,16 @@ public class BinaryDictionary extends Dictionary {
mFlags, outputChars, scores);
}
+ public static double calcNormalizedScore(String before, String after, int score) {
+ return calcNormalizedScoreNative(before.toCharArray(), before.length(),
+ after.toCharArray(), after.length(), score);
+ }
+
+ public static int editDistance(String before, String after) {
+ return editDistanceNative(
+ before.toCharArray(), before.length(), after.toCharArray(), after.length());
+ }
+
@Override
public boolean isValidWord(CharSequence word) {
if (word == null) return false;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index b333e4873..79441c557 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -75,7 +75,8 @@ class BinaryDictionaryGetter {
// This assumes '%' is fully available as a non-separator, normal
// character in a file name. This is probably true for all file systems.
final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < name.length(); ++i) {
+ final int nameLength = name.length();
+ for (int i = 0; i < nameLength; i = name.offsetByCodePoints(i, 1)) {
final int codePoint = name.codePointAt(i);
if (isFileNameCharacter(codePoint)) {
sb.appendCodePoint(codePoint);
@@ -92,7 +93,8 @@ class BinaryDictionaryGetter {
*/
private static String getWordListIdFromFileName(final String fname) {
final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < fname.length(); ++i) {
+ final int fnameLength = fname.length();
+ for (int i = 0; i < fnameLength; i = fname.offsetByCodePoints(i, 1)) {
final int codePoint = fname.codePointAt(i);
if ('%' != codePoint) {
sb.appendCodePoint(codePoint);
diff --git a/java/src/com/android/inputmethod/latin/ComposingStateManager.java b/java/src/com/android/inputmethod/latin/ComposingStateManager.java
index 8811f2023..27f509a29 100644
--- a/java/src/com/android/inputmethod/latin/ComposingStateManager.java
+++ b/java/src/com/android/inputmethod/latin/ComposingStateManager.java
@@ -53,6 +53,13 @@ public class ComposingStateManager {
}
}
+ public synchronized boolean isComposing() {
+ // TODO: use the composing flag in WordComposer instead of maintaining it
+ // here separately. Even better, do away with this class and manage the auto
+ // correction indicator in the same place as the suggestions.
+ return mIsComposing;
+ }
+
public synchronized boolean isAutoCorrectionIndicatorOn() {
return mAutoCorrectionIndicatorOn;
}
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index 2f1e7c2b8..3805da154 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -30,6 +30,7 @@ public class DebugSettings extends PreferenceActivity
private static final String TAG = "DebugSettings";
private static final String DEBUG_MODE_KEY = "debug_mode";
+ public static final String FORCE_NON_DISTINCT_MULTITOUCH_KEY = "force_non_distinct_multitouch";
private boolean mServiceNeedsRestart = false;
private CheckBoxPreference mDebugMode;
@@ -60,6 +61,8 @@ public class DebugSettings extends PreferenceActivity
updateDebugMode();
mServiceNeedsRestart = true;
}
+ } else if (key.equals(FORCE_NON_DISTINCT_MULTITOUCH_KEY)) {
+ mServiceNeedsRestart = true;
}
}
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index c35b42877..79bf33850 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -33,9 +33,8 @@ public abstract class Dictionary {
*/
protected static final int FULL_WORD_SCORE_MULTIPLIER = 2;
- public static enum DataType {
- UNIGRAM, BIGRAM
- }
+ public static final int UNIGRAM = 0;
+ public static final int BIGRAM = 1;
/**
* Interface to be implemented by classes requesting words to be fetched from the dictionary.
@@ -51,11 +50,11 @@ public abstract class Dictionary {
* @param score the score of occurrence. This is normalized between 1 and 255, but
* can exceed those limits
* @param dicTypeId of the dictionary where word was from
- * @param dataType tells type of this data
+ * @param dataType tells type of this data, either UNIGRAM or BIGRAM
* @return true if the word was added, false if no more words are required
*/
boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId,
- DataType dataType);
+ int dataType);
}
/**
@@ -64,7 +63,7 @@ public abstract class Dictionary {
* @param composer the key sequence to match
* @param callback the callback object to send matched words to as possible candidates
* @param proximityInfo the object for key proximity. May be ignored by some implementations.
- * @see WordCallback#addWord(char[], int, int, int, int, DataType)
+ * @see WordCallback#addWord(char[], int, int, int, int, int)
*/
abstract public void getWords(final WordComposer composer, final WordCallback callback,
final ProximityInfo proximityInfo);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 739153044..c19a5a718 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -18,6 +18,8 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.ProximityInfo;
+import android.util.Log;
+
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -27,7 +29,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
* Class for a collection of dictionaries that behave like one dictionary.
*/
public class DictionaryCollection extends Dictionary {
-
+ private final String TAG = DictionaryCollection.class.getSimpleName();
protected final List<Dictionary> mDictionaries;
public DictionaryCollection() {
@@ -75,7 +77,21 @@ public class DictionaryCollection extends Dictionary {
dict.close();
}
- public void addDictionary(Dictionary newDict) {
- if (null != newDict) mDictionaries.add(newDict);
+ // Warning: this is not thread-safe. Take necessary precaution when calling.
+ public void addDictionary(final Dictionary newDict) {
+ if (null == newDict) return;
+ if (mDictionaries.contains(newDict)) {
+ Log.w(TAG, "This collection already contains this dictionary: " + newDict);
+ }
+ mDictionaries.add(newDict);
+ }
+
+ // Warning: this is not thread-safe. Take necessary precaution when calling.
+ public void removeDictionary(final Dictionary dict) {
+ if (mDictionaries.contains(dict)) {
+ mDictionaries.remove(dict);
+ } else {
+ Log.w(TAG, "This collection does not contain this dictionary: " + dict);
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index 634dbbdfc..1e8ad1840 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -87,23 +87,6 @@ public class EditingUtils {
}
/**
- * Removes the word surrounding the cursor. Parameters are identical to
- * getWordAtCursor.
- */
- public static void deleteWordAtCursor(InputConnection connection, String separators) {
- // getWordRangeAtCursor returns null if the connection is null
- Range range = getWordRangeAtCursor(connection, separators);
- if (range == null) return;
-
- connection.finishComposingText();
- // Move cursor to beginning of word, to avoid crash when cursor is outside
- // of valid range after deleting text.
- int newCursor = getCursorPosition(connection) - range.mCharsBefore;
- connection.setSelection(newCursor, newCursor);
- connection.deleteSurroundingText(0, range.mCharsBefore + range.mCharsAfter);
- }
-
- /**
* Represents a range of text, relative to the current cursor position.
*/
public static class Range {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index cad69bb0e..8e8adc1c2 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -51,6 +51,7 @@ public class ExpandableDictionary extends Dictionary {
private Object mUpdatingLock = new Object();
private static class Node {
+ Node() {}
char mCode;
int mFrequency;
boolean mTerminal;
@@ -300,7 +301,7 @@ public class ExpandableDictionary extends Dictionary {
finalFreq = computeSkippedWordFinalFreq(freq, snr, mInputLength);
}
if (!callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId,
- DataType.UNIGRAM)) {
+ Dictionary.UNIGRAM)) {
return;
}
}
@@ -341,7 +342,7 @@ public class ExpandableDictionary extends Dictionary {
snr * addedAttenuation, mInputLength);
}
callback.addWord(word, 0, depth + 1, finalFreq, mDicTypeId,
- DataType.UNIGRAM);
+ Dictionary.UNIGRAM);
}
}
if (children != null) {
@@ -505,7 +506,7 @@ public class ExpandableDictionary extends Dictionary {
} while (node != null);
callback.addWord(mLookedUpString, index, MAX_WORD_LENGTH - index, freq, mDicTypeId,
- DataType.BIGRAM);
+ Dictionary.BIGRAM);
}
}
@@ -547,6 +548,7 @@ public class ExpandableDictionary extends Dictionary {
}
private class LoadDictionaryTask extends Thread {
+ LoadDictionaryTask() {}
@Override
public void run() {
loadDictionaryAsync();
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
new file mode 100644
index 000000000..3de5c1d48
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 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.latin;
+
+import android.text.InputType;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.inputmethod.compat.InputTypeCompatUtils;
+
+/**
+ * Class to hold attributes of the input field.
+ */
+public class InputAttributes {
+ private final String TAG = InputAttributes.class.getSimpleName();
+
+ final public boolean mInputTypeNoAutoCorrect;
+ final public boolean mIsSettingsSuggestionStripOn;
+ final public boolean mApplicationSpecifiedCompletionOn;
+
+ public InputAttributes(final EditorInfo editorInfo, final boolean isFullscreenMode) {
+ final int inputType = null != editorInfo ? editorInfo.inputType : 0;
+ final int inputClass = inputType & InputType.TYPE_MASK_CLASS;
+ if (inputClass != InputType.TYPE_CLASS_TEXT) {
+ // If we are not looking at a TYPE_CLASS_TEXT field, the following strange
+ // cases may arise, so we do a couple sanity checks for them. If it's a
+ // TYPE_CLASS_TEXT field, these special cases cannot happen, by construction
+ // of the flags.
+ if (null == editorInfo) {
+ Log.w(TAG, "No editor info for this field. Bug?");
+ } else if (InputType.TYPE_NULL == inputType) {
+ // TODO: We should honor TYPE_NULL specification.
+ Log.i(TAG, "InputType.TYPE_NULL is specified");
+ } else if (inputClass == 0) {
+ // TODO: is this check still necessary?
+ Log.w(TAG, String.format("Unexpected input class: inputType=0x%08x"
+ + " imeOptions=0x%08x",
+ inputType, editorInfo.imeOptions));
+ }
+ mIsSettingsSuggestionStripOn = false;
+ mInputTypeNoAutoCorrect = false;
+ mApplicationSpecifiedCompletionOn = false;
+ } else {
+ final int variation = inputType & InputType.TYPE_MASK_VARIATION;
+ final boolean flagNoSuggestions =
+ 0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
+ final boolean flagMultiLine =
+ 0 != (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE);
+ final boolean flagAutoCorrect =
+ 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
+ final boolean flagAutoComplete =
+ 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
+
+ // Make sure that passwords are not displayed in {@link SuggestionsView}.
+ if (InputTypeCompatUtils.isPasswordInputType(inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)
+ || InputTypeCompatUtils.isEmailVariation(variation)
+ || InputType.TYPE_TEXT_VARIATION_URI == variation
+ || InputType.TYPE_TEXT_VARIATION_FILTER == variation
+ || flagNoSuggestions
+ || flagAutoComplete) {
+ mIsSettingsSuggestionStripOn = false;
+ } else {
+ mIsSettingsSuggestionStripOn = true;
+ }
+
+ // If it's a browser edit field and auto correct is not ON explicitly, then
+ // disable auto correction, but keep suggestions on.
+ // If NO_SUGGESTIONS is set, don't do prediction.
+ // If it's not multiline and the autoCorrect flag is not set, then don't correct
+ if ((variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT
+ && !flagAutoCorrect)
+ || flagNoSuggestions
+ || (!flagAutoCorrect && !flagMultiLine)) {
+ mInputTypeNoAutoCorrect = true;
+ } else {
+ mInputTypeNoAutoCorrect = false;
+ }
+
+ mApplicationSpecifiedCompletionOn = flagAutoComplete && isFullscreenMode;
+ }
+ }
+
+ // Pretty print
+ @Override
+ public String toString() {
+ return "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect
+ + "\n mIsSettingsSuggestionStripOn = " + mIsSettingsSuggestionStripOn
+ + "\n mApplicationSpecifiedCompletionOn = " + mApplicationSpecifiedCompletionOn;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
new file mode 100644
index 000000000..f34cb5ff9
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -0,0 +1,74 @@
+/*
+ * 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.latin;
+
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+
+/**
+ * This class encapsulates data about a word previously composed, but that has been
+ * committed already. This is used for resuming suggestion, and cancel auto-correction.
+ */
+public class LastComposedWord {
+ // COMMIT_TYPE_USER_TYPED_WORD is used when the word committed is the exact typed word, with
+ // no hinting from the IME. It happens when some external event happens (rotating the device,
+ // for example) or when auto-correction is off by settings or editor attributes.
+ public static final int COMMIT_TYPE_USER_TYPED_WORD = 0;
+ // COMMIT_TYPE_MANUAL_PICK is used when the user pressed a field in the suggestion strip.
+ public static final int COMMIT_TYPE_MANUAL_PICK = 1;
+ // COMMIT_TYPE_DECIDED_WORD is used when the IME commits the word it decided was best
+ // for the current user input. It may be different from what the user typed (true auto-correct)
+ // or it may be exactly what the user typed if it's in the dictionary or the IME does not have
+ // enough confidence in any suggestion to auto-correct (auto-correct to typed word).
+ public static final int COMMIT_TYPE_DECIDED_WORD = 2;
+ // COMMIT_TYPE_CANCEL_AUTO_CORRECT is used upon committing back the old word upon cancelling
+ // an auto-correction.
+ public static final int COMMIT_TYPE_CANCEL_AUTO_CORRECT = 3;
+
+ public final ArrayList<int[]> mCodes;
+ public final int[] mXCoordinates;
+ public final int[] mYCoordinates;
+ public final String mTypedWord;
+ public final String mAutoCorrection;
+
+ private boolean mActive;
+
+ public static final LastComposedWord NOT_A_COMPOSED_WORD =
+ new LastComposedWord(null, null, null, "", "");
+
+ // Warning: this is using the passed objects as is and fully expects them to be
+ // immutable. Do not fiddle with their contents after you passed them to this constructor.
+ public LastComposedWord(final ArrayList<int[]> codes, final int[] xCoordinates,
+ final int[] yCoordinates, final String typedWord, final String autoCorrection) {
+ mCodes = codes;
+ mXCoordinates = xCoordinates;
+ mYCoordinates = yCoordinates;
+ mTypedWord = typedWord;
+ mAutoCorrection = autoCorrection;
+ mActive = true;
+ }
+
+ public void deactivate() {
+ mActive = false;
+ }
+
+ public boolean canCancelAutoCorrect() {
+ return mActive && !TextUtils.isEmpty(mAutoCorrection)
+ && !TextUtils.equals(mTypedWord, mAutoCorrection);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 9c321bcb9..1cb79e707 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -49,6 +49,7 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.InputConnection;
import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.compat.InputConnectionCompatUtils;
@@ -59,13 +60,13 @@ import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
+import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.LatinKeyboard;
import com.android.inputmethod.keyboard.LatinKeyboardView;
+import com.android.inputmethod.latin.suggestions.SuggestionsView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -77,7 +78,6 @@ import java.util.Locale;
public class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener,
SuggestionsView.Listener {
private static final String TAG = LatinIME.class.getSimpleName();
- private static final boolean PERF_DEBUG = false;
private static final boolean TRACE = false;
private static boolean DEBUG;
@@ -107,7 +107,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
/**
* The private IME option used to indicate that the given text field needs
* ASCII code points input.
+ *
+ * @deprecated Use {@link EditorInfo#IME_FLAG_FORCE_ASCII}.
*/
+ @SuppressWarnings("dep-ann")
public static final String IME_OPTION_FORCE_ASCII = "forceAscii";
/**
@@ -143,6 +146,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
*/
private static final String SCHEME_PACKAGE = "package";
+ // TODO: migrate this to SettingsValues
private int mSuggestionVisibility;
private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE
= R.string.prefs_suggestion_visibility_show_value;
@@ -157,19 +161,38 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
SUGGESTION_VISIBILILTY_HIDE_VALUE
};
- private Settings.Values mSettingsValues;
+ private static final int SPACE_STATE_NONE = 0;
+ // Double space: the state where the user pressed space twice quickly, which LatinIME
+ // resolved as period-space. Undoing this converts the period to a space.
+ private static final int SPACE_STATE_DOUBLE = 1;
+ // Swap punctuation: the state where a (weak or magic) space and a punctuation from the
+ // suggestion strip have just been swapped. Undoing this swaps them back.
+ private static final int SPACE_STATE_SWAP_PUNCTUATION = 2;
+ // Weak space: a space that should be swapped only by suggestion strip punctuation. Weak
+ // spaces happen when the user presses space, accepting the current suggestion (whether
+ // it's an auto-correction or not).
+ private static final int SPACE_STATE_WEAK = 3;
+ // Phantom space: a not-yet-inserted space that should get inserted on the next input,
+ // character provided it's not a separator. If it's a separator, the phantom space is dropped.
+ // Phantom spaces happen when a user chooses a word from the suggestion strip.
+ private static final int SPACE_STATE_PHANTOM = 4;
+
+ // Current space state of the input method. This can be any of the above constants.
+ private int mSpaceState;
+
+ private SettingsValues mSettingsValues;
+ private InputAttributes mInputAttributes;
private View mExtractArea;
private View mKeyPreviewBackingView;
private View mSuggestionsContainer;
private SuggestionsView mSuggestionsView;
- private Suggest mSuggest;
+ /* package for tests */ Suggest mSuggest;
private CompletionInfo[] mApplicationSpecifiedCompletions;
private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
- private String mInputMethodId;
private KeyboardSwitcher mKeyboardSwitcher;
private SubtypeSwitcher mSubtypeSwitcher;
private VoiceProxy mVoiceProxy;
@@ -177,31 +200,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private UserDictionary mUserDictionary;
private UserBigramDictionary mUserBigramDictionary;
private UserUnigramDictionary mUserUnigramDictionary;
- private boolean mIsUserDictionaryAvaliable;
-
- // TODO: Create an inner class to group options and pseudo-options to improve readability.
- // These variables are initialized according to the {@link EditorInfo#inputType}.
- private boolean mInsertSpaceOnPickSuggestionManually;
- private boolean mInputTypeNoAutoCorrect;
- private boolean mIsSettingsSuggestionStripOn;
- private boolean mApplicationSpecifiedCompletionOn;
+ private boolean mIsUserDictionaryAvailable;
- private final StringBuilder mComposingStringBuilder = new StringBuilder();
+ private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
private WordComposer mWordComposer = new WordComposer();
- private CharSequence mBestWord;
- private boolean mHasUncommittedTypedChars;
- // Magic space: a space that should disappear on space/apostrophe insertion, move after the
- // punctuation on punctuation insertion, and become a real space on alpha char insertion.
- private boolean mJustAddedMagicSpace; // This indicates whether the last char is a magic space.
- // This indicates whether the last keypress resulted in processing of double space replacement
- // with period-space.
- private boolean mJustReplacedDoubleSpace;
private int mCorrectionMode;
- private int mCommittedLength;
+
// Keep track of the last selection range to decide if we need to show word alternatives
- private int mLastSelectionStart;
- private int mLastSelectionEnd;
+ private static final int NOT_A_CURSOR_POSITION = -1;
+ private int mLastSelectionStart = NOT_A_CURSOR_POSITION;
+ private int mLastSelectionEnd = NOT_A_CURSOR_POSITION;
// Whether we are expecting an onUpdateSelection event to fire. If it does when we don't
// "expect" it, it means the user actually moved the cursor.
@@ -210,11 +219,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private long mLastKeyTime;
private AudioManager mAudioManager;
- private float mFxVolume = -1.0f; // default volume
private boolean mSilentModeOn; // System-wide current configuration
private VibratorCompatWrapper mVibrator;
- private long mKeypressVibrationDuration = -1;
// TODO: Move this flag to VoiceProxy
private boolean mConfigurationChanging;
@@ -241,9 +248,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 3;
private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 4;
private static final int MSG_SPACE_TYPED = 5;
- private static final int MSG_KEY_TYPED = 6;
- private static final int MSG_SET_BIGRAM_PREDICTIONS = 7;
- private static final int MSG_PENDING_IMS_CALLBACK = 8;
+ private static final int MSG_SET_BIGRAM_PREDICTIONS = 6;
+ private static final int MSG_PENDING_IMS_CALLBACK = 7;
private int mDelayBeforeFadeoutLanguageOnSpacebar;
private int mDelayUpdateSuggestions;
@@ -251,7 +257,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private int mDurationOfFadeoutLanguageOnSpacebar;
private float mFinalFadeoutFactorOfLanguageOnSpacebar;
private long mDoubleSpacesTurnIntoPeriodTimeout;
- private long mIgnoreSpecialKeyTimeout;
public UIHandler(LatinIME outerInstance) {
super(outerInstance);
@@ -271,8 +276,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f;
mDoubleSpacesTurnIntoPeriodTimeout = res.getInteger(
R.integer.config_double_spaces_turn_into_period_timeout);
- mIgnoreSpecialKeyTimeout = res.getInteger(
- R.integer.config_ignore_special_key_timeout);
}
@Override
@@ -291,23 +294,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
latinIme.updateBigramPredictions();
break;
case MSG_VOICE_RESULTS:
+ final Keyboard keyboard = switcher.getKeyboard();
latinIme.mVoiceProxy.handleVoiceResults(latinIme.preferCapitalization()
- || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked()));
+ || (keyboard != null && keyboard.isShiftedOrShiftLocked()));
break;
case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR:
- if (inputView != null) {
- inputView.setSpacebarTextFadeFactor(
- (1.0f + mFinalFadeoutFactorOfLanguageOnSpacebar) / 2,
- (LatinKeyboard)msg.obj);
- }
+ setSpacebarTextFadeFactor(inputView,
+ (1.0f + mFinalFadeoutFactorOfLanguageOnSpacebar) / 2,
+ (Keyboard)msg.obj);
sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj),
mDurationOfFadeoutLanguageOnSpacebar);
break;
case MSG_DISMISS_LANGUAGE_ON_SPACEBAR:
- if (inputView != null) {
- inputView.setSpacebarTextFadeFactor(mFinalFadeoutFactorOfLanguageOnSpacebar,
- (LatinKeyboard)msg.obj);
- }
+ setSpacebarTextFadeFactor(inputView, mFinalFadeoutFactorOfLanguageOnSpacebar,
+ (Keyboard)msg.obj);
break;
}
}
@@ -347,21 +347,32 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
sendMessage(obtainMessage(MSG_VOICE_RESULTS));
}
+ private static void setSpacebarTextFadeFactor(LatinKeyboardView inputView,
+ float fadeFactor, Keyboard oldKeyboard) {
+ if (inputView == null) return;
+ final Keyboard keyboard = inputView.getKeyboard();
+ if (keyboard == oldKeyboard) {
+ inputView.updateSpacebar(fadeFactor,
+ SubtypeSwitcher.getInstance().needsToDisplayLanguage(
+ keyboard.mId.mLocale));
+ }
+ }
+
public void startDisplayLanguageOnSpacebar(boolean localeChanged) {
final LatinIME latinIme = getOuterInstance();
removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR);
removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR);
final LatinKeyboardView inputView = latinIme.mKeyboardSwitcher.getKeyboardView();
if (inputView != null) {
- final LatinKeyboard keyboard = latinIme.mKeyboardSwitcher.getLatinKeyboard();
+ final Keyboard keyboard = latinIme.mKeyboardSwitcher.getKeyboard();
// The language is always displayed when the delay is negative.
final boolean needsToDisplayLanguage = localeChanged
|| mDelayBeforeFadeoutLanguageOnSpacebar < 0;
// The language is never displayed when the delay is zero.
if (mDelayBeforeFadeoutLanguageOnSpacebar != 0) {
- inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f
- : mFinalFadeoutFactorOfLanguageOnSpacebar,
- keyboard);
+ setSpacebarTextFadeFactor(inputView,
+ needsToDisplayLanguage ? 1.0f : mFinalFadeoutFactorOfLanguageOnSpacebar,
+ keyboard);
}
// The fadeout animation will start when the delay is positive.
if (localeChanged && mDelayBeforeFadeoutLanguageOnSpacebar > 0) {
@@ -384,21 +395,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return hasMessages(MSG_SPACE_TYPED);
}
- public void startKeyTypedTimer() {
- removeMessages(MSG_KEY_TYPED);
- sendMessageDelayed(obtainMessage(MSG_KEY_TYPED), mIgnoreSpecialKeyTimeout);
- }
-
- public boolean isIgnoringSpecialKey() {
- return hasMessages(MSG_KEY_TYPED);
- }
-
// Working variables for the following methods.
private boolean mIsOrientationChanging;
- private boolean mPendingSuccesiveImsCallback;
+ private boolean mPendingSuccessiveImsCallback;
private boolean mHasPendingStartInput;
private boolean mHasPendingFinishInputView;
private boolean mHasPendingFinishInput;
+ private EditorInfo mAppliedEditorInfo;
public void startOrientationChanging() {
removeMessages(MSG_PENDING_IMS_CALLBACK);
@@ -416,18 +419,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHasPendingStartInput = false;
}
- private void executePendingImsCallback(LatinIME latinIme, EditorInfo attribute,
+ private void executePendingImsCallback(LatinIME latinIme, EditorInfo editorInfo,
boolean restarting) {
if (mHasPendingFinishInputView)
latinIme.onFinishInputViewInternal(mHasPendingFinishInput);
if (mHasPendingFinishInput)
latinIme.onFinishInputInternal();
if (mHasPendingStartInput)
- latinIme.onStartInputInternal(attribute, restarting);
+ latinIme.onStartInputInternal(editorInfo, restarting);
resetPendingImsCallback();
}
- public void onStartInput(EditorInfo attribute, boolean restarting) {
+ public void onStartInput(EditorInfo editorInfo, boolean restarting) {
if (hasMessages(MSG_PENDING_IMS_CALLBACK)) {
// Typically this is the second onStartInput after orientation changed.
mHasPendingStartInput = true;
@@ -435,30 +438,32 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (mIsOrientationChanging && restarting) {
// This is the first onStartInput after orientation changed.
mIsOrientationChanging = false;
- mPendingSuccesiveImsCallback = true;
+ mPendingSuccessiveImsCallback = true;
}
final LatinIME latinIme = getOuterInstance();
- executePendingImsCallback(latinIme, attribute, restarting);
- latinIme.onStartInputInternal(attribute, restarting);
+ executePendingImsCallback(latinIme, editorInfo, restarting);
+ latinIme.onStartInputInternal(editorInfo, restarting);
}
}
- public void onStartInputView(EditorInfo attribute, boolean restarting) {
- if (hasMessages(MSG_PENDING_IMS_CALLBACK)) {
- // Typically this is the second onStartInputView after orientation changed.
- resetPendingImsCallback();
- } else {
- if (mPendingSuccesiveImsCallback) {
- // This is the first onStartInputView after orientation changed.
- mPendingSuccesiveImsCallback = false;
- resetPendingImsCallback();
- sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK),
- PENDING_IMS_CALLBACK_DURATION);
- }
- final LatinIME latinIme = getOuterInstance();
- executePendingImsCallback(latinIme, attribute, restarting);
- latinIme.onStartInputViewInternal(attribute, restarting);
- }
+ public void onStartInputView(EditorInfo editorInfo, boolean restarting) {
+ if (hasMessages(MSG_PENDING_IMS_CALLBACK)
+ && KeyboardId.equivalentEditorInfoForKeyboard(editorInfo, mAppliedEditorInfo)) {
+ // Typically this is the second onStartInputView after orientation changed.
+ resetPendingImsCallback();
+ } else {
+ if (mPendingSuccessiveImsCallback) {
+ // This is the first onStartInputView after orientation changed.
+ mPendingSuccessiveImsCallback = false;
+ resetPendingImsCallback();
+ sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK),
+ PENDING_IMS_CALLBACK_DURATION);
+ }
+ final LatinIME latinIme = getOuterInstance();
+ executePendingImsCallback(latinIme, editorInfo, restarting);
+ latinIme.onStartInputViewInternal(editorInfo, restarting);
+ mAppliedEditorInfo = editorInfo;
+ }
}
public void onFinishInputView(boolean finishingInput) {
@@ -468,6 +473,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else {
final LatinIME latinIme = getOuterInstance();
latinIme.onFinishInputViewInternal(finishingInput);
+ mAppliedEditorInfo = null;
}
}
@@ -492,12 +498,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
InputMethodManagerCompatWrapper.init(this);
SubtypeSwitcher.init(this);
KeyboardSwitcher.init(this, prefs);
- AccessibilityUtils.init(this, prefs);
+ AccessibilityUtils.init(this);
super.onCreate();
mImm = InputMethodManagerCompatWrapper.getInstance();
- mInputMethodId = Utils.getInputMethodId(mImm, getPackageName());
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mVibrator = VibratorCompatWrapper.getInstance(this);
@@ -509,6 +514,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
loadSettings();
+ // TODO: remove the following when it's not needed by updateCorrectionMode() any more
+ mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
Utils.GCUtils.getInstance().reset();
boolean tryGC = true;
for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
@@ -546,10 +553,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
/* package */ void loadSettings() {
if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
if (null == mSubtypeSwitcher) mSubtypeSwitcher = SubtypeSwitcher.getInstance();
- mSettingsValues = new Settings.Values(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr());
+ mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr());
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
- updateSoundEffectVolume();
- updateKeypressVibrationDuration();
}
private void initSuggest() {
@@ -574,7 +579,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mUserDictionary = new UserDictionary(this, localeStr);
mSuggest.setUserDictionary(mUserDictionary);
- mIsUserDictionaryAvaliable = mUserDictionary.isEnabled();
+ mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
resetContactsDictionary(oldContactsDictionary);
@@ -695,13 +700,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
@Override
- public void onStartInput(EditorInfo attribute, boolean restarting) {
- mHandler.onStartInput(attribute, restarting);
+ public void onStartInput(EditorInfo editorInfo, boolean restarting) {
+ mHandler.onStartInput(editorInfo, restarting);
}
@Override
- public void onStartInputView(EditorInfo attribute, boolean restarting) {
- mHandler.onStartInputView(attribute, restarting);
+ public void onStartInputView(EditorInfo editorInfo, boolean restarting) {
+ mHandler.onStartInputView(editorInfo, restarting);
}
@Override
@@ -714,20 +719,32 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHandler.onFinishInput();
}
- private void onStartInputInternal(EditorInfo attribute, boolean restarting) {
- super.onStartInput(attribute, restarting);
+ private void onStartInputInternal(EditorInfo editorInfo, boolean restarting) {
+ super.onStartInput(editorInfo, restarting);
}
- private void onStartInputViewInternal(EditorInfo attribute, boolean restarting) {
- super.onStartInputView(attribute, restarting);
+ private void onStartInputViewInternal(EditorInfo editorInfo, boolean restarting) {
+ super.onStartInputView(editorInfo, restarting);
final KeyboardSwitcher switcher = mKeyboardSwitcher;
LatinKeyboardView inputView = switcher.getKeyboardView();
if (DEBUG) {
- Log.d(TAG, "onStartInputView: attribute:" + ((attribute == null) ? "none"
+ Log.d(TAG, "onStartInputView: editorInfo:" + ((editorInfo == null) ? "none"
: String.format("inputType=0x%08x imeOptions=0x%08x",
- attribute.inputType, attribute.imeOptions)));
+ editorInfo.inputType, editorInfo.imeOptions)));
+ }
+ if (Utils.inPrivateImeOptions(null, IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo)) {
+ Log.w(TAG, "Deprecated private IME option specified: "
+ + editorInfo.privateImeOptions);
+ Log.w(TAG, "Use " + getPackageName() + "." + IME_OPTION_NO_MICROPHONE + " instead");
}
+ if (Utils.inPrivateImeOptions(getPackageName(), IME_OPTION_FORCE_ASCII, editorInfo)) {
+ Log.w(TAG, "Deprecated private IME option specified: "
+ + editorInfo.privateImeOptions);
+ Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead");
+ }
+
+ LatinImeLogger.onStartInputView(editorInfo);
// In landscape mode, this method gets called without the input view being created.
if (inputView == null) {
return;
@@ -736,47 +753,44 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Forward this event to the accessibility utilities, if enabled.
final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance();
if (accessUtils.isTouchExplorationEnabled()) {
- accessUtils.onStartInputViewInternal(attribute, restarting);
+ accessUtils.onStartInputViewInternal(editorInfo, restarting);
}
mSubtypeSwitcher.updateParametersOnStartInputView();
- TextEntryState.reset();
-
// Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
// know now whether this is a password text field, because we need to know now whether we
// want to enable the voice button.
final VoiceProxy voiceIme = mVoiceProxy;
- final int inputType = (attribute != null) ? attribute.inputType : 0;
+ final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(inputType)
|| InputTypeCompatUtils.isVisiblePasswordInputType(inputType));
// The EditorInfo might have a flag that affects fullscreen mode.
// Note: This call should be done by InputMethodService?
updateFullscreenMode();
- initializeInputAttributes(attribute);
+ mInputAttributes = new InputAttributes(editorInfo, isFullscreenMode());
+ mApplicationSpecifiedCompletions = null;
inputView.closing();
mEnteredText = null;
- mComposingStringBuilder.setLength(0);
- mHasUncommittedTypedChars = false;
+ resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
- mJustAddedMagicSpace = false;
- mJustReplacedDoubleSpace = false;
+ mSpaceState = SPACE_STATE_NONE;
loadSettings();
updateCorrectionMode();
- updateSuggestionVisibility(mPrefs, mResources);
+ updateSuggestionVisibility(mResources);
if (mSuggest != null && mSettingsValues.mAutoCorrectEnabled) {
mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold);
}
- mVoiceProxy.loadSettings(attribute, mPrefs);
+ mVoiceProxy.loadSettings(editorInfo, mPrefs);
// This will work only when the subtype is not supported.
LanguageSwitcherProxy.loadSettings();
if (mSubtypeSwitcher.isKeyboardMode()) {
- switcher.loadKeyboard(attribute, mSettingsValues);
+ switcher.loadKeyboard(editorInfo, mSettingsValues);
}
if (mSuggestionsView != null)
@@ -785,6 +799,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
isSuggestionsStripVisible(), /* needsInputViewShown */ false);
// Delay updating suggestions because keyboard input view may not be shown at this point.
mHandler.postUpdateSuggestions();
+ mHandler.cancelDoubleSpacesTimer();
inputView.setKeyPreviewPopupEnabled(mSettingsValues.mKeyPreviewPopupOn,
mSettingsValues.mKeyPreviewPopupDismissDelay);
@@ -795,73 +810,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
- private void initializeInputAttributes(EditorInfo attribute) {
- if (attribute == null)
- return;
- final int inputType = attribute.inputType;
- if (inputType == InputType.TYPE_NULL) {
- // TODO: We should honor TYPE_NULL specification.
- Log.i(TAG, "InputType.TYPE_NULL is specified");
- }
- final int inputClass = inputType & InputType.TYPE_MASK_CLASS;
- final int variation = inputType & InputType.TYPE_MASK_VARIATION;
- if (inputClass == 0) {
- Log.w(TAG, String.format("Unexpected input class: inputType=0x%08x imeOptions=0x%08x",
- inputType, attribute.imeOptions));
- }
-
- mInsertSpaceOnPickSuggestionManually = false;
- mInputTypeNoAutoCorrect = false;
- mIsSettingsSuggestionStripOn = false;
- mApplicationSpecifiedCompletionOn = false;
- mApplicationSpecifiedCompletions = null;
-
- if (inputClass == InputType.TYPE_CLASS_TEXT) {
- mIsSettingsSuggestionStripOn = true;
- // Make sure that passwords are not displayed in {@link SuggestionsView}.
- if (InputTypeCompatUtils.isPasswordInputType(inputType)
- || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)) {
- mIsSettingsSuggestionStripOn = false;
- }
- if (InputTypeCompatUtils.isEmailVariation(variation)
- || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
- // The point in turning this off is that we don't want to insert a space after
- // a name when filling a form: we can't delete trailing spaces when changing fields
- mInsertSpaceOnPickSuggestionManually = false;
- } else {
- mInsertSpaceOnPickSuggestionManually = true;
- }
- if (InputTypeCompatUtils.isEmailVariation(variation)) {
- mIsSettingsSuggestionStripOn = false;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
- mIsSettingsSuggestionStripOn = false;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
- mIsSettingsSuggestionStripOn = false;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
- // If it's a browser edit field and auto correct is not ON explicitly, then
- // disable auto correction, but keep suggestions on.
- if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
- mInputTypeNoAutoCorrect = true;
- }
- }
-
- // If NO_SUGGESTIONS is set, don't do prediction.
- if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
- mIsSettingsSuggestionStripOn = false;
- mInputTypeNoAutoCorrect = true;
- }
- // If it's not multiline and the autoCorrect flag is not set, then don't correct
- if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0
- && (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
- mInputTypeNoAutoCorrect = true;
- }
- if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
- mIsSettingsSuggestionStripOn = false;
- mApplicationSpecifiedCompletionOn = isFullscreenMode();
- }
- }
- }
-
@Override
public void onWindowHidden() {
super.onWindowHidden();
@@ -923,12 +871,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|| newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart;
final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1;
if (!mExpectingUpdateSelection) {
- if (((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars)
+ // TAKE CARE: there is a race condition when we enter this test even when the user
+ // did not explicitly move the cursor. This happens when typing fast, where two keys
+ // turn this flag on in succession and both onUpdateSelection() calls arrive after
+ // the second one - the first call successfully avoids this test, but the second one
+ // enters. For the moment we rely on candidatesCleared to further reduce the impact.
+
+ // We set this to NONE because after a cursor move, we don't want the space
+ // state-related special processing to kick in.
+ mSpaceState = SPACE_STATE_NONE;
+
+ if (((mWordComposer.isComposingWord())
|| mVoiceProxy.isVoiceInputHighlighted())
&& (selectionChanged || candidatesCleared)) {
- mComposingStringBuilder.setLength(0);
- mHasUncommittedTypedChars = false;
- TextEntryState.reset();
+ resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
@@ -936,26 +892,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
mComposingStateManager.onFinishComposingText();
mVoiceProxy.setVoiceInputHighlighted(false);
- } else if (!mHasUncommittedTypedChars) {
- TextEntryState.reset();
+ } else if (!mWordComposer.isComposingWord()) {
+ // TODO: is the following reset still needed, given that we are not composing
+ // a word?
+ resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
}
- mJustAddedMagicSpace = false; // The user moved the cursor.
- mJustReplacedDoubleSpace = false;
}
mExpectingUpdateSelection = false;
mHandler.postUpdateShiftKeyState();
+ // TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not
+ // here. It would probably be too expensive to call directly here but we may want to post a
+ // message to delay it. The point would be to unify behavior between backspace to the
+ // end of a word and manually put the pointer at the end of the word.
// Make a note of the cursor position
mLastSelectionStart = newSelStart;
mLastSelectionEnd = newSelEnd;
}
- public void setLastSelection(int start, int end) {
- mLastSelectionStart = start;
- mLastSelectionEnd = end;
- }
-
/**
* This is called when the user has clicked on the extracted text view,
* when running in fullscreen mode. The default implementation hides
@@ -1011,7 +966,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
}
- if (mApplicationSpecifiedCompletionOn) {
+ if (mInputAttributes.mApplicationSpecifiedCompletionOn) {
mApplicationSpecifiedCompletions = applicationSpecifiedCompletions;
if (applicationSpecifiedCompletions == null) {
clearSuggestions();
@@ -1024,7 +979,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
.setHasMinimalSuggestion(false);
// When in fullscreen mode, show completions generated by the application
setSuggestions(builder.build());
- mBestWord = null;
+ // TODO: is this the right thing to do? What should we auto-correct to in
+ // this case? This says to keep whatever the user typed.
+ mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
setSuggestionStripShown(true);
}
}
@@ -1032,8 +989,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) {
// TODO: Modify this if we support suggestions with hard keyboard
if (onEvaluateInputViewShown() && mSuggestionsContainer != null) {
+ final LatinKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView();
+ final boolean inputViewShown = (keyboardView != null) ? keyboardView.isShown() : false;
final boolean shouldShowSuggestions = shown
- && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true);
+ && (needsInputViewShown ? inputViewShown : true);
if (isFullscreenMode()) {
mSuggestionsContainer.setVisibility(
shouldShowSuggestions ? View.VISIBLE : View.GONE);
@@ -1065,7 +1024,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
int touchY = extraHeight;
// Need to set touchable region only if input view is being shown
- if (mKeyboardSwitcher.isInputViewShown()) {
+ final LatinKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView();
+ if (keyboardView != null && keyboardView.isShown()) {
if (mSuggestionsContainer.getVisibility() == View.VISIBLE) {
touchY -= suggestionsHeight;
}
@@ -1085,8 +1045,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public boolean onEvaluateFullscreenMode() {
- return super.onEvaluateFullscreenMode()
- && mResources.getBoolean(R.bool.config_use_fullscreen_mode);
+ // Reread resource value here, because this method is called by framework anytime as needed.
+ final boolean isFullscreenModeAllowed =
+ mSettingsValues.isFullscreenModeAllowed(getResources());
+ return super.onEvaluateFullscreenMode() && isFullscreenModeAllowed;
}
@Override
@@ -1124,9 +1086,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
+ final LatinKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView();
+ final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
// Enable shift key and DPAD to do selections
- if (mKeyboardSwitcher.isInputViewShown()
- && mKeyboardSwitcher.isShiftedOrShiftLocked()) {
+ if ((keyboardView != null && keyboardView.isShown())
+ && (keyboard != null && keyboard.isShiftedOrShiftLocked())) {
KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(),
event.getAction(), event.getKeyCode(), event.getRepeatCount(),
event.getDeviceId(), event.getScanCode(),
@@ -1141,16 +1105,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return super.onKeyUp(keyCode, event);
}
+ private void resetComposingState(final boolean alsoResetLastComposedWord) {
+ mWordComposer.reset();
+ if (alsoResetLastComposedWord)
+ mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
+ }
+
public void commitTyped(final InputConnection ic) {
- if (!mHasUncommittedTypedChars) return;
- mHasUncommittedTypedChars = false;
- if (mComposingStringBuilder.length() > 0) {
+ if (!mWordComposer.isComposingWord()) return;
+ final CharSequence typedWord = mWordComposer.getTypedWord();
+ mLastComposedWord = mWordComposer.commitWord(LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD);
+ if (typedWord.length() > 0) {
if (ic != null) {
- ic.commitText(mComposingStringBuilder, 1);
+ ic.commitText(typedWord, 1);
}
- mCommittedLength = mComposingStringBuilder.length();
- TextEntryState.acceptedTyped(mComposingStringBuilder);
- addToUserUnigramAndBigramDictionaries(mComposingStringBuilder,
+ addToUserUnigramAndBigramDictionaries(typedWord,
UserUnigramDictionary.FREQUENCY_FOR_TYPED);
}
updateSuggestions();
@@ -1166,25 +1135,22 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return false;
}
- private void swapSwapperAndSpace() {
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
+ // "ic" may be null
+ private void swapSwapperAndSpaceWhileInBatchEdit(final InputConnection ic) {
+ if (null == ic) return;
CharSequence lastTwo = ic.getTextBeforeCursor(2, 0);
// It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called.
if (lastTwo != null && lastTwo.length() == 2
&& lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
- ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0);
ic.commitText(lastTwo.charAt(1) + " ", 1);
- ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
}
}
- private void maybeDoubleSpace() {
- if (mCorrectionMode == Suggest.CORRECTION_NONE) return;
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
+ private boolean maybeDoubleSpaceWhileInBatchEdit(final InputConnection ic) {
+ if (mCorrectionMode == Suggest.CORRECTION_NONE) return false;
+ if (ic == null) return false;
final CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3
&& Utils.canBeFollowedByPeriod(lastThree.charAt(0))
@@ -1192,34 +1158,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
&& lastThree.charAt(2) == Keyboard.CODE_SPACE
&& mHandler.isAcceptingDoubleSpaces()) {
mHandler.cancelDoubleSpacesTimer();
- ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0);
ic.commitText(". ", 1);
- ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
- mJustReplacedDoubleSpace = true;
- } else {
- mHandler.startDoubleSpacesTimer();
- }
- }
-
- // "ic" must not null
- private void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) {
- // When the text's first character is '.', remove the previous period
- // if there is one.
- CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
- if (lastOne != null && lastOne.length() == 1
- && lastOne.charAt(0) == Keyboard.CODE_PERIOD
- && text.charAt(0) == Keyboard.CODE_PERIOD) {
- ic.deleteSurroundingText(1, 0);
+ return true;
}
+ return false;
}
- private void removeTrailingSpace() {
- final InputConnection ic = getCurrentInputConnection();
+ // "ic" may be null
+ private static void removeTrailingSpaceWhileInBatchEdit(final InputConnection ic) {
if (ic == null) return;
-
- CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
+ final CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == Keyboard.CODE_SPACE) {
ic.deleteSurroundingText(1, 0);
@@ -1235,19 +1185,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return true;
}
- private boolean isAlphabet(int code) {
- if (Character.isLetter(code)) {
- return true;
- } else {
- return false;
- }
+ private static boolean isAlphabet(int code) {
+ return Character.isLetter(code);
}
private void onSettingsKeyPressed() {
if (isShowingOptionDialog()) return;
if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
showSubtypeSelectorAndSettings();
- } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm, false /* exclude aux subtypes */)) {
+ } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(false /* exclude aux subtypes */)) {
showOptionsMenu();
} else {
launchSettings();
@@ -1256,17 +1202,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Virtual codes representing custom requests. These are used in onCustomRequest() below.
public static final int CODE_SHOW_INPUT_METHOD_PICKER = 1;
+ public static final int CODE_HAPTIC_AND_AUDIO_FEEDBACK = 2;
@Override
public boolean onCustomRequest(int requestCode) {
if (isShowingOptionDialog()) return false;
switch (requestCode) {
case CODE_SHOW_INPUT_METHOD_PICKER:
- if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm, true /* include aux subtypes */)) {
+ if (Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
mImm.showInputMethodPicker();
return true;
}
return false;
+ case CODE_HAPTIC_AND_AUDIO_FEEDBACK:
+ hapticAndAudioFeedback(Keyboard.CODE_UNSPECIFIED);
+ return true;
}
return false;
}
@@ -1275,6 +1225,41 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return mOptionsDialog != null && mOptionsDialog.isShowing();
}
+ private void insertPunctuationFromSuggestionStrip(final int code) {
+ onCodeInput(code, new int[] { code },
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
+ }
+
+ private static int getEditorActionId(EditorInfo editorInfo) {
+ if (editorInfo == null) return 0;
+ return (editorInfo.actionLabel != null)
+ ? editorInfo.actionId
+ : (editorInfo.imeOptions & EditorInfo.IME_MASK_ACTION);
+ }
+
+ private void performeEditorAction(int actionId) {
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ ic.performEditorAction(actionId);
+ }
+ }
+
+ private void sendKeyCodePoint(int code) {
+ // TODO: Remove this special handling of digit letters.
+ // For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
+ if (code >= '0' && code <= '9') {
+ super.sendKeyChar((char)code);
+ return;
+ }
+
+ final InputConnection ic = getCurrentInputConnection();
+ if (ic != null) {
+ final String text = new String(new int[] { code }, 0, 1);
+ ic.commitText(text, text.length());
+ }
+ }
+
// Implementation of {@link KeyboardActionListener}.
@Override
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
@@ -1284,55 +1269,39 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
mLastKeyTime = when;
final KeyboardSwitcher switcher = mKeyboardSwitcher;
- final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
- final boolean lastStateOfJustReplacedDoubleSpace = mJustReplacedDoubleSpace;
- mJustReplacedDoubleSpace = false;
- boolean shouldStartKeyTypedTimer = true;
+ // The space state depends only on the last character pressed and its own previous
+ // state. Here, we revert the space state to neutral if the key is actually modifying
+ // the input contents (any non-shift key), which is what we should do for
+ // all inputs that do not result in a special state. Each character handling is then
+ // free to override the state as they see fit.
+ final int spaceState = mSpaceState;
+
+ // TODO: Consolidate the double space timer, mLastKeyTime, and the space state.
+ if (primaryCode != Keyboard.CODE_SPACE) {
+ mHandler.cancelDoubleSpacesTimer();
+ }
+
+ boolean didAutoCorrect = false;
switch (primaryCode) {
case Keyboard.CODE_DELETE:
- handleBackspace(lastStateOfJustReplacedDoubleSpace);
+ mSpaceState = SPACE_STATE_NONE;
+ handleBackspace(spaceState);
mDeleteCount++;
mExpectingUpdateSelection = true;
LatinImeLogger.logOnDelete();
break;
case Keyboard.CODE_SHIFT:
- // Shift key is handled in onPress() when device has distinct multi-touch panel.
- if (!distinctMultiTouch) {
- switcher.toggleShift();
- }
- shouldStartKeyTypedTimer = false;
- break;
case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
- // Symbol key is handled in onPress() when device has distinct multi-touch panel.
- if (!distinctMultiTouch) {
- switcher.changeKeyboardMode();
- }
- shouldStartKeyTypedTimer = false;
- break;
- case Keyboard.CODE_CANCEL:
- if (!isShowingOptionDialog()) {
- handleClose();
- }
+ // Shift and symbol key is handled in onPressKey() and onReleaseKey().
break;
case Keyboard.CODE_SETTINGS:
- if (!mHandler.isIgnoringSpecialKey()) {
- onSettingsKeyPressed();
- }
- shouldStartKeyTypedTimer = false;
- break;
- case Keyboard.CODE_CAPSLOCK:
- switcher.toggleCapsLock();
- //$FALL-THROUGH$
- case Keyboard.CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY:
- // Dummy code for haptic and audio feedbacks.
- vibrate();
- playKeyClick(primaryCode);
+ onSettingsKeyPressed();
break;
case Keyboard.CODE_SHORTCUT:
- if (!mHandler.isIgnoringSpecialKey()) {
- mSubtypeSwitcher.switchToShortcutIME();
- }
- shouldStartKeyTypedTimer = false;
+ mSubtypeSwitcher.switchToShortcutIME();
+ break;
+ case Keyboard.CODE_ACTION_ENTER:
+ performeEditorAction(getEditorActionId(getCurrentInputEditorInfo()));
break;
case Keyboard.CODE_TAB:
handleTab();
@@ -1346,20 +1315,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// To sum it up: do not update mExpectingUpdateSelection here.
break;
default:
+ mSpaceState = SPACE_STATE_NONE;
if (mSettingsValues.isWordSeparator(primaryCode)) {
- handleSeparator(primaryCode, x, y);
+ didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
} else {
- handleCharacter(primaryCode, keyCodes, x, y);
+ handleCharacter(primaryCode, keyCodes, x, y, spaceState);
}
mExpectingUpdateSelection = true;
break;
}
- switcher.onKey(primaryCode);
+ switcher.onCodeInput(primaryCode);
// Reset after any single keystroke
+ if (!didAutoCorrect)
+ mLastComposedWord.deactivate();
mEnteredText = null;
- if (shouldStartKeyTypedTimer) {
- mHandler.startKeyTypedTimer();
- }
}
@Override
@@ -1369,14 +1338,37 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ic == null) return;
ic.beginBatchEdit();
commitTyped(ic);
- maybeRemovePreviousPeriod(ic, text);
+ text = specificTldProcessingOnTextInput(ic, text);
+ if (SPACE_STATE_PHANTOM == mSpaceState) {
+ sendKeyCodePoint(Keyboard.CODE_SPACE);
+ }
ic.commitText(text, 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
- mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY);
- mJustAddedMagicSpace = false;
+ mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
+ mSpaceState = SPACE_STATE_NONE;
mEnteredText = text;
- mHandler.startKeyTypedTimer();
+ resetComposingState(true /* alsoResetLastComposedWord */);
+ }
+
+ // ic may not be null
+ private CharSequence specificTldProcessingOnTextInput(final InputConnection ic,
+ final CharSequence text) {
+ if (text.length() <= 1 || text.charAt(0) != Keyboard.CODE_PERIOD
+ || !Character.isLetter(text.charAt(1))) {
+ // Not a tld: do nothing.
+ return text;
+ }
+ // We have a TLD (or something that looks like this): make sure we don't add
+ // a space even if currently in phantom mode.
+ mSpaceState = SPACE_STATE_NONE;
+ final CharSequence lastOne = ic.getTextBeforeCursor(1, 0);
+ if (lastOne != null && lastOne.length() == 1
+ && lastOne.charAt(0) == Keyboard.CODE_PERIOD) {
+ return text.subSequence(1, text.length());
+ } else {
+ return text;
+ }
}
@Override
@@ -1385,83 +1377,122 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mKeyboardSwitcher.onCancelInput();
}
- private void handleBackspace(boolean justReplacedDoubleSpace) {
+ private void handleBackspace(final int spaceState) {
if (mVoiceProxy.logAndRevertVoiceInput()) return;
-
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
+ handleBackspaceWhileInBatchEdit(spaceState, ic);
+ ic.endBatchEdit();
+ }
+ // "ic" may not be null.
+ private void handleBackspaceWhileInBatchEdit(final int spaceState, final InputConnection ic) {
mVoiceProxy.handleBackspace();
- final boolean deleteChar = !mHasUncommittedTypedChars;
- if (mHasUncommittedTypedChars) {
- final int length = mComposingStringBuilder.length();
+ // In many cases, we may have to put the keyboard in auto-shift state again.
+ mHandler.postUpdateShiftKeyState();
+
+ if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
+ // Cancel multi-character input: remove the text we just entered.
+ // This is triggered on backspace after a key that inputs multiple characters,
+ // like the smiley key or the .com key.
+ ic.deleteSurroundingText(mEnteredText.length(), 0);
+ // If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
+ // In addition we know that spaceState is false, and that we should not be
+ // reverting any autocorrect at this point. So we can safely return.
+ return;
+ }
+
+ if (mWordComposer.isComposingWord()) {
+ final int length = mWordComposer.size();
if (length > 0) {
- mComposingStringBuilder.delete(length - 1, length);
mWordComposer.deleteLast();
- final CharSequence textWithUnderline =
- mComposingStateManager.isAutoCorrectionIndicatorOn()
- ? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(
- this, mComposingStringBuilder)
- : mComposingStringBuilder;
- ic.setComposingText(textWithUnderline, 1);
- if (mComposingStringBuilder.length() == 0) {
- mHasUncommittedTypedChars = false;
- }
- if (1 == length) {
- // 1 == length means we are about to erase the last character of the word,
- // so we can show bigrams.
+ ic.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
+ // If we have deleted the last remaining character of a word, then we are not
+ // isComposingWord() any more.
+ if (!mWordComposer.isComposingWord()) {
+ // Not composing word any more, so we can show bigrams.
mHandler.postUpdateBigramPredictions();
} else {
- // length > 1, so we still have letters to deduce a suggestion from.
+ // Still composing a word, so we still have letters to deduce a suggestion from.
mHandler.postUpdateSuggestions();
}
} else {
ic.deleteSurroundingText(1, 0);
}
- }
- mHandler.postUpdateShiftKeyState();
-
- TextEntryState.backspace();
- if (TextEntryState.isUndoCommit()) {
- revertLastWord(ic);
- ic.endBatchEdit();
- return;
- }
- if (justReplacedDoubleSpace) {
- if (revertDoubleSpace(ic)) {
- ic.endBatchEdit();
+ } else {
+ // We should be very careful about auto-correction cancellation and suggestion
+ // resuming here. The behavior needs to be different according to text field types,
+ // and it would be much clearer to test for them explicitly here rather than
+ // relying on implicit values like "whether the suggestion strip is displayed".
+ if (mLastComposedWord.canCancelAutoCorrect()) {
+ Utils.Stats.onAutoCorrectionCancellation();
+ cancelAutoCorrect(ic);
return;
}
- }
- if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
- ic.deleteSurroundingText(mEnteredText.length(), 0);
- } else if (deleteChar) {
+ if (SPACE_STATE_DOUBLE == spaceState) {
+ if (revertDoubleSpaceWhileInBatchEdit(ic)) {
+ // No need to reset mSpaceState, it has already be done (that's why we
+ // receive it as a parameter)
+ return;
+ }
+ } else if (SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
+ if (revertSwapPunctuation(ic)) {
+ // Likewise
+ return;
+ }
+ }
+
+ // See the comment above: must be careful about resuming auto-suggestion.
if (mSuggestionsView != null && mSuggestionsView.dismissAddToDictionaryHint()) {
// Go back to the suggestion mode if the user canceled the
// "Touch again to save".
- // NOTE: In gerenal, we don't revert the word when backspacing
+ // NOTE: In general, we don't revert the word when backspacing
// from a manual suggestion pick. We deliberately chose a
// different behavior only in the case of picking the first
// suggestion (typed word). It's intentional to have made this
// inconsistent with backspacing after selecting other suggestions.
- revertLastWord(ic);
+ restartSuggestionsOnManuallyPickedTypedWord(ic);
} else {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
- if (mDeleteCount > DELETE_ACCELERATE_AT) {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ // Here we must check whether there is a selection. If so we should remove the
+ // selected text, otherwise we should just delete the character before the cursor.
+ if (mLastSelectionStart != mLastSelectionEnd) {
+ final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
+ ic.setSelection(mLastSelectionEnd, mLastSelectionEnd);
+ ic.deleteSurroundingText(lengthToDelete, 0);
+ } else {
+ if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
+ // We don't know whether there is a selection or not. We just send a false
+ // hardware key event and let TextView sort it out for us. The problem
+ // here is, this is asynchronous with respect to the input connection
+ // batch edit, so it may flicker. But this only ever happens if backspace
+ // is pressed just after the IME is invoked, and then again only once.
+ // TODO: add an API call that gets the selection indices. This is available
+ // to the IME in the general case via onUpdateSelection anyway, and would
+ // allow us to remove this race condition.
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ } else {
+ ic.deleteSurroundingText(1, 0);
+ }
+ if (mDeleteCount > DELETE_ACCELERATE_AT) {
+ ic.deleteSurroundingText(1, 0);
+ }
+ }
+ if (isSuggestionsRequested()) {
+ restartSuggestionsOnWordBeforeCursorIfAtEndOfWord(ic);
}
}
}
- ic.endBatchEdit();
}
+ // TODO: Implement next and previous actions using other key code than tab's code.
private void handleTab() {
final int imeOptions = getCurrentInputEditorInfo().imeOptions;
if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
&& !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) {
+ // TODO: This should be {@link #sendKeyCodePoint(int)}.
sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB);
return;
}
@@ -1470,89 +1501,108 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ic == null)
return;
- // True if keyboard is in either chording shift or manual temporary upper case mode.
- final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase();
- if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
- && !isManualTemporaryUpperCase) {
+ final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
+ // True if keyboard is in either shift chording or manual shifted state.
+ final boolean isManualShifted = (keyboard != null && keyboard.isManualShifted());
+ if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) && !isManualShifted) {
EditorInfoCompatUtils.performEditorActionNext(ic);
- } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)
- && isManualTemporaryUpperCase) {
+ } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions) && isManualShifted) {
EditorInfoCompatUtils.performEditorActionPrevious(ic);
}
}
- private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) {
- mVoiceProxy.handleCharacter();
+ // ic may be null
+ private boolean maybeStripSpaceWhileInBatchEdit(final InputConnection ic, final int code,
+ final int spaceState, final boolean isFromSuggestionStrip) {
+ if (Keyboard.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
+ removeTrailingSpaceWhileInBatchEdit(ic);
+ return false;
+ } else if ((SPACE_STATE_WEAK == spaceState
+ || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
+ && isFromSuggestionStrip) {
+ if (mSettingsValues.isMagicSpaceSwapper(code)) {
+ return true;
+ } else {
+ if (mSettingsValues.isMagicSpaceStripper(code)) {
+ removeTrailingSpaceWhileInBatchEdit(ic);
+ }
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
- if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceStripper(primaryCode)) {
- removeTrailingSpace();
+ private void handleCharacter(final int primaryCode, final int[] keyCodes, final int x,
+ final int y, final int spaceState) {
+ mVoiceProxy.handleCharacter();
+ final InputConnection ic = getCurrentInputConnection();
+ if (null != ic) ic.beginBatchEdit();
+ // TODO: if ic is null, does it make any sense to call this?
+ handleCharacterWhileInBatchEdit(primaryCode, keyCodes, x, y, spaceState, ic);
+ if (null != ic) ic.endBatchEdit();
+ }
+
+ // "ic" may be null without this crashing, but the behavior will be really strange
+ private void handleCharacterWhileInBatchEdit(final int primaryCode, final int[] keyCodes,
+ final int x, final int y, final int spaceState, final InputConnection ic) {
+ boolean isComposingWord = mWordComposer.isComposingWord();
+
+ if (SPACE_STATE_PHANTOM == spaceState &&
+ !mSettingsValues.isSymbolExcludedFromWordSeparators(primaryCode)) {
+ if (isComposingWord) {
+ // Sanity check
+ throw new RuntimeException("Should not be composing here");
+ }
+ sendKeyCodePoint(Keyboard.CODE_SPACE);
}
- int code = primaryCode;
- if ((isAlphabet(code) || mSettingsValues.isSymbolExcludedFromWordSeparators(code))
+ if ((isAlphabet(primaryCode)
+ || mSettingsValues.isSymbolExcludedFromWordSeparators(primaryCode))
&& isSuggestionsRequested() && !isCursorTouchingWord()) {
- if (!mHasUncommittedTypedChars) {
- mHasUncommittedTypedChars = true;
- mComposingStringBuilder.setLength(0);
- mWordComposer.reset();
+ if (!isComposingWord) {
+ // Reset entirely the composing state anyway, then start composing a new word unless
+ // the character is a single quote. The idea here is, single quote is not a
+ // separator and it should be treated as a normal character, except in the first
+ // position where it should not start composing a word.
+ isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != primaryCode);
+ // Here we don't need to reset the last composed word. It will be reset
+ // when we commit this one, if we ever do; if on the other hand we backspace
+ // it entirely and resume suggestions on the previous word, we'd like to still
+ // have touch coordinates for it.
+ resetComposingState(false /* alsoResetLastComposedWord */);
clearSuggestions();
mComposingStateManager.onFinishComposingText();
}
}
- final KeyboardSwitcher switcher = mKeyboardSwitcher;
- if (switcher.isShiftedOrShiftLocked()) {
- if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
- || keyCodes[0] > Character.MAX_CODE_POINT) {
- return;
- }
- code = keyCodes[0];
- if (switcher.isAlphabetMode() && Character.isLowerCase(code)) {
- // In some locales, such as Turkish, Character.toUpperCase() may return a wrong
- // character because it doesn't take care of locale.
- final String upperCaseString = new String(new int[] {code}, 0, 1)
- .toUpperCase(mSubtypeSwitcher.getInputLocale());
- if (upperCaseString.codePointCount(0, upperCaseString.length()) == 1) {
- code = upperCaseString.codePointAt(0);
- } else {
- // Some keys, such as [eszett], have upper case as multi-characters.
- onTextInput(upperCaseString);
- return;
- }
- }
- }
- if (mHasUncommittedTypedChars) {
- mComposingStringBuilder.append((char) code);
- mWordComposer.add(code, keyCodes, x, y);
- final InputConnection ic = getCurrentInputConnection();
+ if (isComposingWord) {
+ mWordComposer.add(primaryCode, keyCodes, x, y);
if (ic != null) {
// If it's the first letter, make note of auto-caps state
if (mWordComposer.size() == 1) {
mWordComposer.setAutoCapitalized(getCurrentAutoCapsState());
mComposingStateManager.onStartComposingText();
}
- final CharSequence textWithUnderline =
- mComposingStateManager.isAutoCorrectionIndicatorOn()
- ? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(
- this, mComposingStringBuilder)
- : mComposingStringBuilder;
- ic.setComposingText(textWithUnderline, 1);
+ ic.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
}
mHandler.postUpdateSuggestions();
} else {
- sendKeyChar((char)code);
- }
- if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
- swapSwapperAndSpace();
- } else {
- mJustAddedMagicSpace = false;
- }
+ final boolean swapWeakSpace = maybeStripSpaceWhileInBatchEdit(ic, primaryCode,
+ spaceState, KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x);
- switcher.updateShiftState();
- if (LatinIME.PERF_DEBUG) measureCps();
- TextEntryState.typedCharacter((char) code, mSettingsValues.isWordSeparator(code), x, y);
+ sendKeyCodePoint(primaryCode);
+
+ if (swapWeakSpace) {
+ swapSwapperAndSpaceWhileInBatchEdit(ic);
+ mSpaceState = SPACE_STATE_WEAK;
+ }
+ }
+ Utils.Stats.onNonSeparator((char)primaryCode, x, y);
}
- private void handleSeparator(int primaryCode, int x, int y) {
+ // Returns true if we did an autocorrection, false otherwise.
+ private boolean handleSeparator(final int primaryCode, final int x, final int y,
+ final int spaceState) {
mVoiceProxy.handleSeparator();
mComposingStateManager.onFinishComposingText();
@@ -1562,67 +1612,77 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mHandler.postUpdateSuggestions();
}
- boolean pickedDefault = false;
+ boolean didAutoCorrect = false;
// Handle separator
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.beginBatchEdit();
}
- if (mHasUncommittedTypedChars) {
+ if (mWordComposer.isComposingWord()) {
// In certain languages where single quote is a separator, it's better
// not to auto correct, but accept the typed word. For instance,
// in Italian dov' should not be expanded to dove' because the elision
// requires the last vowel to be removed.
final boolean shouldAutoCorrect = mSettingsValues.mAutoCorrectEnabled
- && !mInputTypeNoAutoCorrect;
+ && !mInputAttributes.mInputTypeNoAutoCorrect;
if (shouldAutoCorrect && primaryCode != Keyboard.CODE_SINGLE_QUOTE) {
- pickedDefault = pickDefaultSuggestion(primaryCode);
+ commitCurrentAutoCorrection(primaryCode, ic);
+ didAutoCorrect = true;
} else {
commitTyped(ic);
}
}
- if (mJustAddedMagicSpace) {
- if (mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
- sendKeyChar((char)primaryCode);
- swapSwapperAndSpace();
- } else {
- if (mSettingsValues.isMagicSpaceStripper(primaryCode)) removeTrailingSpace();
- sendKeyChar((char)primaryCode);
- mJustAddedMagicSpace = false;
- }
- } else {
- sendKeyChar((char)primaryCode);
- }
-
- if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
- maybeDoubleSpace();
- }
+ final boolean swapWeakSpace = maybeStripSpaceWhileInBatchEdit(ic, primaryCode, spaceState,
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE == x);
- TextEntryState.typedCharacter((char) primaryCode, true, x, y);
+ sendKeyCodePoint(primaryCode);
- if (pickedDefault) {
- CharSequence typedWord = mWordComposer.getTypedWord();
- TextEntryState.backToAcceptedDefault(typedWord);
- if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) {
- InputConnectionCompatUtils.commitCorrection(
- ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord);
- }
- }
if (Keyboard.CODE_SPACE == primaryCode) {
+ if (isSuggestionsRequested()) {
+ if (maybeDoubleSpaceWhileInBatchEdit(ic)) {
+ mSpaceState = SPACE_STATE_DOUBLE;
+ } else if (!isShowingPunctuationList()) {
+ mSpaceState = SPACE_STATE_WEAK;
+ }
+ }
+
+ mHandler.startDoubleSpacesTimer();
if (!isCursorTouchingWord()) {
mHandler.cancelUpdateSuggestions();
mHandler.postUpdateBigramPredictions();
}
} else {
+ if (swapWeakSpace) {
+ swapSwapperAndSpaceWhileInBatchEdit(ic);
+ mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
+ } else if (SPACE_STATE_PHANTOM == spaceState) {
+ // If we are in phantom space state, and the user presses a separator, we want to
+ // stay in phantom space state so that the next keypress has a chance to add the
+ // space. For example, if I type "Good dat", pick "day" from the suggestion strip
+ // then insert a comma and go on to typing the next word, I want the space to be
+ // inserted automatically before the next word, the same way it is when I don't
+ // input the comma.
+ mSpaceState = SPACE_STATE_PHANTOM;
+ }
+
// Set punctuation right away. onUpdateSelection will fire but tests whether it is
// already displayed or not, so it's okay.
setPunctuationSuggestions();
}
- mKeyboardSwitcher.updateShiftState();
+
+ Utils.Stats.onSeparator((char)primaryCode, x, y);
+
if (ic != null) {
ic.endBatchEdit();
}
+ return didAutoCorrect;
+ }
+
+ private CharSequence getTextWithUnderline(final CharSequence text) {
+ return mComposingStateManager.isAutoCorrectionIndicatorOn()
+ ? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(this, text)
+ : text;
}
private void handleClose() {
@@ -1635,7 +1695,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
public boolean isSuggestionsRequested() {
- return mIsSettingsSuggestionStripOn
+ return mInputAttributes.mIsSettingsSuggestionStripOn
&& (mCorrectionMode > 0 || isShowingSuggestionsStrip());
}
@@ -1653,11 +1713,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
public boolean isSuggestionsStripVisible() {
if (mSuggestionsView == null)
return false;
- if (mSuggestionsView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting())
+ if (mSuggestionsView.isShowingAddToDictionaryHint())
return true;
if (!isShowingSuggestionsStrip())
return false;
- if (mApplicationSpecifiedCompletionOn)
+ if (mInputAttributes.mApplicationSpecifiedCompletionOn)
return true;
return isSuggestionsRequested();
}
@@ -1698,18 +1758,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mComposingStateManager.isAutoCorrectionIndicatorOn();
final boolean newAutoCorrectionIndicator = Utils.willAutoCorrect(words);
if (oldAutoCorrectionIndicator != newAutoCorrectionIndicator) {
- if (LatinImeLogger.sDBG) {
+ mComposingStateManager.setAutoCorrectionIndicatorOn(newAutoCorrectionIndicator);
+ if (DEBUG) {
Log.d(TAG, "Flip the indicator. " + oldAutoCorrectionIndicator
+ " -> " + newAutoCorrectionIndicator);
+ if (mComposingStateManager.isComposing() && newAutoCorrectionIndicator
+ != mComposingStateManager.isAutoCorrectionIndicatorOn()) {
+ throw new RuntimeException("Couldn't flip the indicator!");
+ }
}
- final CharSequence textWithUnderline = newAutoCorrectionIndicator
- ? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(
- this, mComposingStringBuilder)
- : mComposingStringBuilder;
+ final CharSequence textWithUnderline =
+ getTextWithUnderline(mWordComposer.getTypedWord());
if (!TextUtils.isEmpty(textWithUnderline)) {
ic.setComposingText(textWithUnderline, 1);
}
- mComposingStateManager.setAutoCorrectionIndicatorOn(newAutoCorrectionIndicator);
}
}
}
@@ -1718,18 +1780,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Check if we have a suggestion engine attached.
if ((mSuggest == null || !isSuggestionsRequested())
&& !mVoiceProxy.isVoiceInputHighlighted()) {
+ if (mWordComposer.isComposingWord()) {
+ Log.w(TAG, "Called updateSuggestions but suggestions were not requested!");
+ mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
+ }
return;
}
mHandler.cancelUpdateSuggestions();
mHandler.cancelUpdateBigramPredictions();
- if (!mHasUncommittedTypedChars) {
+ if (!mWordComposer.isComposingWord()) {
setPunctuationSuggestions();
return;
}
- final WordComposer wordComposer = mWordComposer;
// TODO: May need a better way of retrieving previous word
final InputConnection ic = getCurrentInputConnection();
final CharSequence prevWord;
@@ -1739,26 +1804,35 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
prevWord = EditingUtils.getPreviousWord(ic, mSettingsValues.mWordSeparators);
}
// getSuggestedWordBuilder handles gracefully a null value of prevWord
- final SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
- wordComposer, prevWord, mKeyboardSwitcher.getLatinKeyboard().getProximityInfo());
+ final SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(mWordComposer,
+ prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), mCorrectionMode);
- boolean autoCorrectionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection();
- final CharSequence typedWord = wordComposer.getTypedWord();
+ boolean autoCorrectionAvailable = !mInputAttributes.mInputTypeNoAutoCorrect
+ && mSuggest.hasAutoCorrection();
+ final CharSequence typedWord = mWordComposer.getTypedWord();
// Here, we want to promote a whitelisted word if exists.
// TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid"
// but still autocorrected from - in the case the whitelist only capitalizes the word.
// The whitelist should be case-insensitive, so it's not possible to be consistent with
// a boolean flag. Right now this is handled with a slight hack in
// WhitelistDictionary#shouldForciblyAutoCorrectFrom.
+ final int quotesCount = mWordComposer.trailingSingleQuotesCount();
final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected(
- mSuggest.getUnigramDictionaries(), typedWord, preferCapitalization());
+ mSuggest.getUnigramDictionaries(),
+ // If the typed string ends with a single quote, for dictionary lookup purposes
+ // we behave as if the single quote was not here. Here, we are looking up the
+ // typed string in the dictionary (to avoid autocorrecting from an existing
+ // word, so for consistency this lookup should be made WITHOUT the trailing
+ // single quote.
+ quotesCount > 0
+ ? typedWord.subSequence(0, typedWord.length() - quotesCount) : typedWord,
+ preferCapitalization());
if (mCorrectionMode == Suggest.CORRECTION_FULL
|| mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) {
autoCorrectionAvailable |= (!allowsToBeAutoCorrected);
}
// Don't auto-correct words with multiple capital letter
- autoCorrectionAvailable &= !wordComposer.isMostlyCaps();
- autoCorrectionAvailable &= !TextEntryState.isRecorrecting();
+ autoCorrectionAvailable &= !mWordComposer.isMostlyCaps();
// Basically, we update the suggestion strip only when suggestion count > 1. However,
// there is an exception: We update the suggestion strip whenever typed word's length
@@ -1794,103 +1868,91 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
setSuggestions(suggestedWords);
if (suggestedWords.size() > 0) {
if (shouldBlockAutoCorrectionBySafetyNet) {
- mBestWord = typedWord;
+ mWordComposer.setAutoCorrection(typedWord);
} else if (suggestedWords.hasAutoCorrectionWord()) {
- mBestWord = suggestedWords.getWord(1);
+ mWordComposer.setAutoCorrection(suggestedWords.getWord(1));
} else {
- mBestWord = typedWord;
+ mWordComposer.setAutoCorrection(typedWord);
}
} else {
- mBestWord = null;
+ // TODO: replace with mWordComposer.deleteAutoCorrection()?
+ mWordComposer.setAutoCorrection(null);
}
setSuggestionStripShown(isSuggestionsStripVisible());
}
- private boolean pickDefaultSuggestion(int separatorCode) {
+ private void commitCurrentAutoCorrection(final int separatorCodePoint,
+ final InputConnection ic) {
// Complete any pending suggestions query first
if (mHandler.hasPendingUpdateSuggestions()) {
mHandler.cancelUpdateSuggestions();
updateSuggestions();
}
- if (mBestWord != null && mBestWord.length() > 0) {
- TextEntryState.acceptedDefault(mWordComposer.getTypedWord(), mBestWord, separatorCode);
+ final CharSequence autoCorrection = mWordComposer.getAutoCorrectionOrNull();
+ if (autoCorrection != null) {
+ final String typedWord = mWordComposer.getTypedWord();
+ if (TextUtils.isEmpty(typedWord)) {
+ throw new RuntimeException("We have an auto-correction but the typed word "
+ + "is empty? Impossible! I must commit suicide.");
+ }
+ Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
mExpectingUpdateSelection = true;
- commitBestWord(mBestWord);
+ commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD);
// Add the word to the user unigram dictionary if it's not a known word
- addToUserUnigramAndBigramDictionaries(mBestWord,
+ addToUserUnigramAndBigramDictionaries(autoCorrection,
UserUnigramDictionary.FREQUENCY_FOR_TYPED);
- return true;
+ if (!typedWord.equals(autoCorrection) && null != ic) {
+ // This will make the correction flash for a short while as a visual clue
+ // to the user that auto-correction happened.
+ InputConnectionCompatUtils.commitCorrection(ic,
+ mLastSelectionEnd - typedWord.length(), typedWord, autoCorrection);
+ }
}
- return false;
}
@Override
- public void pickSuggestionManually(int index, CharSequence suggestion) {
+ public void pickSuggestionManually(final int index, final CharSequence suggestion) {
mComposingStateManager.onFinishComposingText();
- SuggestedWords suggestions = mSuggestionsView.getSuggestions();
+ final SuggestedWords suggestions = mSuggestionsView.getSuggestions();
mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion,
mSettingsValues.mWordSeparators);
- final boolean recorrecting = TextEntryState.isRecorrecting();
- final InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.beginBatchEdit();
- }
- if (mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null
+ if (mInputAttributes.mApplicationSpecifiedCompletionOn
+ && mApplicationSpecifiedCompletions != null
&& index >= 0 && index < mApplicationSpecifiedCompletions.length) {
- if (ic != null) {
- final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index];
- ic.commitCompletion(completionInfo);
- }
- mCommittedLength = suggestion.length();
if (mSuggestionsView != null) {
mSuggestionsView.clear();
}
mKeyboardSwitcher.updateShiftState();
+ final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
+ ic.beginBatchEdit();
+ final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index];
+ ic.commitCompletion(completionInfo);
ic.endBatchEdit();
}
return;
}
- // If this is a punctuation, apply it through the normal key press
- if (suggestion.length() == 1 && (mSettingsValues.isWordSeparator(suggestion.charAt(0))
- || mSettingsValues.isSuggestedPunctuation(suggestion.charAt(0)))) {
+ // If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
+ if (suggestion.length() == 1 && isShowingPunctuationList()) {
// Word separators are suggested before the user inputs something.
// So, LatinImeLogger logs "" as a user's input.
LatinImeLogger.logOnManualSuggestion(
"", suggestion.toString(), index, suggestions.mWords);
- // Find out whether the previous character is a space. If it is, as a special case
- // for punctuation entered through the suggestion strip, it should be considered
- // a magic space even if it was a normal space. This is meant to help in case the user
- // pressed space on purpose of displaying the suggestion strip punctuation.
- final int rawPrimaryCode = suggestion.charAt(0);
- // Maybe apply the "bidi mirrored" conversions for parentheses
- final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard();
- final boolean isRtl = keyboard != null && keyboard.mIsRtlKeyboard;
- final int primaryCode = Key.getRtlParenthesisCode(rawPrimaryCode, isRtl);
-
- final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : "";
- final int toLeft = (ic == null || TextUtils.isEmpty(beforeText))
- ? 0 : beforeText.charAt(0);
- final boolean oldMagicSpace = mJustAddedMagicSpace;
- if (Keyboard.CODE_SPACE == toLeft) mJustAddedMagicSpace = true;
+ // Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
+ final int primaryCode = suggestion.charAt(0);
onCodeInput(primaryCode, new int[] { primaryCode },
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
- KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
- mJustAddedMagicSpace = oldMagicSpace;
- if (ic != null) {
- ic.endBatchEdit();
- }
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE,
+ KeyboardActionListener.SUGGESTION_STRIP_COORDINATE);
return;
}
- if (!mHasUncommittedTypedChars) {
- // If we are not composing a word, then it was a suggestion inferred from
- // context - no user input. We should reset the word composer.
- mWordComposer.reset();
- }
+ // We need to log before we commit, because the word composer will store away the user
+ // typed word.
+ LatinImeLogger.logOnManualSuggestion(mWordComposer.getTypedWord().toString(),
+ suggestion.toString(), index, suggestions.mWords);
mExpectingUpdateSelection = true;
- commitBestWord(suggestion);
+ commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK);
// Add the word to the auto dictionary if it's not a known word
if (index == 0) {
addToUserUnigramAndBigramDictionaries(suggestion,
@@ -1898,13 +1960,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else {
addToOnlyBigramDictionary(suggestion, 1);
}
- LatinImeLogger.logOnManualSuggestion(mComposingStringBuilder.toString(),
- suggestion.toString(), index, suggestions.mWords);
- TextEntryState.acceptedSuggestion(mComposingStringBuilder.toString(), suggestion);
- // Follow it with a space
- if (mInsertSpaceOnPickSuggestionManually && !recorrecting) {
- sendMagicSpace();
- }
+ mSpaceState = SPACE_STATE_PHANTOM;
+ // TODO: is this necessary?
+ mKeyboardSwitcher.updateShiftState();
// We should show the "Touch again to save" hint if the user pressed the first entry
// AND either:
@@ -1922,13 +1980,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|| !AutoCorrection.isValidWord(
mSuggest.getUnigramDictionaries(), suggestion, true));
- if (!recorrecting) {
- // Fool the state watcher so that a subsequent backspace will not do a revert, unless
- // we just did a correction, in which case we need to stay in
- // TextEntryState.State.PICKED_SUGGESTION state.
- TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true,
- WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
- }
+ Utils.Stats.onSeparator((char)Keyboard.CODE_SPACE, WordComposer.NOT_A_COORDINATE,
+ WordComposer.NOT_A_COORDINATE);
if (!showingAddToDictionaryHint) {
// If we're not showing the "Touch again to save", then show corrections again.
// In case the cursor position doesn't change, make sure we show the suggestions again.
@@ -1936,26 +1989,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Updating the predictions right away may be slow and feel unresponsive on slower
// terminals. On the other hand if we just postUpdateBigramPredictions() it will
// take a noticeable delay to update them which may feel uneasy.
- }
- if (showingAddToDictionaryHint) {
- if (mIsUserDictionaryAvaliable) {
- mSuggestionsView.showAddToDictionaryHint(suggestion);
+ } else {
+ if (mIsUserDictionaryAvailable) {
+ mSuggestionsView.showAddToDictionaryHint(
+ suggestion, mSettingsValues.mHintToSaveText);
} else {
mHandler.postUpdateSuggestions();
}
}
- if (ic != null) {
- ic.endBatchEdit();
- }
}
/**
* Commits the chosen word to the text field and saves it for later retrieval.
*/
- private void commitBestWord(CharSequence bestWord) {
- final KeyboardSwitcher switcher = mKeyboardSwitcher;
- if (!switcher.isKeyboardAvailable())
- return;
+ private void commitChosenWord(final CharSequence bestWord, final int commitType) {
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
mVoiceProxy.rememberReplacedWord(bestWord, mSettingsValues.mWordSeparators);
@@ -1967,8 +2014,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
ic.commitText(bestWord, 1);
}
}
- mHasUncommittedTypedChars = false;
- mCommittedLength = bestWord.length();
+ // TODO: figure out here if this is an auto-correct or if the best word is actually
+ // what user typed. Note: currently this is done much later in
+ // LastComposedWord#canCancelAutoCorrect by string equality of the remembered
+ // strings.
+ mLastComposedWord = mWordComposer.commitWord(commitType);
}
private static final WordComposer sEmptyWordComposer = new WordComposer();
@@ -1984,7 +2034,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(),
mSettingsValues.mWordSeparators);
SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(sEmptyWordComposer,
- prevWord, mKeyboardSwitcher.getLatinKeyboard().getProximityInfo());
+ prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), mCorrectionMode);
if (builder.size() > 0) {
// Explicitly supply an empty typed word (the no-second-arg version of
@@ -2058,69 +2108,179 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
CharSequence toLeft = ic.getTextBeforeCursor(1, 0);
CharSequence toRight = ic.getTextAfterCursor(1, 0);
if (!TextUtils.isEmpty(toLeft)
- && !mSettingsValues.isWordSeparator(toLeft.charAt(0))
- && !mSettingsValues.isSuggestedPunctuation(toLeft.charAt(0))) {
+ && !mSettingsValues.isWordSeparator(toLeft.charAt(0))) {
return true;
}
if (!TextUtils.isEmpty(toRight)
- && !mSettingsValues.isWordSeparator(toRight.charAt(0))
- && !mSettingsValues.isSuggestedPunctuation(toRight.charAt(0))) {
+ && !mSettingsValues.isWordSeparator(toRight.charAt(0))) {
return true;
}
return false;
}
- // "ic" must not null
- private boolean sameAsTextBeforeCursor(final InputConnection ic, CharSequence text) {
- CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0);
+ // "ic" must not be null
+ private static boolean sameAsTextBeforeCursor(final InputConnection ic,
+ final CharSequence text) {
+ final CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0);
return TextUtils.equals(text, beforeText);
}
- // "ic" must not null
- private void revertLastWord(final InputConnection ic) {
- if (mHasUncommittedTypedChars || mComposingStringBuilder.length() <= 0) {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ // "ic" must not be null
+ /**
+ * Check if the cursor is actually at the end of a word. If so, restart suggestions on this
+ * word, else do nothing.
+ */
+ private void restartSuggestionsOnWordBeforeCursorIfAtEndOfWord(
+ final InputConnection ic) {
+ // Bail out if the cursor is not at the end of a word (cursor must be preceded by
+ // non-whitespace, non-separator, non-start-of-text)
+ // Example ("|" is the cursor here) : <SOL>"|a" " |a" " | " all get rejected here.
+ final CharSequence textBeforeCursor = ic.getTextBeforeCursor(1, 0);
+ if (TextUtils.isEmpty(textBeforeCursor)
+ || mSettingsValues.isWordSeparator(textBeforeCursor.charAt(0))) return;
+
+ // Bail out if the cursor is in the middle of a word (cursor must be followed by whitespace,
+ // separator or end of line/text)
+ // Example: "test|"<EOL> "te|st" get rejected here
+ final CharSequence textAfterCursor = ic.getTextAfterCursor(1, 0);
+ if (!TextUtils.isEmpty(textAfterCursor)
+ && !mSettingsValues.isWordSeparator(textAfterCursor.charAt(0))) return;
+
+ // Bail out if word before cursor is 0-length or a single non letter (like an apostrophe)
+ // Example: " -|" gets rejected here but "e-|" and "e|" are okay
+ CharSequence word = EditingUtils.getWordAtCursor(ic, mSettingsValues.mWordSeparators);
+ // We don't suggest on leading single quotes, so we have to remove them from the word if
+ // it starts with single quotes.
+ while (!TextUtils.isEmpty(word) && Keyboard.CODE_SINGLE_QUOTE == word.charAt(0)) {
+ word = word.subSequence(1, word.length());
+ }
+ if (TextUtils.isEmpty(word)) return;
+ final char firstChar = word.charAt(0); // we just tested that word is not empty
+ if (word.length() == 1 && !Character.isLetter(firstChar)) return;
+
+ // We only suggest on words that start with a letter or a symbol that is excluded from
+ // word separators (see #handleCharacterWhileInBatchEdit).
+ if (!(isAlphabet(firstChar)
+ || mSettingsValues.isSymbolExcludedFromWordSeparators(firstChar))) {
return;
}
+ // Okay, we are at the end of a word. Restart suggestions.
+ restartSuggestionsOnWordBeforeCursor(ic, word);
+ }
+
+ // "ic" must not be null
+ private void restartSuggestionsOnWordBeforeCursor(final InputConnection ic,
+ final CharSequence word) {
+ mWordComposer.setComposingWord(word, mKeyboardSwitcher.getKeyboard());
+ mComposingStateManager.onStartComposingText();
+ ic.deleteSurroundingText(word.length(), 0);
+ ic.setComposingText(word, 1);
+ mHandler.postUpdateSuggestions();
+ }
+
+ // "ic" must not be null
+ private void cancelAutoCorrect(final InputConnection ic) {
+ final String originallyTypedWord = mLastComposedWord.mTypedWord;
+ final CharSequence autoCorrectedTo = mLastComposedWord.mAutoCorrection;
+ final int cancelLength = autoCorrectedTo.length();
final CharSequence separator = ic.getTextBeforeCursor(1, 0);
- ic.deleteSurroundingText(1, 0);
- final CharSequence textToTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
- ic.deleteSurroundingText(mCommittedLength, 0);
-
- // Re-insert "separator" only when the deleted character was word separator and the
- // composing text wasn't equal to the auto-corrected text which can be found before
- // the cursor.
- if (!TextUtils.isEmpty(separator)
- && mSettingsValues.isWordSeparator(separator.charAt(0))
- && !TextUtils.equals(mComposingStringBuilder, textToTheLeft)) {
- ic.commitText(mComposingStringBuilder, 1);
- TextEntryState.acceptedTyped(mComposingStringBuilder);
- ic.commitText(separator, 1);
- TextEntryState.typedCharacter(separator.charAt(0), true,
- WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
- // Clear composing text
- mComposingStringBuilder.setLength(0);
- } else {
- mHasUncommittedTypedChars = true;
- ic.setComposingText(mComposingStringBuilder, 1);
- TextEntryState.backspace();
+ if (DEBUG) {
+ if (mWordComposer.isComposingWord()) {
+ throw new RuntimeException("cancelAutoCorrect, but we are composing a word");
+ }
+ final String wordBeforeCursor =
+ ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength)
+ .toString();
+ if (!TextUtils.equals(autoCorrectedTo, wordBeforeCursor)) {
+ throw new RuntimeException("cancelAutoCorrect check failed: we thought we were "
+ + "reverting \"" + autoCorrectedTo
+ + "\", but before the cursor we found \"" + wordBeforeCursor + "\"");
+ }
+ if (TextUtils.equals(originallyTypedWord, wordBeforeCursor)) {
+ throw new RuntimeException("cancelAutoCorrect check failed: we wanted to cancel "
+ + "auto correction and revert to \"" + originallyTypedWord
+ + "\" but we found this very string before the cursor");
+ }
}
+ ic.deleteSurroundingText(cancelLength + 1, 0);
+ ic.commitText(originallyTypedWord, 1);
+ // Re-insert the separator
+ ic.commitText(separator, 1);
+ mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
+ Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
+ WordComposer.NOT_A_COORDINATE);
mHandler.cancelUpdateBigramPredictions();
mHandler.postUpdateSuggestions();
}
- // "ic" must not null
- private boolean revertDoubleSpace(final InputConnection ic) {
+ // "ic" must not be null
+ private void restartSuggestionsOnManuallyPickedTypedWord(final InputConnection ic) {
+ // Note: this relies on the last word still being held in the WordComposer, in
+ // the field for suggestion resuming.
+ // Note: in the interest of code simplicity, we may want to just call
+ // restartSuggestionsOnWordBeforeCursorIfAtEndOfWord instead, but retrieving
+ // the old WordComposer allows to reuse the actual typed coordinates.
+ mWordComposer.resumeSuggestionOnLastComposedWord(mLastComposedWord);
+ // We resume suggestion, and then we want to set the composing text to the content
+ // of the word composer again. But since we just manually picked a word, there is
+ // no composing text at the moment, so we have to delete the word before we set a
+ // new composing text.
+ final int restartLength = mWordComposer.size();
+ if (DEBUG) {
+ final String wordBeforeCursor = ic.getTextBeforeCursor(restartLength, 0).toString();
+ if (!TextUtils.equals(mWordComposer.getTypedWord(), wordBeforeCursor)) {
+ throw new RuntimeException("restartSuggestionsOnManuallyPickedTypedWord "
+ + "check failed: we thought we were reverting \""
+ + mWordComposer.getTypedWord()
+ + "\", but before the cursor we found \""
+ + wordBeforeCursor + "\"");
+ }
+ }
+ ic.deleteSurroundingText(restartLength, 0);
+ mComposingStateManager.onStartComposingText();
+ ic.setComposingText(mWordComposer.getTypedWord(), 1);
+ mHandler.cancelUpdateBigramPredictions();
+ mHandler.postUpdateSuggestions();
+ }
+
+ // "ic" must not be null
+ private boolean revertDoubleSpaceWhileInBatchEdit(final InputConnection ic) {
mHandler.cancelDoubleSpacesTimer();
// Here we test whether we indeed have a period and a space before us. This should not
// be needed, but it's there just in case something went wrong.
final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0);
- if (!". ".equals(textBeforeCursor))
+ if (!". ".equals(textBeforeCursor)) {
+ // Theoretically we should not be coming here if there isn't ". " before the
+ // cursor, but the application may be changing the text while we are typing, so
+ // anything goes. We should not crash.
+ Log.d(TAG, "Tried to revert double-space combo but we didn't find "
+ + "\". \" just before the cursor.");
return false;
- ic.beginBatchEdit();
+ }
ic.deleteSurroundingText(2, 0);
ic.commitText(" ", 1);
+ return true;
+ }
+
+ private static boolean revertSwapPunctuation(final InputConnection ic) {
+ // Here we test whether we indeed have a space and something else before us. This should not
+ // be needed, but it's there just in case something went wrong.
+ final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0);
+ // NOTE: This does not work with surrogate pairs. Hopefully when the keyboard is able to
+ // enter surrogate pairs this code will have been removed.
+ if (TextUtils.isEmpty(textBeforeCursor)
+ || (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1))) {
+ // We may only come here if the application is changing the text while we are typing.
+ // This is quite a broken case, but not logically impossible, so we shouldn't crash,
+ // but some debugging log may be in order.
+ Log.d(TAG, "Tried to revert a swap of punctuation but we didn't "
+ + "find a space just before the cursor.");
+ return false;
+ }
+ ic.beginBatchEdit();
+ ic.deleteSurroundingText(2, 0);
+ ic.commitText(" " + textBeforeCursor.subSequence(0, 1), 1);
ic.endBatchEdit();
return true;
}
@@ -2129,12 +2289,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return mSettingsValues.isWordSeparator(code);
}
- private void sendMagicSpace() {
- sendKeyChar((char)Keyboard.CODE_SPACE);
- mJustAddedMagicSpace = true;
- mKeyboardSwitcher.updateShiftState();
- }
-
public boolean preferCapitalization() {
return mWordComposer.isFirstCharCapitalized();
}
@@ -2157,36 +2311,33 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
loadSettings();
}
+ public void hapticAndAudioFeedback(int primaryCode) {
+ vibrate();
+ playKeyClick(primaryCode);
+ }
+
@Override
- public void onPress(int primaryCode, boolean withSliding) {
- final KeyboardSwitcher switcher = mKeyboardSwitcher;
- if (switcher.isVibrateAndSoundFeedbackRequired()) {
- vibrate();
- playKeyClick(primaryCode);
- }
- final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
- if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
- switcher.onPressShift(withSliding);
- } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
- switcher.onPressSymbol();
- } else {
- switcher.onOtherKeyPressed();
- }
+ public void onPressKey(int primaryCode) {
+ mKeyboardSwitcher.onPressKey(primaryCode);
}
@Override
- public void onRelease(int primaryCode, boolean withSliding) {
- KeyboardSwitcher switcher = mKeyboardSwitcher;
- // Reset any drag flags in the keyboard
- final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
- if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
- switcher.onReleaseShift(withSliding);
- } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
- switcher.onReleaseSymbol();
+ public void onReleaseKey(int primaryCode, boolean withSliding) {
+ mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding);
+
+ // If accessibility is on, ensure the user receives keyboard state updates.
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ switch (primaryCode) {
+ case Keyboard.CODE_SHIFT:
+ AccessibleKeyboardViewProxy.getInstance().notifyShiftState();
+ break;
+ case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
+ AccessibleKeyboardViewProxy.getInstance().notifySymbolsState();
+ break;
+ }
}
}
-
// receive ringer mode change and network state change.
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -2200,11 +2351,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
};
- // update keypress sound volume
- private void updateSoundEffectVolume() {
- mFxVolume = Utils.getCurrentKeypressSoundVolume(mPrefs, mResources);
- }
-
// update flags for silent mode
private void updateRingerMode() {
if (mAudioManager == null) {
@@ -2214,10 +2360,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSilentModeOn = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL);
}
- private void updateKeypressVibrationDuration() {
- mKeypressVibrationDuration = Utils.getCurrentVibrationDuration(mPrefs, mResources);
- }
-
private void playKeyClick(int primaryCode) {
// if mAudioManager is null, we don't have the ringer state yet
// mAudioManager will be set by updateRingerMode
@@ -2242,7 +2384,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
sound = AudioManager.FX_KEYPRESS_STANDARD;
break;
}
- mAudioManager.playSoundEffect(sound, mFxVolume);
+ mAudioManager.playSoundEffect(sound, mSettingsValues.mFxVolume);
}
}
@@ -2250,7 +2392,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (!mSettingsValues.mVibrateOn) {
return;
}
- if (mKeypressVibrationDuration < 0) {
+ if (mSettingsValues.mKeypressVibrationDuration < 0) {
// Go ahead with the system default
LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) {
@@ -2259,12 +2401,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
} else if (mVibrator != null) {
- mVibrator.vibrate(mKeypressVibrationDuration);
+ mVibrator.vibrate(mSettingsValues.mKeypressVibrationDuration);
}
}
- public WordComposer getCurrentWord() {
- return mWordComposer;
+ public boolean isAutoCapitalized() {
+ return mWordComposer.isAutoCapitalized();
}
boolean isSoundOn() {
@@ -2274,22 +2416,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void updateCorrectionMode() {
// TODO: cleanup messy flags
final boolean shouldAutoCorrect = mSettingsValues.mAutoCorrectEnabled
- && !mInputTypeNoAutoCorrect;
- mCorrectionMode = (shouldAutoCorrect && mSettingsValues.mAutoCorrectEnabled)
- ? Suggest.CORRECTION_FULL
- : (shouldAutoCorrect ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
- mCorrectionMode = (mSettingsValues.mBigramSuggestionEnabled && shouldAutoCorrect
- && mSettingsValues.mAutoCorrectEnabled)
+ && !mInputAttributes.mInputTypeNoAutoCorrect;
+ mCorrectionMode = shouldAutoCorrect ? Suggest.CORRECTION_FULL : Suggest.CORRECTION_NONE;
+ mCorrectionMode = (mSettingsValues.mBigramSuggestionEnabled && shouldAutoCorrect)
? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode;
- if (mSuggest != null) {
- mSuggest.setCorrectionMode(mCorrectionMode);
- }
}
- private void updateSuggestionVisibility(final SharedPreferences prefs, final Resources res) {
- final String suggestionVisiblityStr = prefs.getString(
- Settings.PREF_SHOW_SUGGESTIONS_SETTING,
- res.getString(R.string.prefs_suggestion_visibility_default_value));
+ private void updateSuggestionVisibility(final Resources res) {
+ final String suggestionVisiblityStr = mSettingsValues.mShowSuggestionsSetting;
for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) {
if (suggestionVisiblityStr.equals(res.getString(visibility))) {
mSuggestionVisibility = visibility;
@@ -2328,7 +2462,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
switch (position) {
case 0:
Intent intent = CompatUtils.getInputLanguageSelectionIntent(
- mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK
+ Utils.getInputMethodId(mImm, getPackageName()),
+ Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
@@ -2377,35 +2512,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final Printer p = new PrintWriterPrinter(fout);
p.println("LatinIME state :");
- p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode());
- p.println(" mComposingStringBuilder=" + mComposingStringBuilder.toString());
- p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn);
+ final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
+ final int keyboardMode = keyboard != null ? keyboard.mId.mMode : -1;
+ p.println(" Keyboard mode = " + keyboardMode);
+ p.println(" mIsSuggestionsRequested=" + mInputAttributes.mIsSettingsSuggestionStripOn);
p.println(" mCorrectionMode=" + mCorrectionMode);
- p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars);
+ p.println(" isComposingWord=" + mWordComposer.isComposingWord());
p.println(" mAutoCorrectEnabled=" + mSettingsValues.mAutoCorrectEnabled);
- p.println(" mInsertSpaceOnPickSuggestionManually=" + mInsertSpaceOnPickSuggestionManually);
- p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn);
- p.println(" TextEntryState.state=" + TextEntryState.getState());
p.println(" mSoundOn=" + mSettingsValues.mSoundOn);
p.println(" mVibrateOn=" + mSettingsValues.mVibrateOn);
p.println(" mKeyPreviewPopupOn=" + mSettingsValues.mKeyPreviewPopupOn);
- }
-
- // Characters per second measurement
-
- private long mLastCpsTime;
- private static final int CPS_BUFFER_SIZE = 16;
- private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
- private int mCpsIndex;
-
- private void measureCps() {
- long now = System.currentTimeMillis();
- if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial
- mCpsIntervals[mCpsIndex] = now - mLastCpsTime;
- mLastCpsTime = now;
- mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE;
- long total = 0;
- for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i];
- System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total));
+ p.println(" mInputAttributes=" + mInputAttributes.toString());
}
}
diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
index ae8eb374b..e3dadf250 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -16,11 +16,11 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.Dictionary.DataType;
-
import android.content.Context;
import android.content.SharedPreferences;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.inputmethod.keyboard.Keyboard;
import java.util.List;
@@ -28,12 +28,13 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
public static boolean sDBG = false;
public static boolean sVISUALDEBUG = false;
+ public static boolean sUsabilityStudy = false;
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
- public static void init(Context context, SharedPreferences prefs) {
+ public static void init(LatinIME context, SharedPreferences prefs) {
}
public static void commit() {
@@ -44,7 +45,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
public static void logOnManualSuggestion(
String before, String after, int position, List<CharSequence> suggestions) {
- }
+ }
public static void logOnAutoCorrection(String before, String after, int separatorCode) {
}
@@ -67,10 +68,13 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
public static void logOnWarning(String warning) {
}
+ public static void onStartInputView(EditorInfo editorInfo) {
+ }
+
public static void onStartSuggestion(CharSequence previousWords) {
}
- public static void onAddSuggestedWord(String word, int typeId, DataType dataType) {
+ public static void onAddSuggestedWord(String word, int typeId, int dataType) {
}
public static void onSetKeyboard(Keyboard kb) {
@@ -78,4 +82,8 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
public static void onPrintAllUsabilityStudyLogs() {
}
+
+ public static boolean isResearcherPackage(Context context) {
+ return false;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 773efe709..d32310096 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -38,7 +38,6 @@ import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
-import android.view.inputmethod.EditorInfo;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
@@ -46,12 +45,10 @@ import android.widget.TextView;
import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
-import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethodcommon.InputMethodSettingsActivity;
-import java.util.Arrays;
import java.util.Locale;
public class Settings extends InputMethodSettingsActivity
@@ -61,255 +58,39 @@ public class Settings extends InputMethodSettingsActivity
public static final boolean ENABLE_EXPERIMENTAL_SETTINGS = false;
- public static final String PREF_GENERAL_SETTINGS_KEY = "general_settings";
+ // In the same order as xml/prefs.xml
+ public static final String PREF_GENERAL_SETTINGS = "general_settings";
+ public static final String PREF_SUBTYPES_SETTINGS = "subtype_settings";
+ public static final String PREF_AUTO_CAP = "auto_cap";
public static final String PREF_VIBRATE_ON = "vibrate_on";
public static final String PREF_SOUND_ON = "sound_on";
- public static final String PREF_KEY_PREVIEW_POPUP_ON = "popup_on";
- public static final String PREF_AUTO_CAP = "auto_cap";
+ public static final String PREF_POPUP_ON = "popup_on";
public static final String PREF_SHOW_SETTINGS_KEY = "show_settings_key";
- public static final String PREF_VOICE_SETTINGS_KEY = "voice_mode";
- public static final String PREF_INPUT_LANGUAGE = "input_language";
- public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
- public static final String PREF_SUBTYPES = "subtype_settings";
-
+ public static final String PREF_VOICE_MODE = "voice_mode";
+ public static final String PREF_CORRECTION_SETTINGS = "correction_settings";
public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
- public static final String PREF_CORRECTION_SETTINGS_KEY = "correction_settings";
- public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting";
public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
- public static final String PREF_DEBUG_SETTINGS = "debug_settings";
-
- public static final String PREF_BIGRAM_SUGGESTIONS = "bigram_suggestion";
- public static final String PREF_BIGRAM_PREDICTIONS = "bigram_prediction";
-
- public static final String PREF_MISC_SETTINGS_KEY = "misc_settings";
-
+ public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting";
+ public static final String PREF_MISC_SETTINGS = "misc_settings";
+ public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
+ public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
"pref_key_preview_popup_dismiss_delay";
- public static final String PREF_KEY_USE_CONTACTS_DICT =
- "pref_key_use_contacts_dict";
- public static final String PREF_KEY_ENABLE_SPAN_INSERT =
- "enable_span_insert";
-
- public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
-
- public static final String PREF_KEYPRESS_VIBRATION_DURATION_SETTINGS =
+ public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
+ public static final String PREF_BIGRAM_SUGGESTION = "bigram_suggestion";
+ public static final String PREF_BIGRAM_PREDICTIONS = "bigram_prediction";
+ public static final String PREF_KEY_ENABLE_SPAN_INSERT = "enable_span_insert";
+ public static final String PREF_VIBRATION_DURATION_SETTINGS =
"pref_vibration_duration_settings";
-
public static final String PREF_KEYPRESS_SOUND_VOLUME =
"pref_keypress_sound_volume";
- // Dialog ids
- private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
-
- public static class Values {
- // From resources:
- public final int mDelayUpdateOldSuggestions;
- public final String mWordSeparators;
- public final String mMagicSpaceStrippers;
- public final String mMagicSpaceSwappers;
- public final String mSuggestPuncs;
- public final SuggestedWords mSuggestPuncList;
- private final String mSymbolsExcludedFromWordSeparators;
-
- // From preferences:
- public final boolean mSoundOn; // Sound setting private to Latin IME (see mSilentModeOn)
- public final boolean mVibrateOn;
- public final boolean mKeyPreviewPopupOn;
- public final int mKeyPreviewPopupDismissDelay;
- public final boolean mAutoCap;
- public final boolean mAutoCorrectEnabled;
- public final double mAutoCorrectionThreshold;
- // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
- public final boolean mBigramSuggestionEnabled;
- // Prediction: use bigrams to predict the next word when there is no input for it yet
- public final boolean mBigramPredictionEnabled;
- public final boolean mUseContactsDict;
- public final boolean mEnableSuggestionSpanInsertion;
-
- private final boolean mShowSettingsKey;
- private final boolean mVoiceKeyEnabled;
- private final boolean mVoiceKeyOnMain;
-
- public Values(final SharedPreferences prefs, final Context context,
- final String localeStr) {
- final Resources res = context.getResources();
- final Locale savedLocale;
- if (null != localeStr) {
- final Locale keyboardLocale = LocaleUtils.constructLocaleFromString(localeStr);
- savedLocale = LocaleUtils.setSystemLocale(res, keyboardLocale);
- } else {
- savedLocale = null;
- }
-
- // Get the resources
- mDelayUpdateOldSuggestions = res.getInteger(
- R.integer.config_delay_update_old_suggestions);
- mMagicSpaceStrippers = res.getString(R.string.magic_space_stripping_symbols);
- mMagicSpaceSwappers = res.getString(R.string.magic_space_swapping_symbols);
- String wordSeparators = mMagicSpaceStrippers + mMagicSpaceSwappers
- + res.getString(R.string.magic_space_promoting_symbols);
- final String symbolsExcludedFromWordSeparators =
- res.getString(R.string.symbols_excluded_from_word_separators);
- for (int i = symbolsExcludedFromWordSeparators.length() - 1; i >= 0; --i) {
- wordSeparators = wordSeparators.replace(
- symbolsExcludedFromWordSeparators.substring(i, i + 1), "");
- }
- mSymbolsExcludedFromWordSeparators = symbolsExcludedFromWordSeparators;
- mWordSeparators = wordSeparators;
- mSuggestPuncs = res.getString(R.string.suggested_punctuations);
- // TODO: it would be nice not to recreate this each time we change the configuration
- mSuggestPuncList = createSuggestPuncList(mSuggestPuncs);
-
- // Get the settings preferences
- final boolean hasVibrator = VibratorCompatWrapper.getInstance(context).hasVibrator();
- mVibrateOn = hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON,
- res.getBoolean(R.bool.config_default_vibration_enabled));
- mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
- res.getBoolean(R.bool.config_default_sound_enabled));
- mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res);
- mKeyPreviewPopupDismissDelay = getKeyPreviewPopupDismissDelay(prefs, res);
- mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
- mAutoCorrectEnabled = isAutoCorrectEnabled(prefs, res);
- mBigramSuggestionEnabled = mAutoCorrectEnabled
- && isBigramSuggestionEnabled(prefs, res, mAutoCorrectEnabled);
- mBigramPredictionEnabled = mBigramSuggestionEnabled
- && isBigramPredictionEnabled(prefs, res);
- mAutoCorrectionThreshold = getAutoCorrectionThreshold(prefs, res);
- mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
- mEnableSuggestionSpanInsertion =
- prefs.getBoolean(Settings.PREF_KEY_ENABLE_SPAN_INSERT, true);
- final boolean defaultShowSettingsKey = res.getBoolean(
- R.bool.config_default_show_settings_key);
- mShowSettingsKey = isShowSettingsKeyOption(res)
- ? prefs.getBoolean(Settings.PREF_SHOW_SETTINGS_KEY, defaultShowSettingsKey)
- : defaultShowSettingsKey;
- final String voiceModeMain = res.getString(R.string.voice_mode_main);
- final String voiceModeOff = res.getString(R.string.voice_mode_off);
- final String voiceMode = prefs.getString(PREF_VOICE_SETTINGS_KEY, voiceModeMain);
- mVoiceKeyEnabled = voiceMode != null && !voiceMode.equals(voiceModeOff);
- mVoiceKeyOnMain = voiceMode != null && voiceMode.equals(voiceModeMain);
-
- LocaleUtils.setSystemLocale(res, savedLocale);
- }
- public boolean isSuggestedPunctuation(int code) {
- return mSuggestPuncs.contains(String.valueOf((char)code));
- }
-
- public boolean isWordSeparator(int code) {
- return mWordSeparators.contains(String.valueOf((char)code));
- }
-
- public boolean isSymbolExcludedFromWordSeparators(int code) {
- return mSymbolsExcludedFromWordSeparators.contains(String.valueOf((char)code));
- }
-
- public boolean isMagicSpaceStripper(int code) {
- return mMagicSpaceStrippers.contains(String.valueOf((char)code));
- }
-
- public boolean isMagicSpaceSwapper(int code) {
- return mMagicSpaceSwappers.contains(String.valueOf((char)code));
- }
-
- private static boolean isAutoCorrectEnabled(SharedPreferences sp, Resources resources) {
- final String currentAutoCorrectionSetting = sp.getString(
- Settings.PREF_AUTO_CORRECTION_THRESHOLD,
- resources.getString(R.string.auto_correction_threshold_mode_index_modest));
- final String autoCorrectionOff = resources.getString(
- R.string.auto_correction_threshold_mode_index_off);
- return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
- }
-
- // Public to access from KeyboardSwitcher. Should it have access to some
- // process-global instance instead?
- public static boolean isKeyPreviewPopupEnabled(SharedPreferences sp, Resources resources) {
- final boolean showPopupOption = resources.getBoolean(
- R.bool.config_enable_show_popup_on_keypress_option);
- if (!showPopupOption) return resources.getBoolean(R.bool.config_default_popup_preview);
- return sp.getBoolean(Settings.PREF_KEY_PREVIEW_POPUP_ON,
- resources.getBoolean(R.bool.config_default_popup_preview));
- }
-
- // Likewise
- public static int getKeyPreviewPopupDismissDelay(SharedPreferences sp,
- Resources resources) {
- return Integer.parseInt(sp.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
- Integer.toString(resources.getInteger(R.integer.config_delay_after_preview))));
- }
-
- private static boolean isBigramSuggestionEnabled(SharedPreferences sp, Resources resources,
- boolean autoCorrectEnabled) {
- final boolean showBigramSuggestionsOption = resources.getBoolean(
- R.bool.config_enable_bigram_suggestions_option);
- if (!showBigramSuggestionsOption) {
- return autoCorrectEnabled;
- }
- return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, resources.getBoolean(
- R.bool.config_default_bigram_suggestions));
- }
-
- private static boolean isBigramPredictionEnabled(SharedPreferences sp,
- Resources resources) {
- return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, resources.getBoolean(
- R.bool.config_default_bigram_prediction));
- }
-
- private static double getAutoCorrectionThreshold(SharedPreferences sp,
- Resources resources) {
- final String currentAutoCorrectionSetting = sp.getString(
- Settings.PREF_AUTO_CORRECTION_THRESHOLD,
- resources.getString(R.string.auto_correction_threshold_mode_index_modest));
- final String[] autoCorrectionThresholdValues = resources.getStringArray(
- R.array.auto_correction_threshold_values);
- // When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off.
- double autoCorrectionThreshold = Double.MAX_VALUE;
- try {
- final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting);
- if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) {
- autoCorrectionThreshold = Double.parseDouble(
- autoCorrectionThresholdValues[arrayIndex]);
- }
- } catch (NumberFormatException e) {
- // Whenever the threshold settings are correct, never come here.
- autoCorrectionThreshold = Double.MAX_VALUE;
- Log.w(TAG, "Cannot load auto correction threshold setting."
- + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting
- + ", autoCorrectionThresholdValues: "
- + Arrays.toString(autoCorrectionThresholdValues));
- }
- return autoCorrectionThreshold;
- }
-
- private static SuggestedWords createSuggestPuncList(final String puncs) {
- SuggestedWords.Builder builder = new SuggestedWords.Builder();
- if (puncs != null) {
- for (int i = 0; i < puncs.length(); i++) {
- builder.addWord(puncs.subSequence(i, i + 1));
- }
- }
- return builder.setIsPunctuationSuggestions().build();
- }
-
- public static boolean isShowSettingsKeyOption(final Resources resources) {
- return resources.getBoolean(R.bool.config_enable_show_settings_key_option);
-
- }
-
- public boolean isSettingsKeyEnabled() {
- return mShowSettingsKey;
- }
-
- public boolean isVoiceKeyEnabled(EditorInfo attribute) {
- final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
- final int inputType = (attribute != null) ? attribute.inputType : 0;
- return shortcutImeEnabled && mVoiceKeyEnabled
- && !InputTypeCompatUtils.isPasswordInputType(inputType);
- }
+ public static final String PREF_INPUT_LANGUAGE = "input_language";
+ public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
+ public static final String PREF_DEBUG_SETTINGS = "debug_settings";
- public boolean isVoiceKeyOnMain() {
- return mVoiceKeyOnMain;
- }
- }
+ // Dialog ids
+ private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
private PreferenceScreen mInputLanguageSelection;
private PreferenceScreen mKeypressVibrationDurationSettingsPref;
@@ -363,9 +144,9 @@ public class Settings extends InputMethodSettingsActivity
final Context context = getActivityInternal();
addPreferencesFromResource(R.xml.prefs);
- mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES);
+ mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES_SETTINGS);
mInputLanguageSelection.setOnPreferenceClickListener(this);
- mVoicePreference = (ListPreference) findPreference(PREF_VOICE_SETTINGS_KEY);
+ mVoicePreference = (ListPreference) findPreference(PREF_VOICE_MODE);
mShowSettingsKeyPreference = (CheckBoxPreference) findPreference(PREF_SHOW_SETTINGS_KEY);
mShowCorrectionSuggestionsPreference =
(ListPreference) findPreference(PREF_SHOW_SUGGESTIONS_SETTING);
@@ -373,12 +154,12 @@ public class Settings extends InputMethodSettingsActivity
prefs.registerOnSharedPreferenceChangeListener(this);
mVoiceModeOff = getString(R.string.voice_mode_off);
- mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
+ mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff)
.equals(mVoiceModeOff));
mAutoCorrectionThresholdPreference =
(ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD);
- mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTIONS);
+ mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTION);
mBigramPrediction = (CheckBoxPreference) findPreference(PREF_BIGRAM_PREDICTIONS);
mDebugSettingsPreference = findPreference(PREF_DEBUG_SETTINGS);
if (mDebugSettingsPreference != null) {
@@ -391,13 +172,13 @@ public class Settings extends InputMethodSettingsActivity
ensureConsistencyOfAutoCorrectionSettings();
final PreferenceGroup generalSettings =
- (PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS_KEY);
+ (PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS);
final PreferenceGroup textCorrectionGroup =
- (PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY);
+ (PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS);
final PreferenceGroup miscSettings =
- (PreferenceGroup) findPreference(PREF_MISC_SETTINGS_KEY);
+ (PreferenceGroup) findPreference(PREF_MISC_SETTINGS);
- if (!Values.isShowSettingsKeyOption(res)) {
+ if (!SettingsValues.isShowSettingsKeyOptionEnabled(res)) {
generalSettings.removePreference(mShowSettingsKeyPreference);
}
@@ -412,13 +193,13 @@ public class Settings extends InputMethodSettingsActivity
}
if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
- generalSettings.removePreference(findPreference(PREF_SUBTYPES));
+ generalSettings.removePreference(findPreference(PREF_SUBTYPES_SETTINGS));
}
final boolean showPopupOption = res.getBoolean(
R.bool.config_enable_show_popup_on_keypress_option);
if (!showPopupOption) {
- generalSettings.removePreference(findPreference(PREF_KEY_PREVIEW_POPUP_ON));
+ generalSettings.removePreference(findPreference(PREF_POPUP_ON));
}
final boolean showBigramSuggestionsOption = res.getBoolean(
@@ -437,14 +218,15 @@ public class Settings extends InputMethodSettingsActivity
res.getString(R.string.key_preview_popup_dismiss_default_delay),
};
final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
- R.integer.config_delay_after_preview));
+ R.integer.config_key_preview_linger_timeout));
mKeyPreviewPopupDismissDelay.setEntries(entries);
mKeyPreviewPopupDismissDelay.setEntryValues(
new String[] { "0", popupDismissDelayDefaultValue });
if (null == mKeyPreviewPopupDismissDelay.getValue()) {
mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
}
- mKeyPreviewPopupDismissDelay.setEnabled(Values.isKeyPreviewPopupEnabled(prefs, res));
+ mKeyPreviewPopupDismissDelay.setEnabled(
+ SettingsValues.isKeyPreviewPopupEnabled(prefs, res));
final PreferenceScreen dictionaryLink =
(PreferenceScreen) findPreference(PREF_CONFIGURE_DICTIONARIES_KEY);
@@ -455,17 +237,26 @@ public class Settings extends InputMethodSettingsActivity
textCorrectionGroup.removePreference(dictionaryLink);
}
- final boolean showUsabilityModeStudyOption = res.getBoolean(
- R.bool.config_enable_usability_study_mode_option);
- if (!showUsabilityModeStudyOption || !ENABLE_EXPERIMENTAL_SETTINGS) {
- final Preference pref = findPreference(PREF_USABILITY_STUDY_MODE);
- if (pref != null) {
- miscSettings.removePreference(pref);
+ final boolean isResearcherPackage = LatinImeLogger.isResearcherPackage(this);
+ final boolean showUsabilityStudyModeOption =
+ res.getBoolean(R.bool.config_enable_usability_study_mode_option)
+ || isResearcherPackage || ENABLE_EXPERIMENTAL_SETTINGS;
+ final Preference usabilityStudyPref = findPreference(PREF_USABILITY_STUDY_MODE);
+ if (!showUsabilityStudyModeOption) {
+ if (usabilityStudyPref != null) {
+ miscSettings.removePreference(usabilityStudyPref);
+ }
+ }
+ if (isResearcherPackage) {
+ if (usabilityStudyPref instanceof CheckBoxPreference) {
+ CheckBoxPreference checkbox = (CheckBoxPreference)usabilityStudyPref;
+ checkbox.setChecked(prefs.getBoolean(PREF_USABILITY_STUDY_MODE, true));
+ checkbox.setSummary(R.string.settings_warning_researcher_mode);
}
}
mKeypressVibrationDurationSettingsPref =
- (PreferenceScreen) findPreference(PREF_KEYPRESS_VIBRATION_DURATION_SETTINGS);
+ (PreferenceScreen) findPreference(PREF_VIBRATION_DURATION_SETTINGS);
if (mKeypressVibrationDurationSettingsPref != null) {
mKeypressVibrationDurationSettingsPref.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
@@ -521,20 +312,20 @@ public class Settings extends InputMethodSettingsActivity
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
(new BackupManager(getActivityInternal())).dataChanged();
// If turning on voice input, show dialog
- if (key.equals(PREF_VOICE_SETTINGS_KEY) && !mVoiceOn) {
- if (!prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
+ if (key.equals(PREF_VOICE_MODE) && !mVoiceOn) {
+ if (!prefs.getString(PREF_VOICE_MODE, mVoiceModeOff)
.equals(mVoiceModeOff)) {
showVoiceConfirmation();
}
- } else if (key.equals(PREF_KEY_PREVIEW_POPUP_ON)) {
+ } else if (key.equals(PREF_POPUP_ON)) {
final ListPreference popupDismissDelay =
(ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
if (null != popupDismissDelay) {
- popupDismissDelay.setEnabled(prefs.getBoolean(PREF_KEY_PREVIEW_POPUP_ON, true));
+ popupDismissDelay.setEnabled(prefs.getBoolean(PREF_POPUP_ON, true));
}
}
ensureConsistencyOfAutoCorrectionSettings();
- mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
+ mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff)
.equals(mVoiceModeOff));
updateVoiceModeSummary();
updateShowCorrectionSuggestionsSummary();
@@ -660,7 +451,7 @@ public class Settings extends InputMethodSettingsActivity
SharedPreferences sp, Resources res) {
if (mKeypressVibrationDurationSettingsPref != null) {
mKeypressVibrationDurationSettingsPref.setSummary(
- Utils.getCurrentVibrationDuration(sp, res)
+ SettingsValues.getCurrentVibrationDuration(sp, res)
+ res.getString(R.string.settings_ms));
}
}
@@ -676,7 +467,7 @@ public class Settings extends InputMethodSettingsActivity
public void onClick(DialogInterface dialog, int whichButton) {
final int ms = Integer.valueOf(
mKeypressVibrationDurationSettingsTextView.getText().toString());
- sp.edit().putInt(Settings.PREF_KEYPRESS_VIBRATION_DURATION_SETTINGS, ms).apply();
+ sp.edit().putInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, ms).apply();
updateKeypressVibrationDurationSettingsSummary(sp, res);
}
});
@@ -688,7 +479,7 @@ public class Settings extends InputMethodSettingsActivity
});
final View v = context.getLayoutInflater().inflate(
R.layout.vibration_settings_dialog, null);
- final int currentMs = Utils.getCurrentVibrationDuration(
+ final int currentMs = SettingsValues.getCurrentVibrationDuration(
getPreferenceManager().getSharedPreferences(), getResources());
mKeypressVibrationDurationSettingsTextView = (TextView)v.findViewById(R.id.vibration_value);
final SeekBar sb = (SeekBar)v.findViewById(R.id.vibration_settings);
@@ -717,8 +508,8 @@ public class Settings extends InputMethodSettingsActivity
private void updateKeypressSoundVolumeSummary(SharedPreferences sp, Resources res) {
if (mKeypressSoundVolumeSettingsPref != null) {
- mKeypressSoundVolumeSettingsPref.setSummary(
- String.valueOf((int)(Utils.getCurrentKeypressSoundVolume(sp, res) * 100)));
+ mKeypressSoundVolumeSettingsPref.setSummary(String.valueOf(
+ (int)(SettingsValues.getCurrentKeypressSoundVolume(sp, res) * 100)));
}
}
@@ -747,8 +538,8 @@ public class Settings extends InputMethodSettingsActivity
});
final View v = context.getLayoutInflater().inflate(
R.layout.sound_effect_volume_dialog, null);
- final int currentVolumeInt = (int)(Utils.getCurrentKeypressSoundVolume(
- getPreferenceManager().getSharedPreferences(), getResources()) * 100);
+ final int currentVolumeInt =
+ (int)(SettingsValues.getCurrentKeypressSoundVolume(sp, res) * 100);
mKeypressSoundVolumeSettingsTextView =
(TextView)v.findViewById(R.id.sound_effect_volume_value);
final SeekBar sb = (SeekBar)v.findViewById(R.id.sound_effect_volume_bar);
@@ -774,4 +565,4 @@ public class Settings extends InputMethodSettingsActivity
builder.setView(v);
builder.create().show();
}
-} \ No newline at end of file
+}
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
new file mode 100644
index 000000000..6b652313c
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2011 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.latin;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Build;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.inputmethod.compat.InputTypeCompatUtils;
+import com.android.inputmethod.compat.VibratorCompatWrapper;
+import com.android.inputmethod.keyboard.internal.KeySpecParser;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+public class SettingsValues {
+ private static final String TAG = SettingsValues.class.getSimpleName();
+
+ // From resources:
+ public final int mDelayUpdateOldSuggestions;
+ public final String mMagicSpaceStrippers;
+ public final String mMagicSpaceSwappers;
+ private final String mSuggestPuncs;
+ public final SuggestedWords mSuggestPuncList;
+ public final SuggestedWords mSuggestPuncOutputTextList;
+ private final String mSymbolsExcludedFromWordSeparators;
+ public final String mWordSeparators;
+ public final CharSequence mHintToSaveText;
+
+ // From preferences, in the same order as xml/prefs.xml:
+ public final boolean mAutoCap;
+ public final boolean mVibrateOn;
+ public final boolean mSoundOn;
+ public final boolean mKeyPreviewPopupOn;
+ private final boolean mShowSettingsKey;
+ private final String mVoiceMode;
+ private final String mAutoCorrectionThresholdRawValue;
+ public final String mShowSuggestionsSetting;
+ @SuppressWarnings("unused") // TODO: Use this
+ private final boolean mUsabilityStudyMode;
+ @SuppressWarnings("unused") // TODO: Use this
+ private final String mKeyPreviewPopupDismissDelayRawValue;
+ public final boolean mUseContactsDict;
+ // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
+ public final boolean mBigramSuggestionEnabled;
+ // Prediction: use bigrams to predict the next word when there is no input for it yet
+ public final boolean mBigramPredictionEnabled;
+ public final boolean mEnableSuggestionSpanInsertion;
+ @SuppressWarnings("unused") // TODO: Use this
+ private final int mVibrationDurationSettingsRawValue;
+ @SuppressWarnings("unused") // TODO: Use this
+ private final float mKeypressSoundVolumeRawValue;
+
+ // Deduced settings
+ public final int mKeypressVibrationDuration;
+ public final float mFxVolume;
+ public final int mKeyPreviewPopupDismissDelay;
+ public final boolean mAutoCorrectEnabled;
+ public final double mAutoCorrectionThreshold;
+ private final boolean mVoiceKeyEnabled;
+ private final boolean mVoiceKeyOnMain;
+
+ public SettingsValues(final SharedPreferences prefs, final Context context,
+ final String localeStr) {
+ final Resources res = context.getResources();
+ final Locale savedLocale;
+ if (null != localeStr) {
+ final Locale keyboardLocale = LocaleUtils.constructLocaleFromString(localeStr);
+ savedLocale = LocaleUtils.setSystemLocale(res, keyboardLocale);
+ } else {
+ savedLocale = null;
+ }
+
+ // Get the resources
+ mDelayUpdateOldSuggestions = res.getInteger(R.integer.config_delay_update_old_suggestions);
+ mMagicSpaceStrippers = res.getString(R.string.magic_space_stripping_symbols);
+ mMagicSpaceSwappers = res.getString(R.string.magic_space_swapping_symbols);
+ if (LatinImeLogger.sDBG) {
+ final int length = mMagicSpaceStrippers.length();
+ for (int i = 0; i < length; i = mMagicSpaceStrippers.offsetByCodePoints(i, 1)) {
+ if (isMagicSpaceSwapper(mMagicSpaceStrippers.codePointAt(i))) {
+ throw new RuntimeException("Char code " + mMagicSpaceStrippers.codePointAt(i)
+ + " is both a magic space swapper and stripper.");
+ }
+ }
+ }
+ final String[] suggestPuncsSpec = KeySpecParser.parseCsvString(
+ res.getString(R.string.suggested_punctuations), res, R.string.english_ime_name);
+ mSuggestPuncs = createSuggestPuncs(suggestPuncsSpec);
+ mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+ mSuggestPuncOutputTextList = createSuggestPuncOutputTextList(suggestPuncsSpec);
+ mSymbolsExcludedFromWordSeparators =
+ res.getString(R.string.symbols_excluded_from_word_separators);
+ mWordSeparators = createWordSeparators(mMagicSpaceStrippers, mMagicSpaceSwappers,
+ mSymbolsExcludedFromWordSeparators, res);
+ mHintToSaveText = context.getText(R.string.hint_add_to_dictionary);
+
+ // Get the settings preferences
+ mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
+ mVibrateOn = isVibrateOn(context, prefs, res);
+ mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
+ res.getBoolean(R.bool.config_default_sound_enabled));
+ mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res);
+ mShowSettingsKey = isSettingsKeyShown(prefs, res);
+ final String voiceModeMain = res.getString(R.string.voice_mode_main);
+ final String voiceModeOff = res.getString(R.string.voice_mode_off);
+ mVoiceMode = prefs.getString(Settings.PREF_VOICE_MODE, voiceModeMain);
+ mAutoCorrectionThresholdRawValue = prefs.getString(Settings.PREF_AUTO_CORRECTION_THRESHOLD,
+ res.getString(R.string.auto_correction_threshold_mode_index_modest));
+ mShowSuggestionsSetting = prefs.getString(Settings.PREF_SHOW_SUGGESTIONS_SETTING,
+ res.getString(R.string.prefs_suggestion_visibility_default_value));
+ mUsabilityStudyMode = getUsabilityStudyMode(prefs);
+ mKeyPreviewPopupDismissDelayRawValue = prefs.getString(
+ Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+ Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout)));
+ mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
+ mAutoCorrectEnabled = isAutoCorrectEnabled(res, mAutoCorrectionThresholdRawValue);
+ mBigramSuggestionEnabled = mAutoCorrectEnabled
+ && isBigramSuggestionEnabled(prefs, res, mAutoCorrectEnabled);
+ mBigramPredictionEnabled = mBigramSuggestionEnabled
+ && isBigramPredictionEnabled(prefs, res);
+ mEnableSuggestionSpanInsertion =
+ prefs.getBoolean(Settings.PREF_KEY_ENABLE_SPAN_INSERT, true);
+ mVibrationDurationSettingsRawValue =
+ prefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, -1);
+ mKeypressSoundVolumeRawValue = prefs.getFloat(Settings.PREF_KEYPRESS_SOUND_VOLUME, -1.0f);
+
+ // Compute other readable settings
+ mKeypressVibrationDuration = getCurrentVibrationDuration(prefs, res);
+ mFxVolume = getCurrentKeypressSoundVolume(prefs, res);
+ mKeyPreviewPopupDismissDelay = getKeyPreviewPopupDismissDelay(prefs, res);
+ mAutoCorrectionThreshold = getAutoCorrectionThreshold(res,
+ mAutoCorrectionThresholdRawValue);
+ mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
+ mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
+
+ LocaleUtils.setSystemLocale(res, savedLocale);
+ }
+
+ // Helper functions to create member values.
+ private static String createSuggestPuncs(final String[] puncs) {
+ final StringBuilder sb = new StringBuilder();
+ if (puncs != null) {
+ for (final String puncSpec : puncs) {
+ sb.append(KeySpecParser.getLabel(puncSpec));
+ }
+ }
+ return sb.toString();
+ }
+
+ private static SuggestedWords createSuggestPuncList(final String[] puncs) {
+ final SuggestedWords.Builder builder = new SuggestedWords.Builder();
+ if (puncs != null) {
+ for (final String puncSpec : puncs) {
+ builder.addWord(KeySpecParser.getLabel(puncSpec));
+ }
+ }
+ return builder.setIsPunctuationSuggestions().build();
+ }
+
+ private static SuggestedWords createSuggestPuncOutputTextList(final String[] puncs) {
+ final SuggestedWords.Builder builder = new SuggestedWords.Builder();
+ if (puncs != null) {
+ for (final String puncSpec : puncs) {
+ final String outputText = KeySpecParser.getOutputText(puncSpec);
+ if (outputText != null) {
+ builder.addWord(outputText);
+ } else {
+ builder.addWord(KeySpecParser.getLabel(puncSpec));
+ }
+ }
+ }
+ return builder.setIsPunctuationSuggestions().build();
+ }
+
+ private static String createWordSeparators(final String magicSpaceStrippers,
+ final String magicSpaceSwappers, final String symbolsExcludedFromWordSeparators,
+ final Resources res) {
+ String wordSeparators = magicSpaceStrippers + magicSpaceSwappers
+ + res.getString(R.string.magic_space_promoting_symbols);
+ for (int i = symbolsExcludedFromWordSeparators.length() - 1; i >= 0; --i) {
+ wordSeparators = wordSeparators.replace(
+ symbolsExcludedFromWordSeparators.substring(i, i + 1), "");
+ }
+ return wordSeparators;
+ }
+
+ private static boolean isSettingsKeyShown(final SharedPreferences prefs, final Resources res) {
+ final boolean defaultShowSettingsKey = res.getBoolean(
+ R.bool.config_default_show_settings_key);
+ return isShowSettingsKeyOptionEnabled(res)
+ ? prefs.getBoolean(Settings.PREF_SHOW_SETTINGS_KEY, defaultShowSettingsKey)
+ : defaultShowSettingsKey;
+ }
+
+ public static boolean isShowSettingsKeyOptionEnabled(final Resources resources) {
+ // TODO: Read this once and for all into a public final member
+ return resources.getBoolean(R.bool.config_enable_show_settings_key_option);
+ }
+
+ private static boolean isVibrateOn(final Context context, final SharedPreferences prefs,
+ final Resources res) {
+ final boolean hasVibrator = VibratorCompatWrapper.getInstance(context).hasVibrator();
+ return hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON,
+ res.getBoolean(R.bool.config_default_vibration_enabled));
+ }
+
+ public boolean isWordSeparator(int code) {
+ return mWordSeparators.contains(String.valueOf((char)code));
+ }
+
+ public boolean isSymbolExcludedFromWordSeparators(int code) {
+ return mSymbolsExcludedFromWordSeparators.contains(String.valueOf((char)code));
+ }
+
+ public boolean isMagicSpaceStripper(int code) {
+ // TODO: this does not work if the code does not fit in a char
+ return mMagicSpaceStrippers.contains(String.valueOf((char)code));
+ }
+
+ public boolean isMagicSpaceSwapper(int code) {
+ // TODO: this does not work if the code does not fit in a char
+ return mMagicSpaceSwappers.contains(String.valueOf((char)code));
+ }
+
+ private static boolean isAutoCorrectEnabled(final Resources resources,
+ final String currentAutoCorrectionSetting) {
+ final String autoCorrectionOff = resources.getString(
+ R.string.auto_correction_threshold_mode_index_off);
+ return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
+ }
+
+ // Public to access from KeyboardSwitcher. Should it have access to some
+ // process-global instance instead?
+ public static boolean isKeyPreviewPopupEnabled(SharedPreferences sp, Resources resources) {
+ final boolean showPopupOption = resources.getBoolean(
+ R.bool.config_enable_show_popup_on_keypress_option);
+ if (!showPopupOption) return resources.getBoolean(R.bool.config_default_popup_preview);
+ return sp.getBoolean(Settings.PREF_POPUP_ON,
+ resources.getBoolean(R.bool.config_default_popup_preview));
+ }
+
+ // Likewise
+ public static int getKeyPreviewPopupDismissDelay(SharedPreferences sp,
+ Resources resources) {
+ // TODO: use mKeyPreviewPopupDismissDelayRawValue instead of reading it again here.
+ return Integer.parseInt(sp.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+ Integer.toString(resources.getInteger(
+ R.integer.config_key_preview_linger_timeout))));
+ }
+
+ private static boolean isBigramSuggestionEnabled(final SharedPreferences sp,
+ final Resources resources, final boolean autoCorrectEnabled) {
+ final boolean showBigramSuggestionsOption = resources.getBoolean(
+ R.bool.config_enable_bigram_suggestions_option);
+ if (!showBigramSuggestionsOption) {
+ return autoCorrectEnabled;
+ }
+ return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTION, resources.getBoolean(
+ R.bool.config_default_bigram_suggestions));
+ }
+
+ private static boolean isBigramPredictionEnabled(final SharedPreferences sp,
+ final Resources resources) {
+ return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, resources.getBoolean(
+ R.bool.config_default_bigram_prediction));
+ }
+
+ private static double getAutoCorrectionThreshold(final Resources resources,
+ final String currentAutoCorrectionSetting) {
+ final String[] autoCorrectionThresholdValues = resources.getStringArray(
+ R.array.auto_correction_threshold_values);
+ // When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off.
+ double autoCorrectionThreshold = Double.MAX_VALUE;
+ try {
+ final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting);
+ if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) {
+ autoCorrectionThreshold = Double.parseDouble(
+ autoCorrectionThresholdValues[arrayIndex]);
+ }
+ } catch (NumberFormatException e) {
+ // Whenever the threshold settings are correct, never come here.
+ autoCorrectionThreshold = Double.MAX_VALUE;
+ Log.w(TAG, "Cannot load auto correction threshold setting."
+ + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting
+ + ", autoCorrectionThresholdValues: "
+ + Arrays.toString(autoCorrectionThresholdValues));
+ }
+ return autoCorrectionThreshold;
+ }
+
+ public boolean isSettingsKeyEnabled() {
+ return mShowSettingsKey;
+ }
+
+ public boolean isVoiceKeyEnabled(final EditorInfo editorInfo) {
+ final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
+ final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
+ return shortcutImeEnabled && mVoiceKeyEnabled
+ && !InputTypeCompatUtils.isPasswordInputType(inputType);
+ }
+
+ public boolean isVoiceKeyOnMain() {
+ return mVoiceKeyOnMain;
+ }
+
+ public boolean isFullscreenModeAllowed(Resources res) {
+ return res.getBoolean(R.bool.config_use_fullscreen_mode);
+ }
+
+ // Accessed from the settings interface, hence public
+ public static float getCurrentKeypressSoundVolume(final SharedPreferences sp,
+ final Resources res) {
+ // TODO: use mVibrationDurationSettingsRawValue instead of reading it again here
+ final float volume = sp.getFloat(Settings.PREF_KEYPRESS_SOUND_VOLUME, -1.0f);
+ if (volume >= 0) {
+ return volume;
+ }
+
+ final String[] volumePerHardwareList = res.getStringArray(R.array.keypress_volumes);
+ final String hardwarePrefix = Build.HARDWARE + ",";
+ for (final String element : volumePerHardwareList) {
+ if (element.startsWith(hardwarePrefix)) {
+ return Float.parseFloat(element.substring(element.lastIndexOf(',') + 1));
+ }
+ }
+ return -1.0f;
+ }
+
+ // Likewise
+ public static int getCurrentVibrationDuration(final SharedPreferences sp,
+ final Resources res) {
+ // TODO: use mKeypressVibrationDuration instead of reading it again here
+ final int ms = sp.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, -1);
+ if (ms >= 0) {
+ return ms;
+ }
+ final String[] durationPerHardwareList = res.getStringArray(
+ R.array.keypress_vibration_durations);
+ final String hardwarePrefix = Build.HARDWARE + ",";
+ for (final String element : durationPerHardwareList) {
+ if (element.startsWith(hardwarePrefix)) {
+ return (int)Long.parseLong(element.substring(element.lastIndexOf(',') + 1));
+ }
+ }
+ return -1;
+ }
+
+ // Likewise
+ public static boolean getUsabilityStudyMode(final SharedPreferences prefs) {
+ // TODO: use mUsabilityStudyMode instead of reading it again here
+ return prefs.getBoolean(Settings.PREF_USABILITY_STUDY_MODE, true);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 8a4862094..f5778167a 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -35,7 +35,6 @@ import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.LatinKeyboard;
import java.util.ArrayList;
import java.util.Arrays;
@@ -47,8 +46,8 @@ public class SubtypeSwitcher {
private static boolean DBG = LatinImeLogger.sDBG;
private static final String TAG = SubtypeSwitcher.class.getSimpleName();
+ public static final String KEYBOARD_MODE = "keyboard";
private static final char LOCALE_SEPARATER = '_';
- private static final String KEYBOARD_MODE = "keyboard";
private static final String VOICE_MODE = "voice";
private static final String SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY =
"requireNetworkConnectivity";
@@ -421,11 +420,7 @@ public class SubtypeSwitcher {
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
mIsNetworkConnected = !noConnection;
- final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
- final LatinKeyboard keyboard = switcher.getLatinKeyboard();
- if (keyboard != null) {
- keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getKeyboardView());
- }
+ KeyboardSwitcher.getInstance().onNetworkStateChanged();
}
//////////////////////////////////
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index caa5aac51..f6e177aaf 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.ProximityInfo;
import java.io.File;
@@ -42,9 +43,8 @@ public class Suggest implements Dictionary.WordCallback {
public static final int APPROX_MAX_WORD_LENGTH = 32;
public static final int CORRECTION_NONE = 0;
- public static final int CORRECTION_BASIC = 1;
- public static final int CORRECTION_FULL = 2;
- public static final int CORRECTION_FULL_BIGRAM = 3;
+ public static final int CORRECTION_FULL = 1;
+ public static final int CORRECTION_FULL_BIGRAM = 2;
/**
* Words that appear in both bigram and unigram data gets multiplier ranging from
@@ -101,13 +101,12 @@ public class Suggest implements Dictionary.WordCallback {
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
- private CharSequence mTypedWord;
+ private CharSequence mConsideredWord;
// TODO: Remove these member variables by passing more context to addWord() callback method
private boolean mIsFirstCharCapitalized;
private boolean mIsAllUpperCase;
-
- private int mCorrectionMode = CORRECTION_BASIC;
+ private int mTrailingSingleQuotesCount;
public Suggest(final Context context, final int dictionaryResId, final Locale locale) {
initAsynchronously(context, dictionaryResId, locale);
@@ -116,7 +115,7 @@ public class Suggest implements Dictionary.WordCallback {
/* package for test */ Suggest(final Context context, final File dictionary,
final long startOffset, final long length, final Flag[] flagArray,
final Locale locale) {
- initSynchronously(null, DictionaryFactory.createDictionaryForTest(context, dictionary,
+ initSynchronously(context, DictionaryFactory.createDictionaryForTest(context, dictionary,
startOffset, length, flagArray), locale);
}
@@ -144,7 +143,7 @@ public class Suggest implements Dictionary.WordCallback {
initWhitelistAndAutocorrectAndPool(context, locale);
}
- private void addOrReplaceDictionary(Map<String, Dictionary> dictionaries, String key,
+ private static void addOrReplaceDictionary(Map<String, Dictionary> dictionaries, String key,
Dictionary dict) {
final Dictionary oldDict = (dict == null)
? dictionaries.remove(key)
@@ -169,14 +168,6 @@ public class Suggest implements Dictionary.WordCallback {
}.start();
}
- public int getCorrectionMode() {
- return mCorrectionMode;
- }
-
- public void setCorrectionMode(int mode) {
- mCorrectionMode = mode;
- }
-
// The main dictionary could have been loaded asynchronously. Don't cache the return value
// of this method.
public boolean hasMainDictionary() {
@@ -255,9 +246,10 @@ public class Suggest implements Dictionary.WordCallback {
* @return suggested words object.
*/
public SuggestedWords getSuggestions(final WordComposer wordComposer,
- final CharSequence prevWordForBigram, final ProximityInfo proximityInfo) {
+ final CharSequence prevWordForBigram, final ProximityInfo proximityInfo,
+ final int correctionMode) {
return getSuggestedWordBuilder(wordComposer, prevWordForBigram,
- proximityInfo).build();
+ proximityInfo, correctionMode).build();
}
private CharSequence capitalizeWord(boolean all, boolean first, CharSequence word) {
@@ -290,25 +282,27 @@ public class Suggest implements Dictionary.WordCallback {
// TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder
public SuggestedWords.Builder getSuggestedWordBuilder(
final WordComposer wordComposer, CharSequence prevWordForBigram,
- final ProximityInfo proximityInfo) {
+ final ProximityInfo proximityInfo, final int correctionMode) {
LatinImeLogger.onStartSuggestion(prevWordForBigram);
mAutoCorrection.init();
mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
mIsAllUpperCase = wordComposer.isAllUpperCase();
+ mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
collectGarbage(mSuggestions, mPrefMaxSuggestions);
Arrays.fill(mScores, 0);
- // Save a lowercase version of the original word
- String typedWord = wordComposer.getTypedWord();
+ final String typedWord = wordComposer.getTypedWord();
+ final String consideredWord = mTrailingSingleQuotesCount > 0
+ ? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount)
+ : typedWord;
if (typedWord != null) {
// Treating USER_TYPED as UNIGRAM suggestion for logging now.
LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED,
- Dictionary.DataType.UNIGRAM);
+ Dictionary.UNIGRAM);
}
- mTypedWord = typedWord;
+ mConsideredWord = consideredWord;
- if (wordComposer.size() <= 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM
- || mCorrectionMode == CORRECTION_BASIC)) {
+ if (wordComposer.size() <= 1 && (correctionMode == CORRECTION_FULL_BIGRAM)) {
// At first character typed, search only the bigrams
Arrays.fill(mBigramScores, 0);
collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS);
@@ -321,7 +315,7 @@ public class Suggest implements Dictionary.WordCallback {
for (final Dictionary dictionary : mBigramDictionaries.values()) {
dictionary.getBigrams(wordComposer, prevWordForBigram, this);
}
- if (TextUtils.isEmpty(typedWord)) {
+ if (TextUtils.isEmpty(consideredWord)) {
// Nothing entered: return all bigrams for the previous word
int insertCount = Math.min(mBigramSuggestions.size(), mPrefMaxSuggestions);
for (int i = 0; i < insertCount; ++i) {
@@ -330,7 +324,7 @@ public class Suggest implements Dictionary.WordCallback {
} else {
// Word entered: return only bigrams that match the first char of the typed word
@SuppressWarnings("null")
- final char currentChar = typedWord.charAt(0);
+ final char currentChar = consideredWord.charAt(0);
// TODO: Must pay attention to locale when changing case.
final char currentCharUpper = Character.toUpperCase(currentChar);
int count = 0;
@@ -354,24 +348,41 @@ public class Suggest implements Dictionary.WordCallback {
if (key.equals(DICT_KEY_USER_UNIGRAM) || key.equals(DICT_KEY_WHITELIST))
continue;
final Dictionary dictionary = mUnigramDictionaries.get(key);
- dictionary.getWords(wordComposer, this, proximityInfo);
+ if (mTrailingSingleQuotesCount > 0) {
+ final WordComposer tmpWordComposer = new WordComposer(wordComposer);
+ for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) {
+ tmpWordComposer.deleteLast();
+ }
+ dictionary.getWords(tmpWordComposer, this, proximityInfo);
+ } else {
+ dictionary.getWords(wordComposer, this, proximityInfo);
+ }
}
}
- final String typedWordString = typedWord == null ? null : typedWord.toString();
+ final String consideredWordString =
+ consideredWord == null ? null : consideredWord.toString();
CharSequence whitelistedWord = capitalizeWord(mIsAllUpperCase, mIsFirstCharCapitalized,
- mWhiteListDictionary.getWhitelistedWord(typedWordString));
+ mWhiteListDictionary.getWhitelistedWord(consideredWordString));
mAutoCorrection.updateAutoCorrectionStatus(mUnigramDictionaries, wordComposer,
- mSuggestions, mScores, typedWord, mAutoCorrectionThreshold, mCorrectionMode,
+ mSuggestions, mScores, consideredWord, mAutoCorrectionThreshold, correctionMode,
whitelistedWord);
if (whitelistedWord != null) {
- mSuggestions.add(0, whitelistedWord);
+ if (mTrailingSingleQuotesCount > 0) {
+ final StringBuilder sb = new StringBuilder(whitelistedWord);
+ for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) {
+ sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
+ }
+ mSuggestions.add(0, sb.toString());
+ } else {
+ mSuggestions.add(0, whitelistedWord);
+ }
}
if (typedWord != null) {
- mSuggestions.add(0, typedWordString);
+ mSuggestions.add(0, typedWord.toString());
}
Utils.removeDupes(mSuggestions);
@@ -406,12 +417,12 @@ public class Suggest implements Dictionary.WordCallback {
@Override
public boolean addWord(final char[] word, final int offset, final int length, int score,
- final int dicTypeId, final Dictionary.DataType dataType) {
- Dictionary.DataType dataTypeForLog = dataType;
+ final int dicTypeId, final int dataType) {
+ int dataTypeForLog = dataType;
final ArrayList<CharSequence> suggestions;
final int[] sortedScores;
final int prefMaxSuggestions;
- if(dataType == Dictionary.DataType.BIGRAM) {
+ if (dataType == Dictionary.BIGRAM) {
suggestions = mBigramSuggestions;
sortedScores = mBigramScores;
prefMaxSuggestions = PREF_MAX_BIGRAMS;
@@ -424,7 +435,7 @@ public class Suggest implements Dictionary.WordCallback {
int pos = 0;
// Check if it's the same word, only caps are different
- if (Utils.equalsIgnoreCase(mTypedWord, word, offset, length)) {
+ if (Utils.equalsIgnoreCase(mConsideredWord, word, offset, length)) {
// TODO: remove this surrounding if clause and move this logic to
// getSuggestedWordBuilder.
if (suggestions.size() > 0) {
@@ -439,11 +450,11 @@ public class Suggest implements Dictionary.WordCallback {
}
}
} else {
- if (dataType == Dictionary.DataType.UNIGRAM) {
+ if (dataType == Dictionary.UNIGRAM) {
// Check if the word was already added before (by bigram data)
int bigramSuggestion = searchBigramSuggestion(word,offset,length);
if(bigramSuggestion >= 0) {
- dataTypeForLog = Dictionary.DataType.BIGRAM;
+ dataTypeForLog = Dictionary.BIGRAM;
// turn freq from bigram into multiplier specified above
double multiplier = (((double) mBigramScores[bigramSuggestion])
/ MAXIMUM_BIGRAM_FREQUENCY)
@@ -486,6 +497,9 @@ public class Suggest implements Dictionary.WordCallback {
} else {
sb.append(word, offset, length);
}
+ for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) {
+ sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
+ }
suggestions.add(pos, sb);
if (suggestions.size() > prefMaxSuggestions) {
final CharSequence garbage = suggestions.remove(prefMaxSuggestions);
@@ -518,7 +532,8 @@ public class Suggest implements Dictionary.WordCallback {
return -1;
}
- private void collectGarbage(ArrayList<CharSequence> suggestions, int prefMaxSuggestions) {
+ private static void collectGarbage(ArrayList<CharSequence> suggestions,
+ int prefMaxSuggestions) {
int poolSize = StringBuilderPool.getSize();
int garbageSize = suggestions.size();
while (poolSize < prefMaxSuggestions && garbageSize > 0) {
diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java
deleted file mode 100644
index 79b3bdebb..000000000
--- a/java/src/com/android/inputmethod/latin/TextEntryState.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2008 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.latin;
-
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.Utils.RingCharBuffer;
-
-import android.util.Log;
-
-public class TextEntryState {
- private static final String TAG = TextEntryState.class.getSimpleName();
- private static final boolean DEBUG = false;
-
- private static final int UNKNOWN = 0;
- private static final int START = 1;
- private static final int IN_WORD = 2;
- private static final int ACCEPTED_DEFAULT = 3;
- private static final int PICKED_SUGGESTION = 4;
- private static final int PUNCTUATION_AFTER_WORD = 5;
- private static final int PUNCTUATION_AFTER_ACCEPTED = 6;
- private static final int SPACE_AFTER_ACCEPTED = 7;
- private static final int SPACE_AFTER_PICKED = 8;
- private static final int UNDO_COMMIT = 9;
- private static final int RECORRECTING = 10;
- private static final int PICKED_RECORRECTION = 11;
-
- private static int sState = UNKNOWN;
- private static int sPreviousState = UNKNOWN;
-
- private static void setState(final int newState) {
- sPreviousState = sState;
- sState = newState;
- }
-
- public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord,
- int separatorCode) {
- if (typedWord == null) return;
- setState(ACCEPTED_DEFAULT);
- LatinImeLogger.logOnAutoCorrection(
- typedWord.toString(), actualWord.toString(), separatorCode);
- if (DEBUG)
- displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord);
- }
-
- // State.ACCEPTED_DEFAULT will be changed to other sub-states
- // (see "case ACCEPTED_DEFAULT" in typedCharacter() below),
- // and should be restored back to State.ACCEPTED_DEFAULT after processing for each sub-state.
- public static void backToAcceptedDefault(CharSequence typedWord) {
- if (typedWord == null) return;
- switch (sState) {
- case SPACE_AFTER_ACCEPTED:
- case PUNCTUATION_AFTER_ACCEPTED:
- case IN_WORD:
- setState(ACCEPTED_DEFAULT);
- break;
- default:
- break;
- }
- if (DEBUG) displayState("backToAcceptedDefault", "typedWord", typedWord);
- }
-
- public static void acceptedTyped(CharSequence typedWord) {
- setState(PICKED_SUGGESTION);
- if (DEBUG) displayState("acceptedTyped", "typedWord", typedWord);
- }
-
- public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
- if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
- setState(PICKED_RECORRECTION);
- } else {
- setState(PICKED_SUGGESTION);
- }
- if (DEBUG)
- displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord);
- }
-
- public static void selectedForRecorrection() {
- setState(RECORRECTING);
- if (DEBUG) displayState("selectedForRecorrection");
- }
-
- public static void onAbortRecorrection() {
- if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
- setState(START);
- }
- if (DEBUG) displayState("onAbortRecorrection");
- }
-
- public static void typedCharacter(char c, boolean isSeparator, int x, int y) {
- final boolean isSpace = (c == Keyboard.CODE_SPACE);
- switch (sState) {
- case IN_WORD:
- if (isSpace || isSeparator) {
- setState(START);
- } else {
- // State hasn't changed.
- }
- break;
- case ACCEPTED_DEFAULT:
- case SPACE_AFTER_PICKED:
- case PUNCTUATION_AFTER_ACCEPTED:
- if (isSpace) {
- setState(SPACE_AFTER_ACCEPTED);
- } else if (isSeparator) {
- // Swap
- setState(PUNCTUATION_AFTER_ACCEPTED);
- } else {
- setState(IN_WORD);
- }
- break;
- case PICKED_SUGGESTION:
- case PICKED_RECORRECTION:
- if (isSpace) {
- setState(SPACE_AFTER_PICKED);
- } else if (isSeparator) {
- // Swap
- setState(PUNCTUATION_AFTER_ACCEPTED);
- } else {
- setState(IN_WORD);
- }
- break;
- case START:
- case UNKNOWN:
- case SPACE_AFTER_ACCEPTED:
- case PUNCTUATION_AFTER_WORD:
- if (!isSpace && !isSeparator) {
- setState(IN_WORD);
- } else {
- setState(START);
- }
- break;
- case UNDO_COMMIT:
- if (isSpace || isSeparator) {
- setState(START);
- } else {
- setState(IN_WORD);
- }
- break;
- case RECORRECTING:
- setState(START);
- break;
- }
- RingCharBuffer.getInstance().push(c, x, y);
- if (isSeparator) {
- LatinImeLogger.logOnInputSeparator();
- } else {
- LatinImeLogger.logOnInputChar();
- }
- if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator);
- }
-
- public static void backspace() {
- if (sState == ACCEPTED_DEFAULT) {
- setState(UNDO_COMMIT);
- LatinImeLogger.logOnAutoCorrectionCancelled();
- } else if (sState == UNDO_COMMIT) {
- setState(IN_WORD);
- }
- if (DEBUG) displayState("backspace");
- }
-
- public static void reset() {
- setState(START);
- if (DEBUG) displayState("reset");
- }
-
- public static boolean isAcceptedDefault() {
- return sState == ACCEPTED_DEFAULT;
- }
-
- public static boolean isSpaceAfterPicked() {
- return sState == SPACE_AFTER_PICKED;
- }
-
- public static boolean isUndoCommit() {
- return sState == UNDO_COMMIT;
- }
-
- public static boolean isPunctuationAfterAccepted() {
- return sState == PUNCTUATION_AFTER_ACCEPTED;
- }
-
- public static boolean isRecorrecting() {
- return sState == RECORRECTING || sState == PICKED_RECORRECTION;
- }
-
- public static String getState() {
- return stateName(sState);
- }
-
- private static String stateName(int state) {
- switch (state) {
- case START: return "START";
- case IN_WORD: return "IN_WORD";
- case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT";
- case PICKED_SUGGESTION: return "PICKED_SUGGESTION";
- case PUNCTUATION_AFTER_WORD: return "PUNCTUATION_AFTER_WORD";
- case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED";
- case SPACE_AFTER_ACCEPTED: return "SPACE_AFTER_ACCEPTED";
- case SPACE_AFTER_PICKED: return "SPACE_AFTER_PICKED";
- case UNDO_COMMIT: return "UNDO_COMMIT";
- case RECORRECTING: return "RECORRECTING";
- case PICKED_RECORRECTION: return "PICKED_RECORRECTION";
- default: return "UNKNOWN";
- }
- }
-
- private static void displayState(String title, Object ... args) {
- final StringBuilder sb = new StringBuilder(title);
- sb.append(':');
- for (int i = 0; i < args.length; i += 2) {
- sb.append(' ');
- sb.append(args[i]);
- sb.append('=');
- sb.append(args[i+1].toString());
- }
- sb.append(" state=");
- sb.append(stateName(sState));
- sb.append(" previous=");
- sb.append(stateName(sPreviousState));
- Log.d(TAG, sb.toString());
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
index 9e656675e..f80534cb5 100644
--- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
@@ -159,7 +159,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
*/
public int addBigrams(String word1, String word2) {
// remove caps if second word is autocapitalized
- if (mIme != null && mIme.getCurrentWord().isAutoCapitalized()) {
+ if (mIme != null && mIme.isAutoCapitalized()) {
word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1);
}
// Do not insert a word as a bigram of itself
@@ -238,7 +238,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
/**
* Query the database
*/
- private Cursor query(String selection, String[] selectionArgs) {
+ private static Cursor query(String selection, String[] selectionArgs) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
// main INNER JOIN frequency ON (main._id=freq.pair_id)
@@ -310,7 +310,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
}
/** Prune any old data if the database is getting too big. */
- private void checkPruneData(SQLiteDatabase db) {
+ private static void checkPruneData(SQLiteDatabase db) {
db.execSQL("PRAGMA foreign_keys = ON;");
Cursor c = db.query(FREQ_TABLE_NAME, new String[] { FREQ_COLUMN_PAIR_ID },
null, null, null, null, null);
@@ -380,7 +380,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
return null;
}
- private ContentValues getContentValues(String word1, String word2, String locale) {
+ private static ContentValues getContentValues(String word1, String word2, String locale) {
ContentValues values = new ContentValues(3);
values.put(MAIN_COLUMN_WORD1, word1);
values.put(MAIN_COLUMN_WORD2, word2);
@@ -388,7 +388,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
return values;
}
- private ContentValues getFrequencyContentValues(int pairId, int frequency) {
+ private static ContentValues getFrequencyContentValues(int pairId, int frequency) {
ContentValues values = new ContentValues(2);
values.put(FREQ_COLUMN_PAIR_ID, pairId);
values.put(FREQ_COLUMN_FREQUENCY, frequency);
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index 0bbbf3995..6d6296e10 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -18,12 +18,10 @@ package com.android.inputmethod.latin;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
-import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
-import android.net.Uri;
-import android.os.RemoteException;
import android.provider.UserDictionary.Words;
import android.text.TextUtils;
@@ -38,11 +36,9 @@ public class UserDictionary extends ExpandableDictionary {
Words.FREQUENCY,
};
- private static final String[] PROJECTION_ADD = {
- Words._ID,
- Words.FREQUENCY,
- Words.LOCALE,
- };
+ // This is not exported by the framework so we pretty much have to write it here verbatim
+ private static final String ACTION_USER_DICTIONARY_INSERT =
+ "com.android.settings.USER_DICTIONARY_INSERT";
private ContentObserver mObserver;
final private String mLocale;
@@ -134,7 +130,11 @@ public class UserDictionary extends ExpandableDictionary {
final Cursor cursor = getContext().getContentResolver()
.query(Words.CONTENT_URI, PROJECTION_QUERY, request.toString(),
requestArguments, null);
- addWords(cursor);
+ try {
+ addWords(cursor);
+ } finally {
+ if (null != cursor) cursor.close();
+ }
}
public boolean isEnabled() {
@@ -160,54 +160,19 @@ public class UserDictionary extends ExpandableDictionary {
public synchronized void addWord(final String word, final int frequency) {
// Force load the dictionary here synchronously
if (getRequiresReload()) loadDictionaryAsync();
+ // TODO: do something for the UI. With the following, any sufficiently long word will
+ // look like it will go to the user dictionary but it won't.
// Safeguard against adding long words. Can cause stack overflow.
if (word.length() >= getMaxWordLength()) return;
super.addWord(word, frequency);
- // Update the user dictionary provider
- final ContentValues values = new ContentValues(5);
- values.put(Words.WORD, word);
- values.put(Words.FREQUENCY, frequency);
- values.put(Words.LOCALE, mLocale);
- values.put(Words.APP_ID, 0);
-
- final ContentResolver contentResolver = getContext().getContentResolver();
- final ContentProviderClient client =
- contentResolver.acquireContentProviderClient(Words.CONTENT_URI);
- if (null == client) return;
- new Thread("addWord") {
- @Override
- public void run() {
- Cursor cursor = null;
- try {
- cursor = client.query(Words.CONTENT_URI, PROJECTION_ADD,
- "word=? and ((locale IS NULL) or (locale=?))",
- new String[] { word, mLocale }, null);
- if (cursor != null && cursor.moveToFirst()) {
- final String locale = cursor.getString(cursor.getColumnIndex(Words.LOCALE));
- // If locale is null, we will not override the entry.
- if (locale != null && locale.equals(mLocale.toString())) {
- final long id = cursor.getLong(cursor.getColumnIndex(Words._ID));
- final Uri uri =
- Uri.withAppendedPath(Words.CONTENT_URI, Long.toString(id));
- // Update the entry with new frequency value.
- client.update(uri, values, null, null);
- }
- } else {
- // Insert new entry.
- client.insert(Words.CONTENT_URI, values);
- }
- } catch (RemoteException e) {
- // If we come here, the activity is already about to be killed, and we
- // have no means of contacting the content provider any more.
- // See ContentResolver#insert, inside the catch(){}
- } finally {
- if (null != cursor) cursor.close();
- client.release();
- }
- }
- }.start();
+ // TODO: Add an argument to the intent to specify the frequency.
+ Intent intent = new Intent(ACTION_USER_DICTIONARY_INSERT);
+ intent.putExtra(Words.WORD, word);
+ intent.putExtra(Words.LOCALE, mLocale);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ getContext().startActivity(intent);
// In case the above does a synchronous callback of the change observer
setRequiresReload(false);
@@ -242,6 +207,5 @@ public class UserDictionary extends ExpandableDictionary {
cursor.moveToNext();
}
}
- cursor.close();
}
}
diff --git a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java
index e41230b3c..a7f57ae46 100644
--- a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java
@@ -149,7 +149,7 @@ public class UserUnigramDictionary extends ExpandableDictionary {
final int length = word.length();
// Don't add very short or very long words.
if (length < 2 || length > getMaxWordLength()) return;
- if (mIme.getCurrentWord().isAutoCapitalized()) {
+ if (mIme.isAutoCapitalized()) {
// Remove caps before adding
word = Character.toLowerCase(word.charAt(0)) + word.substring(1);
}
@@ -172,7 +172,7 @@ public class UserUnigramDictionary extends ExpandableDictionary {
// Nothing pending? Return
if (mPendingWrites.isEmpty()) return;
// Create a background thread to write the pending entries
- new UpdateDbTask(getContext(), sOpenHelper, mPendingWrites, mLocale).execute();
+ new UpdateDbTask(sOpenHelper, mPendingWrites, mLocale).execute();
// Create a new map for writing new entries into while the old one is written to db
mPendingWrites = new HashMap<String, Integer>();
}
@@ -206,7 +206,7 @@ public class UserUnigramDictionary extends ExpandableDictionary {
}
}
- private Cursor query(String selection, String[] selectionArgs) {
+ private static Cursor query(String selection, String[] selectionArgs) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(USER_UNIGRAM_DICT_TABLE_NAME);
qb.setProjectionMap(sDictProjectionMap);
@@ -227,8 +227,8 @@ public class UserUnigramDictionary extends ExpandableDictionary {
private final DatabaseHelper mDbHelper;
private final String mLocale;
- public UpdateDbTask(@SuppressWarnings("unused") Context context, DatabaseHelper openHelper,
- HashMap<String, Integer> pendingWrites, String locale) {
+ public UpdateDbTask(DatabaseHelper openHelper, HashMap<String, Integer> pendingWrites,
+ String locale) {
mMap = pendingWrites;
mLocale = locale;
mDbHelper = openHelper;
@@ -251,7 +251,7 @@ public class UserUnigramDictionary extends ExpandableDictionary {
return null;
}
- private ContentValues getContentValues(String word, int frequency, String locale) {
+ private static ContentValues getContentValues(String word, int frequency, String locale) {
ContentValues values = new ContentValues(4);
values.put(COLUMN_WORD, word);
values.put(COLUMN_FREQUENCY, frequency);
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index b29ff1975..3975dddeb 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -17,11 +17,13 @@
package com.android.inputmethod.latin;
import android.content.Context;
-import android.content.SharedPreferences;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
+import android.net.Uri;
import android.os.AsyncTask;
-import android.os.Build;
+import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@@ -37,14 +39,17 @@ import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.latin.define.JniLibName;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@@ -113,8 +118,9 @@ public class Utils {
}
public static boolean hasMultipleEnabledIMEsOrSubtypes(
- final InputMethodManagerCompatWrapper imm,
final boolean shouldIncludeAuxiliarySubtypes) {
+ final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
+ if (imm == null) return false;
final List<InputMethodInfoCompatWrapper> enabledImis = imm.getEnabledInputMethodList();
// Number of the filtered IMEs
@@ -148,10 +154,21 @@ public class Utils {
}
}
- return filteredImisCount > 1
- // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
- // input method subtype (The current IME should be LatinIME.)
- || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
+ if (filteredImisCount > 1) {
+ return true;
+ }
+ final List<InputMethodSubtypeCompatWrapper> subtypes =
+ imm.getEnabledInputMethodSubtypeList(null, true);
+ int keyboardCount = 0;
+ // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's
+ // both explicitly and implicitly enabled input method subtype.
+ // (The current IME should be LatinIME.)
+ for (InputMethodSubtypeCompatWrapper subtype : subtypes) {
+ if (SubtypeSwitcher.KEYBOARD_MODE.equals(subtype.getMode())) {
+ ++keyboardCount;
+ }
+ }
+ return keyboardCount > 1;
}
public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) {
@@ -185,7 +202,8 @@ public class Utils {
final int typedWordLength = typedWord.length();
final int maxEditDistanceOfNativeDictionary =
(typedWordLength < 5 ? 2 : typedWordLength / 2) + 1;
- final int distance = Utils.editDistance(typedWord, suggestionWord);
+ final int distance = BinaryDictionary.editDistance(
+ typedWord.toString(), suggestionWord.toString());
if (DBG) {
Log.d(TAG, "Autocorrected edit distance = " + distance
+ ", " + maxEditDistanceOfNativeDictionary);
@@ -242,7 +260,7 @@ public class Utils {
UsabilityStudyLogUtils.getInstance().init(context);
return sRingCharBuffer;
}
- private int normalize(int in) {
+ private static int normalize(int in) {
int ret = in % BUFSIZE;
return ret < 0 ? ret + BUFSIZE : ret;
}
@@ -317,49 +335,6 @@ public class Utils {
}
}
-
- /* Damerau-Levenshtein distance */
- public static int editDistance(CharSequence s, CharSequence t) {
- if (s == null || t == null) {
- throw new IllegalArgumentException("editDistance: Arguments should not be null.");
- }
- final int sl = s.length();
- final int tl = t.length();
- int[][] dp = new int [sl + 1][tl + 1];
- for (int i = 0; i <= sl; i++) {
- dp[i][0] = i;
- }
- for (int j = 0; j <= tl; j++) {
- dp[0][j] = j;
- }
- for (int i = 0; i < sl; ++i) {
- for (int j = 0; j < tl; ++j) {
- final char sc = Character.toLowerCase(s.charAt(i));
- final char tc = Character.toLowerCase(t.charAt(j));
- final int cost = sc == tc ? 0 : 1;
- dp[i + 1][j + 1] = Math.min(
- dp[i][j + 1] + 1, Math.min(dp[i + 1][j] + 1, dp[i][j] + cost));
- // Overwrite for transposition cases
- if (i > 0 && j > 0
- && sc == Character.toLowerCase(t.charAt(j - 1))
- && tc == Character.toLowerCase(s.charAt(i - 1))) {
- dp[i + 1][j + 1] = Math.min(dp[i + 1][j + 1], dp[i - 1][j - 1] + cost);
- }
- }
- }
- if (DBG_EDIT_DISTANCE) {
- Log.d(TAG, "editDistance:" + s + "," + t);
- for (int i = 0; i < dp.length; ++i) {
- StringBuffer sb = new StringBuffer();
- for (int j = 0; j < dp[i].length; ++j) {
- sb.append(dp[i][j]).append(',');
- }
- Log.d(TAG, i + ":" + sb.toString());
- }
- }
- return dp[sl][tl];
- }
-
// Get the current stack trace
public static String getStackTrace() {
StringBuilder sb = new StringBuilder();
@@ -373,55 +348,6 @@ public class Utils {
return sb.toString();
}
- // In dictionary.cpp, getSuggestion() method,
- // suggestion scores are computed using the below formula.
- // original score
- // := pow(mTypedLetterMultiplier (this is defined 2),
- // (the number of matched characters between typed word and suggested word))
- // * (individual word's score which defined in the unigram dictionary,
- // and this score is defined in range [0, 255].)
- // Then, the following processing is applied.
- // - If the dictionary word is matched up to the point of the user entry
- // (full match up to min(before.length(), after.length())
- // => Then multiply by FULL_MATCHED_WORDS_PROMOTION_RATE (this is defined 1.2)
- // - If the word is a true full match except for differences in accents or
- // capitalization, then treat it as if the score was 255.
- // - If before.length() == after.length()
- // => multiply by mFullWordMultiplier (this is defined 2))
- // So, maximum original score is pow(2, min(before.length(), after.length())) * 255 * 2 * 1.2
- // For historical reasons we ignore the 1.2 modifier (because the measure for a good
- // autocorrection threshold was done at a time when it didn't exist). This doesn't change
- // the result.
- // So, we can normalize original score by dividing pow(2, min(b.l(),a.l())) * 255 * 2.
- private static final int MAX_INITIAL_SCORE = 255;
- private static final int TYPED_LETTER_MULTIPLIER = 2;
- private static final int FULL_WORD_MULTIPLIER = 2;
- private static final int S_INT_MAX = 2147483647;
- public static double calcNormalizedScore(CharSequence before, CharSequence after, int score) {
- final int beforeLength = before.length();
- final int afterLength = after.length();
- if (beforeLength == 0 || afterLength == 0) return 0;
- final int distance = editDistance(before, after);
- // If afterLength < beforeLength, the algorithm is suggesting a word by excessive character
- // correction.
- int spaceCount = 0;
- for (int i = 0; i < afterLength; ++i) {
- if (after.charAt(i) == Keyboard.CODE_SPACE) {
- ++spaceCount;
- }
- }
- if (spaceCount == afterLength) return 0;
- final double maximumScore = score == S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE
- * Math.pow(
- TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength - spaceCount))
- * FULL_WORD_MULTIPLIER;
- // add a weight based on edit distance.
- // distance <= max(afterLength, beforeLength) == afterLength,
- // so, 0 <= distance / afterLength <= 1
- final double weight = 1.0 - (double) distance / afterLength;
- return (score / maximumScore) * weight;
- }
-
public static class UsabilityStudyLogUtils {
private static final String USABILITY_TAG = UsabilityStudyLogUtils.class.getSimpleName();
private static final String FILENAME = "log.txt";
@@ -437,7 +363,7 @@ public class Utils {
private UsabilityStudyLogUtils() {
mDate = new Date();
- mDateFormat = new SimpleDateFormat("dd MMM HH:mm:ss.SSS");
+ mDateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss.SSSZ");
HandlerThread handlerThread = new HandlerThread("UsabilityStudyLogUtils logging task",
Process.THREAD_PRIORITY_BACKGROUND);
@@ -465,7 +391,7 @@ public class Utils {
}
}
- public void writeBackSpace() {
+ public static void writeBackSpace() {
UsabilityStudyLogUtils.getInstance().write("<backspace>\t0\t0");
}
@@ -504,32 +430,89 @@ public class Utils {
});
}
- public void printAll() {
+ private synchronized String getBufferedLogs() {
+ mWriter.flush();
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = getBufferedReader();
+ String line;
+ try {
+ while ((line = br.readLine()) != null) {
+ sb.append('\n');
+ sb.append(line);
+ }
+ } catch (IOException e) {
+ Log.e(USABILITY_TAG, "Can't read log file.");
+ } finally {
+ if (LatinImeLogger.sDBG) {
+ Log.d(USABILITY_TAG, "Got all buffered logs\n" + sb.toString());
+ }
+ try {
+ br.close();
+ } catch (IOException e) {
+ // ignore.
+ }
+ }
+ return sb.toString();
+ }
+
+ public void emailResearcherLogsAll() {
mLoggingHandler.post(new Runnable() {
@Override
public void run() {
+ final Date date = new Date();
+ date.setTime(System.currentTimeMillis());
+ final String currentDateTimeString =
+ new SimpleDateFormat("yyyyMMdd-HHmmssZ").format(date);
+ if (mFile == null) {
+ Log.w(USABILITY_TAG, "No internal log file found.");
+ return;
+ }
+ if (mIms.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ != PackageManager.PERMISSION_GRANTED) {
+ Log.w(USABILITY_TAG, "Doesn't have the permission WRITE_EXTERNAL_STORAGE");
+ return;
+ }
mWriter.flush();
- StringBuilder sb = new StringBuilder();
- BufferedReader br = getBufferedReader();
- String line;
+ final String destPath = Environment.getExternalStorageDirectory()
+ + "/research-" + currentDateTimeString + ".log";
+ final File destFile = new File(destPath);
try {
- while ((line = br.readLine()) != null) {
- sb.append('\n');
- sb.append(line);
- }
- } catch (IOException e) {
- Log.e(USABILITY_TAG, "Can't read log file.");
- } finally {
- if (LatinImeLogger.sDBG) {
- Log.d(USABILITY_TAG, "output all logs\n" + sb.toString());
- }
- mIms.getCurrentInputConnection().commitText(sb.toString(), 0);
- try {
- br.close();
- } catch (IOException e) {
- // ignore.
- }
+ final FileChannel src = (new FileInputStream(mFile)).getChannel();
+ final FileChannel dest = (new FileOutputStream(destFile)).getChannel();
+ src.transferTo(0, src.size(), dest);
+ src.close();
+ dest.close();
+ } catch (FileNotFoundException e1) {
+ Log.w(USABILITY_TAG, e1);
+ return;
+ } catch (IOException e2) {
+ Log.w(USABILITY_TAG, e2);
+ return;
}
+ if (destFile == null || !destFile.exists()) {
+ Log.w(USABILITY_TAG, "Dest file doesn't exist.");
+ return;
+ }
+ final Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ if (LatinImeLogger.sDBG) {
+ Log.d(USABILITY_TAG, "Destination file URI is " + destFile.toURI());
+ }
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + destPath));
+ intent.putExtra(Intent.EXTRA_SUBJECT,
+ "[Research Logs] " + currentDateTimeString);
+ mIms.startActivity(intent);
+ }
+ });
+ }
+
+ public void printAll() {
+ mLoggingHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mIms.getCurrentInputConnection().commitText(getBufferedLogs(), 0);
}
});
}
@@ -630,9 +613,13 @@ public class Utils {
public static void loadNativeLibrary() {
try {
- System.loadLibrary("jni_latinime");
+ System.loadLibrary(JniLibName.JNI_LIB_NAME);
} catch (UnsatisfiedLinkError ule) {
- Log.e(TAG, "Could not load native library jni_latinime");
+ Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME);
+ if (LatinImeLogger.sDBG) {
+ throw new RuntimeException(
+ "Could not load native library " + JniLibName.JNI_LIB_NAME);
+ }
}
}
@@ -778,40 +765,37 @@ public class Utils {
return s.toUpperCase(locale).charAt(0) + s.substring(1);
}
- public static int getCurrentVibrationDuration(SharedPreferences sp, Resources res) {
- final int ms = sp.getInt(Settings.PREF_KEYPRESS_VIBRATION_DURATION_SETTINGS, -1);
- if (ms >= 0) {
- return ms;
- }
- final String[] durationPerHardwareList = res.getStringArray(
- R.array.keypress_vibration_durations);
- final String hardwarePrefix = Build.HARDWARE + ",";
- for (final String element : durationPerHardwareList) {
- if (element.startsWith(hardwarePrefix)) {
- return (int)Long.parseLong(element.substring(element.lastIndexOf(',') + 1));
- }
- }
- return -1;
+ public static boolean willAutoCorrect(SuggestedWords suggestions) {
+ return !suggestions.mTypedWordValid && suggestions.mHasAutoCorrectionCandidate
+ && !suggestions.shouldBlockAutoCorrection();
}
- public static float getCurrentKeypressSoundVolume(SharedPreferences sp, Resources res) {
- final float volume = sp.getFloat(Settings.PREF_KEYPRESS_SOUND_VOLUME, -1.0f);
- if (volume >= 0) {
- return volume;
+ public static class Stats {
+ public static void onNonSeparator(final char code, final int x,
+ final int y) {
+ RingCharBuffer.getInstance().push(code, x, y);
+ LatinImeLogger.logOnInputChar();
}
- final String[] volumePerHardwareList = res.getStringArray(R.array.keypress_volumes);
- final String hardwarePrefix = Build.HARDWARE + ",";
- for (final String element : volumePerHardwareList) {
- if (element.startsWith(hardwarePrefix)) {
- return Float.parseFloat(element.substring(element.lastIndexOf(',') + 1));
- }
+ public static void onSeparator(final char code, final int x,
+ final int y) {
+ RingCharBuffer.getInstance().push(code, x, y);
+ LatinImeLogger.logOnInputSeparator();
+ }
+
+ public static void onAutoCorrection(final String typedWord, final String correctedWord,
+ final int separatorCode) {
+ if (TextUtils.isEmpty(typedWord)) return;
+ LatinImeLogger.logOnAutoCorrection(typedWord, correctedWord, separatorCode);
+ }
+
+ public static void onAutoCorrectionCancellation() {
+ LatinImeLogger.logOnAutoCorrectionCancelled();
}
- return -1.0f;
}
- public static boolean willAutoCorrect(SuggestedWords suggestions) {
- return !suggestions.mTypedWordValid && suggestions.mHasAutoCorrectionCandidate
- && !suggestions.shouldBlockAutoCorrection();
+ public static int codePointCount(String text) {
+ if (TextUtils.isEmpty(text)) return 0;
+ return text.codePointCount(0, text.length());
}
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index adc5637f6..a1a329a8d 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2008 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
@@ -16,9 +16,12 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.Keyboard;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* A place to store the currently composing word with information such as adjacent key codes as well
@@ -28,31 +31,31 @@ public class WordComposer {
public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE;
public static final int NOT_A_COORDINATE = -1;
- /**
- * The list of unicode values for each keystroke (including surrounding keys)
- */
- private ArrayList<int[]> mCodes;
+ final static int N = BinaryDictionary.MAX_WORD_LENGTH;
+ private ArrayList<int[]> mCodes;
private int[] mXCoordinates;
private int[] mYCoordinates;
-
private StringBuilder mTypedWord;
+ private CharSequence mAutoCorrection;
+ // Cache these values for performance
private int mCapsCount;
-
private boolean mAutoCapitalized;
-
+ private int mTrailingSingleQuotesCount;
+
/**
* Whether the user chose to capitalize the first char of the word.
*/
private boolean mIsFirstCharCapitalized;
public WordComposer() {
- final int N = BinaryDictionary.MAX_WORD_LENGTH;
mCodes = new ArrayList<int[]>(N);
mTypedWord = new StringBuilder(N);
mXCoordinates = new int[N];
mYCoordinates = new int[N];
+ mAutoCorrection = null;
+ mTrailingSingleQuotesCount = 0;
}
public WordComposer(WordComposer source) {
@@ -62,11 +65,12 @@ public class WordComposer {
public void init(WordComposer source) {
mCodes = new ArrayList<int[]>(source.mCodes);
mTypedWord = new StringBuilder(source.mTypedWord);
- mXCoordinates = source.mXCoordinates;
- mYCoordinates = source.mYCoordinates;
+ mXCoordinates = Arrays.copyOf(source.mXCoordinates, source.mXCoordinates.length);
+ mYCoordinates = Arrays.copyOf(source.mYCoordinates, source.mYCoordinates.length);
mCapsCount = source.mCapsCount;
mIsFirstCharCapitalized = source.mIsFirstCharCapitalized;
mAutoCapitalized = source.mAutoCapitalized;
+ mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount;
}
/**
@@ -75,8 +79,10 @@ public class WordComposer {
public void reset() {
mCodes.clear();
mTypedWord.setLength(0);
+ mAutoCorrection = null;
mCapsCount = 0;
mIsFirstCharCapitalized = false;
+ mTrailingSingleQuotesCount = 0;
}
/**
@@ -84,7 +90,11 @@ public class WordComposer {
* @return the number of keystrokes
*/
public final int size() {
- return mTypedWord.length();
+ return mCodes.size();
+ }
+
+ public final boolean isComposingWord() {
+ return mCodes.size() > 0;
}
/**
@@ -115,8 +125,8 @@ public class WordComposer {
* @param codes the array of unicode values
*/
public void add(int primaryCode, int[] codes, int x, int y) {
- final int newIndex = size();
- mTypedWord.append((char) primaryCode);
+ final int newIndex = mCodes.size();
+ mTypedWord.appendCodePoint(primaryCode);
correctPrimaryJuxtapos(primaryCode, codes);
mCodes.add(codes);
if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) {
@@ -126,6 +136,56 @@ public class WordComposer {
mIsFirstCharCapitalized = isFirstCharCapitalized(
newIndex, primaryCode, mIsFirstCharCapitalized);
if (Character.isUpperCase(primaryCode)) mCapsCount++;
+ if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) {
+ ++mTrailingSingleQuotesCount;
+ } else {
+ mTrailingSingleQuotesCount = 0;
+ }
+ mAutoCorrection = null;
+ }
+
+ /**
+ * Internal method to retrieve reasonable proximity info for a character.
+ */
+ private void addKeyInfo(final int codePoint, final Keyboard keyboard,
+ final KeyDetector keyDetector) {
+ for (final Key key : keyboard.mKeys) {
+ if (key.mCode == codePoint) {
+ final int x = key.mX + key.mWidth / 2;
+ final int y = key.mY + key.mHeight / 2;
+ final int[] codes = keyDetector.newCodeArray();
+ keyDetector.getKeyAndNearbyCodes(x, y, codes);
+ add(codePoint, codes, x, y);
+ return;
+ }
+ }
+ add(codePoint, new int[] { codePoint },
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
+ }
+
+ /**
+ * Set the currently composing word to the one passed as an argument.
+ * This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity.
+ */
+ public void setComposingWord(final CharSequence word, final Keyboard keyboard,
+ final KeyDetector keyDetector) {
+ reset();
+ final int length = word.length();
+ for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) {
+ int codePoint = Character.codePointAt(word, i);
+ addKeyInfo(codePoint, keyboard, keyDetector);
+ }
+ }
+
+ /**
+ * Shortcut for the above method, this will create a new KeyDetector for the passed keyboard.
+ */
+ public void setComposingWord(final CharSequence word, final Keyboard keyboard) {
+ final KeyDetector keyDetector = new KeyDetector(0);
+ keyDetector.setKeyboard(keyboard, 0, 0);
+ keyDetector.setProximityCorrectionEnabled(true);
+ keyDetector.setProximityThreshold(keyboard.mMostCommonKeyWidth);
+ setComposingWord(word, keyboard, keyDetector);
}
/**
@@ -135,7 +195,7 @@ public class WordComposer {
* @param primaryCode the preferred character
* @param codes array of codes based on distance from touch point
*/
- private void correctPrimaryJuxtapos(int primaryCode, int[] codes) {
+ private static void correctPrimaryJuxtapos(int primaryCode, int[] codes) {
if (codes.length < 2) return;
if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) {
codes[1] = codes[0];
@@ -147,27 +207,45 @@ public class WordComposer {
* Delete the last keystroke as a result of hitting backspace.
*/
public void deleteLast() {
- final int size = size();
+ final int size = mCodes.size();
if (size > 0) {
- final int lastPos = size - 1;
- char lastChar = mTypedWord.charAt(lastPos);
- mCodes.remove(lastPos);
- mTypedWord.deleteCharAt(lastPos);
+ mCodes.remove(size - 1);
+ // Note: mTypedWord.length() and mCodes.length differ when there are surrogate pairs
+ final int stringBuilderLength = mTypedWord.length();
+ if (stringBuilderLength < size) {
+ throw new RuntimeException(
+ "In WordComposer: mCodes and mTypedWords have non-matching lengths");
+ }
+ final int lastChar = mTypedWord.codePointBefore(stringBuilderLength);
+ if (Character.isSupplementaryCodePoint(lastChar)) {
+ mTypedWord.delete(stringBuilderLength - 2, stringBuilderLength);
+ } else {
+ mTypedWord.deleteCharAt(stringBuilderLength - 1);
+ }
if (Character.isUpperCase(lastChar)) mCapsCount--;
}
- if (size() == 0) {
+ // We may have deleted the last one.
+ if (0 == mCodes.size()) {
mIsFirstCharCapitalized = false;
}
+ if (mTrailingSingleQuotesCount > 0) {
+ --mTrailingSingleQuotesCount;
+ } else {
+ int i = mTypedWord.length();
+ while (i > 0) {
+ i = mTypedWord.offsetByCodePoints(i, -1);
+ if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break;
+ ++mTrailingSingleQuotesCount;
+ }
+ }
+ mAutoCorrection = null;
}
/**
* Returns the word as it was typed, without any correction applied.
- * @return the word that was typed so far
+ * @return the word that was typed so far. Never returns null.
*/
public String getTypedWord() {
- if (size() == 0) {
- return null;
- }
return mTypedWord.toString();
}
@@ -179,6 +257,10 @@ public class WordComposer {
return mIsFirstCharCapitalized;
}
+ public int trailingSingleQuotesCount() {
+ return mTrailingSingleQuotesCount;
+ }
+
/**
* Whether or not all of the user typed chars are upper case
* @return true if all user typed chars are upper case, false otherwise
@@ -194,7 +276,7 @@ public class WordComposer {
return mCapsCount > 1;
}
- /**
+ /**
* Saves the reason why the word is capitalized - whether it was automatic or
* due to the user hitting shift in the middle of a sentence.
* @param auto whether it was an automatic capitalization due to start of sentence
@@ -210,4 +292,56 @@ public class WordComposer {
public boolean isAutoCapitalized() {
return mAutoCapitalized;
}
+
+ /**
+ * Sets the auto-correction for this word.
+ */
+ public void setAutoCorrection(final CharSequence correction) {
+ mAutoCorrection = correction;
+ }
+
+ /**
+ * @return the auto-correction for this word, or null if none.
+ */
+ public CharSequence getAutoCorrectionOrNull() {
+ return mAutoCorrection;
+ }
+
+ // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
+ public LastComposedWord commitWord(final int type) {
+ // Note: currently, we come here whenever we commit a word. If it's any *other* kind than
+ // DECIDED_WORD, we should reset mAutoCorrection so that we don't attempt to cancel later.
+ // If it's a DECIDED_WORD, it may be an actual auto-correction by the IME, or what the user
+ // typed because the IME decided *not* to auto-correct for whatever reason.
+ // Ideally we would also null it when it was a DECIDED_WORD that was not an auto-correct.
+ // As it happens these two cases should behave differently, because the former can be
+ // canceled while the latter can't. Currently, we figure this out in
+ // LastComposedWord#didAutoCorrectToAnotherWord with #equals(). It would be marginally
+ // cleaner to do it here, but it would be slower (since we would #equals() for each commit,
+ // instead of only on cancel), and ultimately we want to figure it out even earlier anyway.
+ final ArrayList<int[]> codes = mCodes;
+ final int[] xCoordinates = mXCoordinates;
+ final int[] yCoordinates = mYCoordinates;
+ mCodes = new ArrayList<int[]>(N);
+ mXCoordinates = new int[N];
+ mYCoordinates = new int[N];
+ final LastComposedWord lastComposedWord = new LastComposedWord(codes,
+ xCoordinates, yCoordinates, mTypedWord.toString(),
+ null == mAutoCorrection ? null : mAutoCorrection.toString());
+ if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) {
+ lastComposedWord.deactivate();
+ }
+ mTypedWord.setLength(0);
+ mAutoCorrection = null;
+ return lastComposedWord;
+ }
+
+ public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) {
+ mCodes = lastComposedWord.mCodes;
+ mXCoordinates = lastComposedWord.mXCoordinates;
+ mYCoordinates = lastComposedWord.mYCoordinates;
+ mTypedWord.setLength(0);
+ mTypedWord.append(lastComposedWord.mTypedWord);
+ mAutoCorrection = lastComposedWord.mAutoCorrection;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/XmlParseUtils.java b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
new file mode 100644
index 000000000..d747a024c
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 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.latin;
+
+import android.content.res.TypedArray;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+public class XmlParseUtils {
+ @SuppressWarnings("serial")
+ public static class ParseException extends XmlPullParserException {
+ public ParseException(String msg, XmlPullParser parser) {
+ super(msg + " at line " + parser.getLineNumber()
+ + ", column " + parser.getColumnNumber());
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class IllegalStartTag extends ParseException {
+ public IllegalStartTag(XmlPullParser parser, String parent) {
+ super("Illegal start tag " + parser.getName() + " in " + parent, parser);
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class IllegalEndTag extends ParseException {
+ public IllegalEndTag(XmlPullParser parser, String parent) {
+ super("Illegal end tag " + parser.getName() + " in " + parent, parser);
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class IllegalAttribute extends ParseException {
+ public IllegalAttribute(XmlPullParser parser, String attribute) {
+ super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser);
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class NonEmptyTag extends ParseException{
+ public NonEmptyTag(String tag, XmlPullParser parser) {
+ super(tag + " must be empty tag", parser);
+ }
+ }
+
+ public static void checkEndTag(String tag, XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName()))
+ return;
+ throw new NonEmptyTag(tag, parser);
+ }
+
+ public static void checkAttributeExists(TypedArray attr, int attrId, String attrName,
+ String tag, XmlPullParser parser) throws XmlPullParserException {
+ if (attr.hasValue(attrId))
+ return;
+ throw new ParseException(
+ "No " + attrName + " attribute found in <" + tag + "/>", parser);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/define/JniLibName.java b/java/src/com/android/inputmethod/latin/define/JniLibName.java
new file mode 100644
index 000000000..3e94a3c07
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/define/JniLibName.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2011 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.latin.define;
+
+public class JniLibName {
+ public static final String JNI_LIB_NAME = "jni_latinime";
+}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 095c2c51c..8ac82ee5b 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -17,7 +17,9 @@
package com.android.inputmethod.latin.spellcheck;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Resources;
+import android.preference.PreferenceManager;
import android.service.textservice.SpellCheckerService;
import android.text.TextUtils;
import android.util.Log;
@@ -25,10 +27,10 @@ import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.ArraysCompatUtils;
+import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.Dictionary.DataType;
import com.android.inputmethod.latin.Dictionary.WordCallback;
import com.android.inputmethod.latin.DictionaryCollection;
import com.android.inputmethod.latin.DictionaryFactory;
@@ -41,21 +43,27 @@ import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.WhitelistDictionary;
import com.android.inputmethod.latin.WordComposer;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
+import java.util.HashSet;
/**
* Service for spell checking, using LatinIME's dictionaries and mechanisms.
*/
-public class AndroidSpellCheckerService extends SpellCheckerService {
+public class AndroidSpellCheckerService extends SpellCheckerService
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = AndroidSpellCheckerService.class.getSimpleName();
private static final boolean DBG = false;
private static final int POOL_SIZE = 2;
+ public static final String PREF_USE_CONTACTS_KEY = "pref_spellcheck_use_contacts";
+
private static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
private static final int CAPITALIZE_FIRST = 1; // First only
private static final int CAPITALIZE_ALL = 2; // All caps
@@ -82,15 +90,100 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
// The threshold for a candidate to be offered as a suggestion.
private double mSuggestionThreshold;
- // The threshold for a suggestion to be considered "likely".
- private double mLikelyThreshold;
+ // The threshold for a suggestion to be considered "recommended".
+ private double mRecommendedThreshold;
+ // Whether to use the contacts dictionary
+ private boolean mUseContactsDictionary;
+ private final Object mUseContactsLock = new Object();
+
+ private final HashSet<WeakReference<DictionaryCollection>> mDictionaryCollectionsList =
+ new HashSet<WeakReference<DictionaryCollection>>();
+
+ public static final int SCRIPT_LATIN = 0;
+ public static final int SCRIPT_CYRILLIC = 1;
+ private static final TreeMap<String, Integer> mLanguageToScript;
+ static {
+ // List of the supported languages and their associated script. We won't check
+ // words written in another script than the selected script, because we know we
+ // don't have those in our dictionary so we will underline everything and we
+ // will never have any suggestions, so it makes no sense checking them.
+ mLanguageToScript = new TreeMap<String, Integer>();
+ mLanguageToScript.put("en", SCRIPT_LATIN);
+ mLanguageToScript.put("fr", SCRIPT_LATIN);
+ mLanguageToScript.put("de", SCRIPT_LATIN);
+ mLanguageToScript.put("nl", SCRIPT_LATIN);
+ mLanguageToScript.put("cs", SCRIPT_LATIN);
+ mLanguageToScript.put("es", SCRIPT_LATIN);
+ mLanguageToScript.put("it", SCRIPT_LATIN);
+ mLanguageToScript.put("ru", SCRIPT_CYRILLIC);
+ }
@Override public void onCreate() {
super.onCreate();
mSuggestionThreshold =
Double.parseDouble(getString(R.string.spellchecker_suggestion_threshold_value));
- mLikelyThreshold =
- Double.parseDouble(getString(R.string.spellchecker_likely_threshold_value));
+ mRecommendedThreshold =
+ Double.parseDouble(getString(R.string.spellchecker_recommended_threshold_value));
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ onSharedPreferenceChanged(prefs, PREF_USE_CONTACTS_KEY);
+ }
+
+ private static int getScriptFromLocale(final Locale locale) {
+ final Integer script = mLanguageToScript.get(locale.getLanguage());
+ if (null == script) {
+ throw new RuntimeException("We have been called with an unsupported language: \""
+ + locale.getLanguage() + "\". Framework bug?");
+ }
+ return script;
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+ if (!PREF_USE_CONTACTS_KEY.equals(key)) return;
+ synchronized(mUseContactsLock) {
+ mUseContactsDictionary = prefs.getBoolean(PREF_USE_CONTACTS_KEY, true);
+ if (mUseContactsDictionary) {
+ startUsingContactsDictionaryLocked();
+ } else {
+ stopUsingContactsDictionaryLocked();
+ }
+ }
+ }
+
+ private void startUsingContactsDictionaryLocked() {
+ if (null == mContactsDictionary) {
+ mContactsDictionary = new SynchronouslyLoadedContactsDictionary(this);
+ }
+ final Iterator<WeakReference<DictionaryCollection>> iterator =
+ mDictionaryCollectionsList.iterator();
+ while (iterator.hasNext()) {
+ final WeakReference<DictionaryCollection> dictRef = iterator.next();
+ final DictionaryCollection dict = dictRef.get();
+ if (null == dict) {
+ iterator.remove();
+ } else {
+ dict.addDictionary(mContactsDictionary);
+ }
+ }
+ }
+
+ private void stopUsingContactsDictionaryLocked() {
+ if (null == mContactsDictionary) return;
+ final SynchronouslyLoadedContactsDictionary contactsDict = mContactsDictionary;
+ mContactsDictionary = null;
+ final Iterator<WeakReference<DictionaryCollection>> iterator =
+ mDictionaryCollectionsList.iterator();
+ while (iterator.hasNext()) {
+ final WeakReference<DictionaryCollection> dictRef = iterator.next();
+ final DictionaryCollection dict = dictRef.get();
+ if (null == dict) {
+ iterator.remove();
+ } else {
+ dict.removeDictionary(contactsDict);
+ }
+ }
+ contactsDict.close();
}
@Override
@@ -110,10 +203,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
private static class SuggestionsGatherer implements WordCallback {
public static class Result {
public final String[] mSuggestions;
- public final boolean mHasLikelySuggestions;
- public Result(final String[] gatheredSuggestions, final boolean hasLikelySuggestions) {
+ public final boolean mHasRecommendedSuggestions;
+ public Result(final String[] gatheredSuggestions,
+ final boolean hasRecommendedSuggestions) {
mSuggestions = gatheredSuggestions;
- mHasLikelySuggestions = hasLikelySuggestions;
+ mHasRecommendedSuggestions = hasRecommendedSuggestions;
}
}
@@ -121,7 +215,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
private final int[] mScores;
private final String mOriginalText;
private final double mSuggestionThreshold;
- private final double mLikelyThreshold;
+ private final double mRecommendedThreshold;
private final int mMaxLength;
private int mLength = 0;
@@ -131,10 +225,10 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
private int mBestScore = Integer.MIN_VALUE; // As small as possible
SuggestionsGatherer(final String originalText, final double suggestionThreshold,
- final double likelyThreshold, final int maxLength) {
+ final double recommendedThreshold, final int maxLength) {
mOriginalText = originalText;
mSuggestionThreshold = suggestionThreshold;
- mLikelyThreshold = likelyThreshold;
+ mRecommendedThreshold = recommendedThreshold;
mMaxLength = maxLength;
mSuggestions = new ArrayList<CharSequence>(maxLength + 1);
mScores = new int[mMaxLength];
@@ -142,7 +236,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
@Override
synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
- int dicTypeId, DataType dataType) {
+ int dicTypeId, int dataType) {
final int positionIndex = ArraysCompatUtils.binarySearch(mScores, 0, mLength, score);
// binarySearch returns the index if the element exists, and -<insertion index> - 1
// if it doesn't. See documentation for binarySearch.
@@ -175,7 +269,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
// make the threshold.
final String wordString = new String(word, wordOffset, wordLength);
final double normalizedScore =
- Utils.calcNormalizedScore(mOriginalText, wordString, score);
+ BinaryDictionary.calcNormalizedScore(mOriginalText, wordString, score);
if (normalizedScore < mSuggestionThreshold) {
if (DBG) Log.i(TAG, wordString + " does not make the score threshold");
return true;
@@ -198,19 +292,19 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
public Result getResults(final int capitalizeType, final Locale locale) {
final String[] gatheredSuggestions;
- final boolean hasLikelySuggestions;
+ final boolean hasRecommendedSuggestions;
if (0 == mLength) {
// Either we found no suggestions, or we found some BUT the max length was 0.
// If we found some mBestSuggestion will not be null. If it is null, then
// we found none, regardless of the max length.
if (null == mBestSuggestion) {
gatheredSuggestions = null;
- hasLikelySuggestions = false;
+ hasRecommendedSuggestions = false;
} else {
gatheredSuggestions = EMPTY_STRING_ARRAY;
- final double normalizedScore =
- Utils.calcNormalizedScore(mOriginalText, mBestSuggestion, mBestScore);
- hasLikelySuggestions = (normalizedScore > mLikelyThreshold);
+ final double normalizedScore = BinaryDictionary.calcNormalizedScore(
+ mOriginalText, mBestSuggestion, mBestScore);
+ hasRecommendedSuggestions = (normalizedScore > mRecommendedThreshold);
}
} else {
if (DBG) {
@@ -243,16 +337,17 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
final int bestScore = mScores[mLength - 1];
final CharSequence bestSuggestion = mSuggestions.get(0);
final double normalizedScore =
- Utils.calcNormalizedScore(mOriginalText, bestSuggestion, bestScore);
- hasLikelySuggestions = (normalizedScore > mLikelyThreshold);
+ BinaryDictionary.calcNormalizedScore(
+ mOriginalText, bestSuggestion.toString(), bestScore);
+ hasRecommendedSuggestions = (normalizedScore > mRecommendedThreshold);
if (DBG) {
Log.i(TAG, "Best suggestion : " + bestSuggestion + ", score " + bestScore);
Log.i(TAG, "Normalized score = " + normalizedScore
- + " (threshold " + mLikelyThreshold
- + ") => hasLikelySuggestions = " + hasLikelySuggestions);
+ + " (threshold " + mRecommendedThreshold
+ + ") => hasRecommendedSuggestions = " + hasRecommendedSuggestions);
}
}
- return new Result(gatheredSuggestions, hasLikelySuggestions);
+ return new Result(gatheredSuggestions, hasRecommendedSuggestions);
}
}
@@ -273,13 +368,15 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
for (Dictionary dict : oldWhitelistDictionaries.values()) {
dict.close();
}
- if (null != mContactsDictionary) {
- // The synchronously loaded contacts dictionary should have been in one
- // or several pools, but it is shielded against multiple closing and it's
- // safe to call it several times.
- final SynchronouslyLoadedContactsDictionary dictToClose = mContactsDictionary;
- mContactsDictionary = null;
- dictToClose.close();
+ synchronized(mUseContactsLock) {
+ if (null != mContactsDictionary) {
+ // The synchronously loaded contacts dictionary should have been in one
+ // or several pools, but it is shielded against multiple closing and it's
+ // safe to call it several times.
+ final SynchronouslyLoadedContactsDictionary dictToClose = mContactsDictionary;
+ mContactsDictionary = null;
+ dictToClose.close();
+ }
}
return false;
}
@@ -295,7 +392,9 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
}
public DictAndProximity createDictAndProximity(final Locale locale) {
- final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo();
+ final int script = getScriptFromLocale(locale);
+ final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo(
+ SpellCheckerProximityInfo.getProximityForScript(script));
final Resources resources = getResources();
final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
final DictionaryCollection dictionaryCollection =
@@ -314,11 +413,16 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
mWhitelistDictionaries.put(localeStr, whitelistDictionary);
}
dictionaryCollection.addDictionary(whitelistDictionary);
- if (null == mContactsDictionary) {
- mContactsDictionary = new SynchronouslyLoadedContactsDictionary(this);
+ synchronized(mUseContactsLock) {
+ if (mUseContactsDictionary) {
+ if (null == mContactsDictionary) {
+ mContactsDictionary = new SynchronouslyLoadedContactsDictionary(this);
+ }
+ }
+ dictionaryCollection.addDictionary(mContactsDictionary);
+ mDictionaryCollectionsList.add(
+ new WeakReference<DictionaryCollection>(dictionaryCollection));
}
- // TODO: add a setting to use or not contacts when checking spelling
- dictionaryCollection.addDictionary(mContactsDictionary);
return new DictAndProximity(dictionaryCollection, proximityInfo);
}
@@ -327,9 +431,9 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
// If the first char is not uppercase, then the word is either all lower case,
// and in either case we return CAPITALIZE_NONE.
if (!Character.isUpperCase(text.codePointAt(0))) return CAPITALIZE_NONE;
- final int len = text.codePointCount(0, text.length());
+ final int len = text.length();
int capsCount = 1;
- for (int i = 1; i < len; ++i) {
+ for (int i = 1; i < len; i = text.offsetByCodePoints(i, 1)) {
if (1 != capsCount && i != capsCount) break;
if (Character.isUpperCase(text.codePointAt(i))) ++capsCount;
}
@@ -346,6 +450,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
private DictionaryPool mDictionaryPool;
// Likewise
private Locale mLocale;
+ // Cache this for performance
+ private int mScript; // One of SCRIPT_LATIN or SCRIPT_CYRILLIC for now.
private final AndroidSpellCheckerService mService;
@@ -358,17 +464,51 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
final String localeString = getLocale();
mDictionaryPool = mService.getDictionaryPool(localeString);
mLocale = LocaleUtils.constructLocaleFromString(localeString);
+ mScript = getScriptFromLocale(mLocale);
+ }
+
+ /*
+ * Returns whether the code point is a letter that makes sense for the specified
+ * locale for this spell checker.
+ * The dictionaries supported by Latin IME are described in res/xml/spellchecker.xml
+ * and is limited to EFIGS languages and Russian.
+ * Hence at the moment this explicitly tests for Cyrillic characters or Latin characters
+ * as appropriate, and explicitly excludes CJK, Arabic and Hebrew characters.
+ */
+ private static boolean isLetterCheckableByLanguage(final int codePoint,
+ final int script) {
+ switch (script) {
+ case SCRIPT_LATIN:
+ // Our supported latin script dictionaries (EFIGS) at the moment only include
+ // characters in the C0, C1, Latin Extended A and B, IPA extensions unicode
+ // blocks. As it happens, those are back-to-back in the code range 0x40 to 0x2AF,
+ // so the below is a very efficient way to test for it. As for the 0-0x3F, it's
+ // excluded from isLetter anyway.
+ return codePoint <= 0x2AF && Character.isLetter(codePoint);
+ case SCRIPT_CYRILLIC:
+ // All Cyrillic characters are in the 400~52F block. There are some in the upper
+ // Unicode range, but they are archaic characters that are not used in modern
+ // russian and are not used by our dictionary.
+ return codePoint >= 0x400 && codePoint <= 0x52F && Character.isLetter(codePoint);
+ default:
+ // Should never come here
+ throw new RuntimeException("Impossible value of script: " + script);
+ }
}
/**
* Finds out whether a particular string should be filtered out of spell checking.
*
- * This will loosely match URLs, numbers, symbols.
+ * This will loosely match URLs, numbers, symbols. To avoid always underlining words that
+ * we know we will never recognize, this accepts a script identifier that should be one
+ * of the SCRIPT_* constants defined above, to rule out quickly characters from very
+ * different languages.
*
* @param text the string to evaluate.
+ * @param script the identifier for the script this spell checker recognizes
* @return true if we should filter this text out, false otherwise
*/
- private boolean shouldFilterOut(final String text) {
+ private static boolean shouldFilterOut(final String text, final int script) {
if (TextUtils.isEmpty(text) || text.length() <= 1) return true;
// TODO: check if an equivalent processing can't be done more quickly with a
@@ -376,20 +516,19 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
// Filter by first letter
final int firstCodePoint = text.codePointAt(0);
// Filter out words that don't start with a letter or an apostrophe
- if (!Character.isLetter(firstCodePoint)
+ if (!isLetterCheckableByLanguage(firstCodePoint, script)
&& '\'' != firstCodePoint) return true;
// Filter contents
final int length = text.length();
int letterCount = 0;
- for (int i = 0; i < length; ++i) {
+ for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
final int codePoint = text.codePointAt(i);
// Any word containing a '@' is probably an e-mail address
// Any word containing a '/' is probably either an ad-hoc combination of two
// words or a URI - in either case we don't want to spell check that
- if ('@' == codePoint
- || '/' == codePoint) return true;
- if (Character.isLetter(codePoint)) ++letterCount;
+ if ('@' == codePoint || '/' == codePoint) return true;
+ if (isLetterCheckableByLanguage(codePoint, script)) ++letterCount;
}
// Guestimate heuristic: perform spell checking if at least 3/4 of the characters
// in this word are letters
@@ -408,7 +547,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
try {
final String text = textInfo.getText();
- if (shouldFilterOut(text)) {
+ if (shouldFilterOut(text, mScript)) {
DictAndProximity dictInfo = null;
try {
dictInfo = mDictionaryPool.takeOrGetNull();
@@ -426,17 +565,23 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
// TODO: Don't gather suggestions if the limit is <= 0 unless necessary
final SuggestionsGatherer suggestionsGatherer = new SuggestionsGatherer(text,
- mService.mSuggestionThreshold, mService.mLikelyThreshold, suggestionsLimit);
+ mService.mSuggestionThreshold, mService.mRecommendedThreshold,
+ suggestionsLimit);
final WordComposer composer = new WordComposer();
final int length = text.length();
- for (int i = 0; i < length; ++i) {
+ for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
final int character = text.codePointAt(i);
- final int proximityIndex = SpellCheckerProximityInfo.getIndexOf(character);
+ final int proximityIndex =
+ SpellCheckerProximityInfo.getIndexOfCodeForScript(character, mScript);
final int[] proximities;
if (-1 == proximityIndex) {
proximities = new int[] { character };
} else {
- proximities = Arrays.copyOfRange(SpellCheckerProximityInfo.PROXIMITY,
+ // TODO: an initial examination seems to reveal this is actually used
+ // read-only. It should be possible to compute the arrays statically once
+ // and skip doing a copy each time here.
+ proximities = Arrays.copyOfRange(
+ SpellCheckerProximityInfo.getProximityForScript(mScript),
proximityIndex,
proximityIndex + SpellCheckerProximityInfo.ROW_SIZE);
}
@@ -475,7 +620,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
+ suggestionsLimit);
Log.i(TAG, "IsInDict = " + isInDict);
Log.i(TAG, "LooksLikeTypo = " + (!isInDict));
- Log.i(TAG, "HasLikelySuggestions = " + result.mHasLikelySuggestions);
+ Log.i(TAG, "HasRecommendedSuggestions = " + result.mHasRecommendedSuggestions);
if (null != result.mSuggestions) {
for (String suggestion : result.mSuggestions) {
Log.i(TAG, suggestion);
@@ -483,10 +628,13 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
}
}
- // TODO: actually use result.mHasLikelySuggestions
final int flags =
(isInDict ? SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
- : SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO);
+ : SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO)
+ | (result.mHasRecommendedSuggestions
+ ? SuggestionsInfoCompatUtils
+ .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS()
+ : 0);
return new SuggestionsInfo(flags, result.mSuggestions);
} catch (RuntimeException e) {
// Don't kill the keyboard if there is a bug in the spell checker
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index d5b04b27c..db3544987 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -22,72 +22,158 @@ import com.android.inputmethod.keyboard.ProximityInfo;
import java.util.TreeMap;
public class SpellCheckerProximityInfo {
- final private static int NUL = KeyDetector.NOT_A_CODE;
+ /* public for test */
+ final public static int NUL = KeyDetector.NOT_A_CODE;
// This must be the same as MAX_PROXIMITY_CHARS_SIZE else it will not work inside
// native code - this value is passed at creation of the binary object and reused
// as the size of the passed array afterwards so they can't be different.
final public static int ROW_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
- // This is a map from the code point to the index in the PROXIMITY array.
- // At the time the native code to read the binary dictionary needs the proximity info be passed
- // as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input character.
- // Since we need to build such an array, we want to be able to search in our big proximity data
- // quickly by character, and a map is probably the best way to do this.
- final private static TreeMap<Integer, Integer> INDICES = new TreeMap<Integer, Integer>();
+ // Helper methods
+ final protected static void buildProximityIndices(final int[] proximity,
+ final TreeMap<Integer, Integer> indices) {
+ for (int i = 0; i < proximity.length; i += ROW_SIZE) {
+ if (NUL != proximity[i]) indices.put(proximity[i], i);
+ }
+ }
+ final protected static int computeIndex(final int characterCode,
+ final TreeMap<Integer, Integer> indices) {
+ final Integer result = indices.get(characterCode);
+ if (null == result) return -1;
+ return result;
+ }
- // The proximity here is the union of
- // - the proximity for a QWERTY keyboard.
- // - the proximity for an AZERTY keyboard.
- // - the proximity for a QWERTZ keyboard.
- // ...plus, add all characters in the ('a', 'e', 'i', 'o', 'u') set to each other.
- //
- // The reasoning behind this construction is, almost any alphabetic text we may want
- // to spell check has been entered with one of the keyboards above. Also, specifically
- // to English, many spelling errors consist of the last vowel of the word being wrong
- // because in English vowels tend to merge with each other in pronunciation.
- final public static int[] PROXIMITY = {
- 'q', 'w', 's', 'a', 'z', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'w', 'q', 'a', 's', 'd', 'e', 'x', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'e', 'w', 's', 'd', 'f', 'r', 'a', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
- 'r', 'e', 'd', 'f', 'g', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 't', 'r', 'f', 'g', 'h', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'y', 't', 'g', 'h', 'j', 'u', 'a', 's', 'd', 'x', NUL, NUL, NUL, NUL, NUL, NUL,
- 'u', 'y', 'h', 'j', 'k', 'i', 'a', 'e', 'o', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'i', 'u', 'j', 'k', 'l', 'o', 'a', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'o', 'i', 'k', 'l', 'p', 'a', 'e', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'p', 'o', 'l', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ private static class Latin {
+ // This is a map from the code point to the index in the PROXIMITY array.
+ // At the time the native code to read the binary dictionary needs the proximity info be
+ // passed as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input
+ // character.
+ // Since we need to build such an array, we want to be able to search in our big proximity
+ // data quickly by character, and a map is probably the best way to do this.
+ final private static TreeMap<Integer, Integer> INDICES = new TreeMap<Integer, Integer>();
- 'a', 'z', 'x', 's', 'w', 'q', 'e', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
- 's', 'q', 'a', 'z', 'x', 'c', 'd', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL,
- 'f', 'e', 'd', 'c', 'v', 'b', 'g', 't', 'r', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'g', 'r', 'f', 'v', 'b', 'n', 'h', 'y', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'h', 't', 'g', 'b', 'n', 'm', 'j', 'u', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'j', 'y', 'h', 'n', 'm', 'k', 'i', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'k', 'u', 'j', 'm', 'l', 'o', 'i', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'l', 'i', 'k', 'p', 'o', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ // The proximity here is the union of
+ // - the proximity for a QWERTY keyboard.
+ // - the proximity for an AZERTY keyboard.
+ // - the proximity for a QWERTZ keyboard.
+ // ...plus, add all characters in the ('a', 'e', 'i', 'o', 'u') set to each other.
+ //
+ // The reasoning behind this construction is, almost any alphabetic text we may want
+ // to spell check has been entered with one of the keyboards above. Also, specifically
+ // to English, many spelling errors consist of the last vowel of the word being wrong
+ // because in English vowels tend to merge with each other in pronunciation.
+ final static int[] PROXIMITY = {
+ 'q', 'w', 's', 'a', 'z', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'w', 'q', 'a', 's', 'd', 'e', 'x', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'e', 'w', 's', 'd', 'f', 'r', 'a', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
+ 'r', 'e', 'd', 'f', 'g', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 't', 'r', 'f', 'g', 'h', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'y', 't', 'g', 'h', 'j', 'u', 'a', 's', 'd', 'x', NUL, NUL, NUL, NUL, NUL, NUL,
+ 'u', 'y', 'h', 'j', 'k', 'i', 'a', 'e', 'o', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'i', 'u', 'j', 'k', 'l', 'o', 'a', 'e', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'o', 'i', 'k', 'l', 'p', 'a', 'e', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'p', 'o', 'l', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'z', 'a', 's', 'd', 'x', 't', 'g', 'h', 'j', 'u', 'q', 'e', NUL, NUL, NUL, NUL,
- 'x', 'z', 'a', 's', 'd', 'c', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'c', 'x', 's', 'd', 'f', 'v', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'v', 'c', 'd', 'f', 'g', 'b', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'b', 'v', 'f', 'g', 'h', 'n', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'n', 'b', 'g', 'h', 'j', 'm', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- 'm', 'n', 'h', 'j', 'k', 'l', 'o', 'p', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
- };
- static {
- for (int i = 0; i < PROXIMITY.length; i += ROW_SIZE) {
- if (NUL != PROXIMITY[i]) INDICES.put(PROXIMITY[i], i);
+ 'a', 'z', 'x', 's', 'w', 'q', 'e', 'i', 'o', 'u', NUL, NUL, NUL, NUL, NUL, NUL,
+ 's', 'q', 'a', 'z', 'x', 'c', 'd', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'd', 'w', 's', 'x', 'c', 'v', 'f', 'r', 'e', 'w', NUL, NUL, NUL, NUL, NUL, NUL,
+ 'f', 'e', 'd', 'c', 'v', 'b', 'g', 't', 'r', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'g', 'r', 'f', 'v', 'b', 'n', 'h', 'y', 't', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'h', 't', 'g', 'b', 'n', 'm', 'j', 'u', 'y', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'j', 'y', 'h', 'n', 'm', 'k', 'i', 'u', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'k', 'u', 'j', 'm', 'l', 'o', 'i', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'l', 'i', 'k', 'p', 'o', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ 'z', 'a', 's', 'd', 'x', 't', 'g', 'h', 'j', 'u', 'q', 'e', NUL, NUL, NUL, NUL,
+ 'x', 'z', 'a', 's', 'd', 'c', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'c', 'x', 's', 'd', 'f', 'v', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'v', 'c', 'd', 'f', 'g', 'b', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'b', 'v', 'f', 'g', 'h', 'n', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'n', 'b', 'g', 'h', 'j', 'm', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'm', 'n', 'h', 'j', 'k', 'l', 'o', 'p', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ };
+ static {
+ buildProximityIndices(PROXIMITY, INDICES);
+ }
+ static int getIndexOf(int characterCode) {
+ return computeIndex(characterCode, INDICES);
}
}
- public static int getIndexOf(int characterCode) {
- final Integer result = INDICES.get(characterCode);
- if (null == result) return -1;
- return result;
+
+ private static class Cyrillic {
+ final private static TreeMap<Integer, Integer> INDICES = new TreeMap<Integer, Integer>();
+ final static int[] PROXIMITY = {
+ // TODO: This table is solely based on the keyboard layout. Consult with Russian
+ // speakers on commonly misspelled words/letters.
+ 'й', 'ц', 'ф', 'ы', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ц', 'й', 'ф', 'ы', 'в', 'у', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'у', 'ц', 'ы', 'в', 'а', 'к', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'к', 'у', 'в', 'а', 'п', 'е', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'е', 'к', 'а', 'п', 'р', 'н', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'н', 'е', 'п', 'р', 'о', 'г', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'г', 'н', 'р', 'о', 'л', 'ш', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ш', 'г', 'о', 'л', 'д', 'щ', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'щ', 'ш', 'л', 'д', 'ж', 'з', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'з', 'щ', 'д', 'ж', 'э', 'х', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'х', 'з', 'ж', 'э', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ 'ф', 'й', 'ц', 'ы', 'я', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ы', 'й', 'ц', 'у', 'ф', 'в', 'я', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'в', 'ц', 'у', 'к', 'ы', 'а', 'я', 'ч', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'а', 'у', 'к', 'е', 'в', 'п', 'ч', 'с', 'м', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'п', 'к', 'е', 'н', 'а', 'р', 'с', 'м', 'и', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'р', 'е', 'н', 'г', 'п', 'о', 'м', 'и', 'т', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'о', 'н', 'г', 'ш', 'р', 'л', 'и', 'т', 'ь', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'л', 'г', 'ш', 'щ', 'о', 'д', 'т', 'ь', 'б', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'д', 'ш', 'щ', 'з', 'л', 'ж', 'ь', 'б', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ж', 'щ', 'з', 'х', 'д', 'э', 'б', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'э', 'з', 'х', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+
+ 'я', 'ф', 'ы', 'в', 'ч', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ч', 'ы', 'в', 'а', 'я', 'с', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'с', 'в', 'а', 'п', 'ч', 'м', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'м', 'а', 'п', 'р', 'с', 'и', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'и', 'п', 'р', 'о', 'м', 'т', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'т', 'р', 'о', 'л', 'и', 'ь', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ь', 'о', 'л', 'д', 'т', 'б', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'б', 'л', 'д', 'ж', 'ь', 'ю', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ 'ю', 'д', 'ж', 'э', 'б', NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL,
+ };
+ static {
+ buildProximityIndices(PROXIMITY, INDICES);
+ }
+ static int getIndexOf(int characterCode) {
+ return computeIndex(characterCode, INDICES);
+ }
+ }
+
+ public static int[] getProximityForScript(final int script) {
+ switch (script) {
+ case AndroidSpellCheckerService.SCRIPT_LATIN:
+ return Latin.PROXIMITY;
+ case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
+ return Cyrillic.PROXIMITY;
+ default:
+ throw new RuntimeException("Wrong script supplied: " + script);
+ }
+ }
+ public static int getIndexOfCodeForScript(final int characterCode, final int script) {
+ switch (script) {
+ case AndroidSpellCheckerService.SCRIPT_LATIN:
+ return Latin.getIndexOf(characterCode);
+ case AndroidSpellCheckerService.SCRIPT_CYRILLIC:
+ return Cyrillic.getIndexOf(characterCode);
+ default:
+ throw new RuntimeException("Wrong script supplied: " + script);
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 9a59ef2e0..4ef5bd386 100644
--- a/java/src/com/android/inputmethod/latin/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.suggestions;
import android.content.res.Resources;
import android.graphics.Paint;
@@ -25,26 +25,28 @@ import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.KeyboardParams;
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
public class MoreSuggestions extends Keyboard {
- private static final boolean DBG = LatinImeLogger.sDBG;
-
public static final int SUGGESTION_CODE_BASE = 1024;
private MoreSuggestions(Builder.MoreSuggestionsParam params) {
super(params);
}
- public static class Builder extends KeyboardBuilder<Builder.MoreSuggestionsParam> {
+ public static class Builder extends Keyboard.Builder<Builder.MoreSuggestionsParam> {
+ private static final boolean DBG = LatinImeLogger.sDBG;
+
private final MoreSuggestionsView mPaneView;
private SuggestedWords mSuggestions;
private int mFromPos;
private int mToPos;
- public static class MoreSuggestionsParam extends KeyboardParams {
+ public static class MoreSuggestionsParam extends Keyboard.Params {
private final int[] mWidths = new int[SuggestionsView.MAX_SUGGESTIONS];
private final int[] mRowNumbers = new int[SuggestionsView.MAX_SUGGESTIONS];
private final int[] mColumnOrders = new int[SuggestionsView.MAX_SUGGESTIONS];
@@ -71,7 +73,7 @@ public class MoreSuggestions extends Keyboard {
int pos = fromPos, rowStartPos = fromPos;
final int size = Math.min(suggestions.size(), SuggestionsView.MAX_SUGGESTIONS);
while (pos < size) {
- final CharSequence word = suggestions.getWord(pos);
+ final String word = suggestions.getWord(pos).toString();
// TODO: Should take care of text x-scaling.
mWidths[pos] = (int)view.getDefaultLabelWidth(word, paint) + padding;
final int numColumn = pos - rowStartPos + 1;
@@ -176,9 +178,9 @@ public class MoreSuggestions extends Keyboard {
public Builder layout(SuggestedWords suggestions, int fromPos, int maxWidth,
int minWidth, int maxRow) {
- final Keyboard keyboard = KeyboardSwitcher.getInstance().getLatinKeyboard();
+ final Keyboard keyboard = KeyboardSwitcher.getInstance().getKeyboard();
final int xmlId = R.xml.kbd_suggestions_pane_template;
- load(keyboard.mId.cloneWithNewXml(mResources.getResourceEntryName(xmlId), xmlId));
+ load(xmlId, keyboard.mId);
mParams.mVerticalGap = mParams.mTopPadding = keyboard.mVerticalGap / 2;
final int count = mParams.layout(suggestions, fromPos, maxWidth, minWidth, maxRow,
@@ -198,6 +200,21 @@ public class MoreSuggestions extends Keyboard {
return info;
}
+ private static class Divider extends Key.Spacer {
+ private final Drawable mIcon;
+
+ public Divider(Keyboard.Params params, Drawable icon, int x, int y, int width,
+ int height) {
+ super(params, x, y, width, height);
+ mIcon = icon;
+ }
+
+ @Override
+ public Drawable getIcon(KeyboardIconsSet iconSet) {
+ return mIcon;
+ }
+ }
+
@Override
public MoreSuggestions build() {
final MoreSuggestionsParam params = mParams;
@@ -209,16 +226,16 @@ public class MoreSuggestions extends Keyboard {
final String info = getDebugInfo(mSuggestions, pos);
final int index = pos + SUGGESTION_CODE_BASE;
final Key key = new Key(
- params, word, info, null, index, null, x, y, width,
- params.mDefaultRowHeight);
+ params, word, info, KeyboardIconsSet.ICON_UNDEFINED, index, null, x, y,
+ width, params.mDefaultRowHeight);
params.markAsEdgeKey(key, pos);
params.onAddKey(key);
final int columnNumber = params.getColumnNumber(pos);
final int numColumnInRow = params.getNumColumnInRow(pos);
if (columnNumber < numColumnInRow - 1) {
- final Key.Spacer spacer = new Key.Spacer(params, params.mDivider, x + width, y,
+ final Divider divider = new Divider(params, params.mDivider, x + width, y,
params.mDividerWidth, params.mDefaultRowHeight);
- params.onAddKey(spacer);
+ params.onAddKey(divider);
}
}
return new MoreSuggestions(params);
diff --git a/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index c61dd6313..cd83c3e21 100644
--- a/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.suggestions;
import android.content.Context;
import android.content.res.Resources;
@@ -34,6 +34,7 @@ import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.latin.R;
/**
* A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
@@ -55,13 +56,13 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
private final KeyboardActionListener mSuggestionsPaneListener =
new KeyboardActionListener.Adapter() {
@Override
- public void onPress(int primaryCode, boolean withSliding) {
- mListener.onPress(primaryCode, withSliding);
+ public void onPressKey(int primaryCode) {
+ mListener.onPressKey(primaryCode);
}
@Override
- public void onRelease(int primaryCode, boolean withSliding) {
- mListener.onRelease(primaryCode, withSliding);
+ public void onReleaseKey(int primaryCode, boolean withSliding) {
+ mListener.onReleaseKey(primaryCode, withSliding);
}
@Override
@@ -140,11 +141,6 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
}
@Override
- public void setShifted(boolean shifted) {
- // Nothing to do with.
- }
-
- @Override
public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
PopupWindow window, KeyboardActionListener listener) {
mController = controller;
diff --git a/java/src/com/android/inputmethod/latin/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
index c25ecb382..40d782640 100644
--- a/java/src/com/android/inputmethod/latin/SuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.suggestions;
import android.content.Context;
import android.content.res.Resources;
@@ -30,7 +30,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Message;
-import android.os.SystemClock;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -58,7 +57,12 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardView;
import com.android.inputmethod.keyboard.MoreKeysPanel;
import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -73,7 +77,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
// The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
public static final int MAX_SUGGESTIONS = 18;
- private static final boolean DBG = LatinImeLogger.sDBG;
+ static final boolean DBG = LatinImeLogger.sDBG;
private final ViewGroup mSuggestionsStrip;
private KeyboardView mKeyboardView;
@@ -101,8 +105,6 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
private static class UiHandler extends StaticInnerHandlerWrapper<SuggestionsView> {
private static final int MSG_HIDE_PREVIEW = 0;
- private static final long DELAY_HIDE_PREVIEW = 1300;
-
public UiHandler(SuggestionsView outerInstance) {
super(outerInstance);
}
@@ -117,11 +119,6 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
}
}
- public void postHidePreview() {
- cancelHidePreview();
- sendMessageDelayed(obtainMessage(MSG_HIDE_PREVIEW), DELAY_HIDE_PREVIEW);
- }
-
public void cancelHidePreview() {
removeMessages(MSG_HIDE_PREVIEW);
}
@@ -149,6 +146,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
private final List<View> mDividers;
private final List<TextView> mInfos;
+ private final int mColorValidTypedWord;
private final int mColorTypedWord;
private final int mColorAutoCorrect;
private final int mColorSuggested;
@@ -172,7 +170,6 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
public final TextView mWordToSaveView;
private final TextView mHintToSaveView;
- private final CharSequence mHintToSaveText;
public SuggestionsViewParams(Context context, AttributeSet attrs, int defStyle,
List<TextView> words, List<View> dividers, List<TextView> infos) {
@@ -193,6 +190,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SuggestionsView, defStyle, R.style.SuggestionsViewStyle);
mSuggestionStripOption = a.getInt(R.styleable.SuggestionsView_suggestionStripOption, 0);
+ final float alphaValidTypedWord = getPercent(a,
+ R.styleable.SuggestionsView_alphaValidTypedWord, 100);
final float alphaTypedWord = getPercent(a,
R.styleable.SuggestionsView_alphaTypedWord, 100);
final float alphaAutoCorrect = getPercent(a,
@@ -200,6 +199,9 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final float alphaSuggested = getPercent(a,
R.styleable.SuggestionsView_alphaSuggested, 100);
mAlphaObsoleted = getPercent(a, R.styleable.SuggestionsView_alphaSuggested, 100);
+ mColorValidTypedWord = applyAlpha(
+ a.getColor(R.styleable.SuggestionsView_colorValidTypedWord, 0),
+ alphaValidTypedWord);
mColorTypedWord = applyAlpha(
a.getColor(R.styleable.SuggestionsView_colorTypedWord, 0), alphaTypedWord);
mColorAutoCorrect = applyAlpha(
@@ -228,7 +230,6 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final LayoutInflater inflater = LayoutInflater.from(context);
mWordToSaveView = (TextView)inflater.inflate(R.layout.suggestion_word, null);
mHintToSaveView = (TextView)inflater.inflate(R.layout.suggestion_word, null);
- mHintToSaveText = context.getText(R.string.hint_add_to_dictionary);
}
private static Drawable getMoreSuggestionsHint(Resources res, float textSize, int color) {
@@ -298,6 +299,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final int color;
if (index == mCenterSuggestionIndex && Utils.willAutoCorrect(suggestions)) {
color = mColorAutoCorrect;
+ } else if (index == mCenterSuggestionIndex && suggestions.mTypedWordValid) {
+ color = mColorValidTypedWord;
} else if (isSuggested) {
color = mColorSuggested;
} else {
@@ -433,7 +436,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final TextView word = mWords.get(index);
word.setEnabled(true);
- word.setTextColor(mColorTypedWord);
+ word.setTextColor(mColorAutoCorrect);
final CharSequence text = suggestions.getWord(index);
word.setText(text);
word.setTextScaleX(1.0f);
@@ -445,7 +448,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
}
public void layoutAddToDictionaryHint(CharSequence word, ViewGroup stripView,
- int stripWidth) {
+ int stripWidth, CharSequence hintText) {
final int width = stripWidth - mDividerWidth - mPadding * 2;
final TextView wordView = mWordToSaveView;
@@ -464,13 +467,98 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
final TextView hintView = mHintToSaveView;
hintView.setTextColor(mColorAutoCorrect);
final int hintWidth = width - wordWidth;
- final float hintScaleX = getTextScaleX(mHintToSaveText, hintWidth, hintView.getPaint());
- hintView.setText(mHintToSaveText);
+ final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint());
+ hintView.setText(hintText);
hintView.setTextScaleX(hintScaleX);
stripView.addView(hintView);
setLayoutWeight(
hintView, 1.0f - mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
}
+
+ private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) {
+ if (DBG && pos < suggestions.size()) {
+ final SuggestedWordInfo wordInfo = suggestions.getInfo(pos);
+ if (wordInfo != null) {
+ final CharSequence debugInfo = wordInfo.getDebugString();
+ if (!TextUtils.isEmpty(debugInfo)) {
+ return debugInfo;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static void setLayoutWeight(View v, float weight, int height) {
+ final ViewGroup.LayoutParams lp = v.getLayoutParams();
+ if (lp instanceof LinearLayout.LayoutParams) {
+ final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
+ llp.weight = weight;
+ llp.width = 0;
+ llp.height = height;
+ }
+ }
+
+ private static float getTextScaleX(CharSequence text, int maxWidth, TextPaint paint) {
+ paint.setTextScaleX(1.0f);
+ final int width = getTextWidth(text, paint);
+ if (width <= maxWidth) {
+ return 1.0f;
+ }
+ return maxWidth / (float)width;
+ }
+
+ private static CharSequence getEllipsizedText(CharSequence text, int maxWidth,
+ TextPaint paint) {
+ if (text == null) return null;
+ paint.setTextScaleX(1.0f);
+ final int width = getTextWidth(text, paint);
+ if (width <= maxWidth) {
+ return text;
+ }
+ final float scaleX = maxWidth / (float)width;
+ if (scaleX >= MIN_TEXT_XSCALE) {
+ paint.setTextScaleX(scaleX);
+ return text;
+ }
+
+ // Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To
+ // get squeezed and ellipsized text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
+ final CharSequence ellipsized = TextUtils.ellipsize(
+ text, paint, maxWidth / MIN_TEXT_XSCALE, TextUtils.TruncateAt.MIDDLE);
+ paint.setTextScaleX(MIN_TEXT_XSCALE);
+ return ellipsized;
+ }
+
+ private static int getTextWidth(CharSequence text, TextPaint paint) {
+ if (TextUtils.isEmpty(text)) return 0;
+ final Typeface savedTypeface = paint.getTypeface();
+ paint.setTypeface(getTextTypeface(text));
+ final int len = text.length();
+ final float[] widths = new float[len];
+ final int count = paint.getTextWidths(text, 0, len, widths);
+ int width = 0;
+ for (int i = 0; i < count; i++) {
+ width += Math.round(widths[i] + 0.5f);
+ }
+ paint.setTypeface(savedTypeface);
+ return width;
+ }
+
+ private static Typeface getTextTypeface(CharSequence text) {
+ if (!(text instanceof SpannableString))
+ return Typeface.DEFAULT;
+
+ final SpannableString ss = (SpannableString)text;
+ final StyleSpan[] styles = ss.getSpans(0, text.length(), StyleSpan.class);
+ if (styles.length == 0)
+ return Typeface.DEFAULT;
+
+ switch (styles[0].getStyle()) {
+ case Typeface.BOLD: return Typeface.DEFAULT_BOLD;
+ // TODO: BOLD_ITALIC, ITALIC case?
+ default: return Typeface.DEFAULT;
+ }
+ }
}
/**
@@ -557,99 +645,15 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
mParams.layout(mSuggestions, mSuggestionsStrip, this, getWidth());
}
- private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) {
- if (DBG && pos < suggestions.size()) {
- final SuggestedWordInfo wordInfo = suggestions.getInfo(pos);
- if (wordInfo != null) {
- final CharSequence debugInfo = wordInfo.getDebugString();
- if (!TextUtils.isEmpty(debugInfo)) {
- return debugInfo;
- }
- }
- }
- return null;
- }
-
- private static void setLayoutWeight(View v, float weight, int height) {
- final ViewGroup.LayoutParams lp = v.getLayoutParams();
- if (lp instanceof LinearLayout.LayoutParams) {
- final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
- llp.weight = weight;
- llp.width = 0;
- llp.height = height;
- }
- }
-
- private static float getTextScaleX(CharSequence text, int maxWidth, TextPaint paint) {
- paint.setTextScaleX(1.0f);
- final int width = getTextWidth(text, paint);
- if (width <= maxWidth) {
- return 1.0f;
- }
- return maxWidth / (float)width;
- }
-
- private static CharSequence getEllipsizedText(CharSequence text, int maxWidth,
- TextPaint paint) {
- if (text == null) return null;
- paint.setTextScaleX(1.0f);
- final int width = getTextWidth(text, paint);
- if (width <= maxWidth) {
- return text;
- }
- final float scaleX = maxWidth / (float)width;
- if (scaleX >= MIN_TEXT_XSCALE) {
- paint.setTextScaleX(scaleX);
- return text;
- }
-
- // Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To get
- // squeezed and ellipsized text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
- final CharSequence ellipsized = TextUtils.ellipsize(
- text, paint, maxWidth / MIN_TEXT_XSCALE, TextUtils.TruncateAt.MIDDLE);
- paint.setTextScaleX(MIN_TEXT_XSCALE);
- return ellipsized;
- }
-
- private static int getTextWidth(CharSequence text, TextPaint paint) {
- if (TextUtils.isEmpty(text)) return 0;
- final Typeface savedTypeface = paint.getTypeface();
- paint.setTypeface(getTextTypeface(text));
- final int len = text.length();
- final float[] widths = new float[len];
- final int count = paint.getTextWidths(text, 0, len, widths);
- int width = 0;
- for (int i = 0; i < count; i++) {
- width += Math.round(widths[i] + 0.5f);
- }
- paint.setTypeface(savedTypeface);
- return width;
- }
-
- private static Typeface getTextTypeface(CharSequence text) {
- if (!(text instanceof SpannableString))
- return Typeface.DEFAULT;
-
- final SpannableString ss = (SpannableString)text;
- final StyleSpan[] styles = ss.getSpans(0, text.length(), StyleSpan.class);
- if (styles.length == 0)
- return Typeface.DEFAULT;
-
- switch (styles[0].getStyle()) {
- case Typeface.BOLD: return Typeface.DEFAULT_BOLD;
- // TODO: BOLD_ITALIC, ITALIC case?
- default: return Typeface.DEFAULT;
- }
- }
public boolean isShowingAddToDictionaryHint() {
return mSuggestionsStrip.getChildCount() > 0
&& mSuggestionsStrip.getChildAt(0) == mParams.mWordToSaveView;
}
- public void showAddToDictionaryHint(CharSequence word) {
+ public void showAddToDictionaryHint(CharSequence word, CharSequence hintText) {
clear();
- mParams.layoutAddToDictionaryHint(word, mSuggestionsStrip, getWidth());
+ mParams.layoutAddToDictionaryHint(word, mSuggestionsStrip, getWidth(), hintText);
}
public boolean dismissAddToDictionaryHint() {
@@ -675,34 +679,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
mPreviewPopup.dismiss();
}
- private void showPreview(View view, CharSequence word) {
- if (TextUtils.isEmpty(word))
- return;
-
- final TextView previewText = mPreviewText;
- previewText.setTextColor(mParams.mColorTypedWord);
- previewText.setText(word);
- previewText.measure(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- final int[] offsetInWindow = new int[2];
- view.getLocationInWindow(offsetInWindow);
- final int posX = offsetInWindow[0];
- final int posY = offsetInWindow[1] - previewText.getMeasuredHeight();
- final PopupWindow previewPopup = mPreviewPopup;
- if (previewPopup.isShowing()) {
- previewPopup.update(posX, posY, previewPopup.getWidth(), previewPopup.getHeight());
- } else {
- previewPopup.showAtLocation(this, Gravity.NO_GRAVITY, posX, posY);
- }
- previewText.setVisibility(VISIBLE);
- mHandler.postHidePreview();
- }
-
private void addToDictionary(CharSequence word) {
- if (mListener.addWordToDictionary(word.toString())) {
- final CharSequence message = getContext().getString(R.string.added_word, word);
- showPreview(mParams.mWordToSaveView, message);
- }
+ mListener.addWordToDictionary(word.toString());
}
private final KeyboardActionListener mMoreSuggestionsListener =
@@ -832,8 +810,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
// Decided to be in the sliding input mode only when the touch point has been moved
// upward.
mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_SLIDING_MODE;
- tracker.onShowMoreKeysPanel(
- translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel);
+ tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel);
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
// Decided to be in the modal input mode
mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_MODAL_MODE;