aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.mk1
-rw-r--r--java/AndroidManifest.xml8
-rw-r--r--java/proguard.flags12
-rw-r--r--java/res/anim/mini_keyboard_fadein.xml2
-rw-r--r--java/res/anim/mini_keyboard_fadeout.xml2
-rw-r--r--java/res/drawable-hdpi/btn_center_default.9.pngbin182 -> 168 bytes
-rw-r--r--java/res/drawable-hdpi/btn_center_pressed.9.pngbin200 -> 194 bytes
-rw-r--r--java/res/drawable-hdpi/btn_center_selected.9.pngbin200 -> 194 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.pngbin472 -> 506 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.pngbin442 -> 435 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.pngbin649 -> 657 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin817 -> 514 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.pngbin944 -> 1048 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin1027 -> 585 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.pngbin663 -> 972 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin763 -> 556 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.pngbin869 -> 1082 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin1223 -> 639 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.pngbin1119 -> 1440 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin1343 -> 720 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.pngbin1649 -> 1785 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin1696 -> 1701 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.pngbin448 -> 505 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.pngbin515 -> 468 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.pngbin453 -> 301 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.pngbin649 -> 835 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.pngbin725 -> 544 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal.9.pngbin715 -> 1134 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.pngbin1001 -> 1243 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.pngbin2389 -> 2389 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.pngbin1077 -> 1307 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.pngbin2408 -> 2409 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.pngbin2213 -> 2213 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_popup_background_holo.9.pngbin0 -> 866 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.pngbin242 -> 384 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed.9.pngbin745 -> 1088 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.pngbin1042 -> 1233 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.pngbin1105 -> 1271 bytes
-rw-r--r--java/res/drawable-hdpi/candidate_feedback_background.9.pngbin833 -> 1607 bytes
-rw-r--r--java/res/drawable-hdpi/caution.pngbin1641 -> 2451 bytes
-rw-r--r--java/res/drawable-hdpi/hint_popup.9.pngbin226 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/hint_popup_holo.9.pngbin333 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_dialog_keyboard.pngbin807 -> 1157 bytes
-rw-r--r--java/res/drawable-hdpi/ic_mic_dialog.pngbin3634 -> 4083 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_keyboard.pngbin1068 -> 812 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_mic.pngbin681 -> 892 bytes
-rw-r--r--java/res/drawable-hdpi/ic_suggest_strip_microphone.pngbin548 -> 970 bytes
-rw-r--r--java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.pngbin438 -> 795 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_at_holo.9.pngbin973 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_at_large_holo.9.pngbin1013 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_colon_holo.9.pngbin515 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_colon_large_holo.9.pngbin503 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_comma_holo.9.pngbin371 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_comma_large_holo.9.pngbin394 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_exclamation_holo.9.pngbin518 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_exclamation_large_holo.9.pngbin540 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num0.9.pngbin379 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num1.9.pngbin301 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num2.9.pngbin404 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num3.9.pngbin413 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num4.9.pngbin341 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num5.9.pngbin388 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num6.9.pngbin413 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num7.9.pngbin367 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num8.9.pngbin417 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_num9.9.pngbin417 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_plus_holo.9.pngbin501 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_plus_large_holo.9.pngbin540 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_question_holo.9.pngbin679 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_question_large_holo.9.pngbin712 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_quote_holo.9.pngbin404 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_quote_large_holo.9.pngbin423 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_underline_holo.9.pngbin337 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/key_hint_underline_large_holo.9.pngbin350 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background.9.pngbin200 -> 207 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background_holo.9.pngbin296 -> 255 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_dark_background.9.pngbin1041 -> 210 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.pngbin136 -> 2107 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.pngbin0 -> 2022 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin0 -> 2173 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.pngbin4190 -> 2262 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.pngbin0 -> 2020 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin0 -> 2180 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background.9.pngbin1494 -> 1204 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip.9.pngbin215 -> 248 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.pngbin136 -> 167 bytes
-rw-r--r--java/res/drawable-hdpi/mic_base.pngbin2957 -> 4347 bytes
-rw-r--r--java/res/drawable-hdpi/mic_full.pngbin2935 -> 5013 bytes
-rw-r--r--java/res/drawable-hdpi/mic_slash.pngbin3766 -> 12569 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_delete_rtl.pngbin0 -> 2208 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num0.pngbin1903 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num1.pngbin792 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num2.pngbin3241 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num3.pngbin2829 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num4.pngbin2638 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num5.pngbin2532 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num6.pngbin3568 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num7.pngbin3687 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num8.pngbin2952 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num9.pngbin3887 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_numalt.pngbin2971 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_numpound.pngbin1577 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_numstar.pngbin1742 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_123_mic.pngbin2575 -> 2510 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_123_mic_holo.pngbin0 -> 2195 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete.pngbin599 -> 4003 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_holo.pngbin1311 -> 951 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_rtl.pngbin0 -> 4611 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_rtl_holo.pngbin0 -> 1111 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.pngbin3541 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_delete.pngbin681 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.pngbin1275 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.pngbin1329 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_mic.pngbin2494 -> 4637 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_numalt.pngbin3797 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_return.pngbin2018 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_search.pngbin2335 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_settings.pngbin1558 -> 4641 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_shift.pngbin677 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_space.pngbin1336 -> 3908 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_tab.pngbin1707 -> 4111 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_arrows_left.pngbin1253 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_arrows_right.pngbin1372 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic.pngbin886 -> 3893 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num0.pngbin1931 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num0_holo.pngbin2398 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num1.pngbin809 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num1_holo.pngbin1118 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num2.pngbin3214 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num2_holo.pngbin4328 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num3.pngbin2805 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num3_holo.pngbin3749 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num4.pngbin2647 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num4_holo.pngbin3670 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num5.pngbin2536 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num5_holo.pngbin3395 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num6.pngbin3573 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num6_holo.pngbin4817 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num7.pngbin3684 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num7_holo.pngbin4963 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num8.pngbin2904 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num8_holo.pngbin4035 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num9.pngbin3860 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num9_holo.pngbin5608 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numalt.pngbin2919 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numbpound_holo.pngbin2027 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numbstar_holo.pngbin1397 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numpound.pngbin1600 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numstar.pngbin1749 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return.pngbin1719 -> 4024 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return_holo.pngbin1296 -> 846 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search.pngbin1260 -> 4248 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search_holo.pngbin0 -> 1218 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings.pngbin1094 -> 4015 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings_holo.pngbin2044 -> 1312 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift.pngbin640 -> 3740 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_holo.pngbin1824 -> 843 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked.pngbin593 -> 3686 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.pngbin1405 -> 671 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space.pngbin326 -> 3331 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_holo.pngbin685 -> 480 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_led.9.pngbin3249 -> 557 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.pngbin0 -> 322 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab_holo.pngbin0 -> 873 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_holo.pngbin1559 -> 1020 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo.pngbin900 -> 880 bytes
-rw-r--r--java/res/drawable-hdpi/vs_dialog_blue.9.pngbin8275 -> 11064 bytes
-rw-r--r--java/res/drawable-hdpi/vs_dialog_red.9.pngbin8607 -> 10976 bytes
-rw-r--r--java/res/drawable-hdpi/vs_dialog_yellow.9.pngbin8151 -> 10518 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.pngbin737 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.pngbin941 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_normal_off_stone.9.pngbin2691 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.pngbin1076 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_normal_on_stone.9.pngbin2720 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_normal_stone.9.pngbin2517 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.pngbin733 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.pngbin964 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.pngbin1055 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/hint_popup_holo.9.pngbin321 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_at_holo.9.pngbin973 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_at_large_holo.9.pngbin1013 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_colon_holo.9.pngbin515 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_colon_large_holo.9.pngbin503 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_comma_holo.9.pngbin371 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_comma_large_holo.9.pngbin394 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_exclamation_holo.9.pngbin518 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_exclamation_large_holo.9.pngbin540 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_plus_holo.9.pngbin501 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_plus_large_holo.9.pngbin540 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_question_holo.9.pngbin679 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_question_large_holo.9.pngbin712 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_quote_holo.9.pngbin404 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_quote_large_holo.9.pngbin423 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_underline_holo.9.pngbin337 -> 0 bytes
-rw-r--r--java/res/drawable-land-hdpi/key_hint_underline_large_holo.9.pngbin350 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/hint_popup_holo.9.pngbin1180 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_at_holo.9.pngbin481 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_at_large_holo.9.pngbin497 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_colon_holo.9.pngbin266 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_colon_large_holo.9.pngbin285 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_comma_holo.9.pngbin246 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_comma_large_holo.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_exclamation_holo.9.pngbin305 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_exclamation_large_holo.9.pngbin312 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_plus_holo.9.pngbin277 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_plus_large_holo.9.pngbin303 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_question_holo.9.pngbin368 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_question_large_holo.9.pngbin383 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_quote_holo.9.pngbin264 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_quote_large_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_underline_holo.9.pngbin196 -> 0 bytes
-rw-r--r--java/res/drawable-land-mdpi/key_hint_underline_large_holo.9.pngbin199 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/hint_popup_holo.9.pngbin373 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_at_holo.9.pngbin1048 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_at_large_holo.9.pngbin1101 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_colon_holo.9.pngbin586 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_colon_large_holo.9.pngbin573 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_comma_holo.9.pngbin411 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_comma_large_holo.9.pngbin430 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_exclamation_holo.9.pngbin559 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_exclamation_large_holo.9.pngbin588 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_plus_holo.9.pngbin595 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_plus_large_holo.9.pngbin630 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_question_holo.9.pngbin739 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_question_large_holo.9.pngbin776 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_quote_holo.9.pngbin438 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_quote_large_holo.9.pngbin459 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_underline_holo.9.pngbin368 -> 0 bytes
-rw-r--r--java/res/drawable-land-xhdpi/key_hint_underline_large_holo.9.pngbin389 -> 0 bytes
-rw-r--r--java/res/drawable-land/btn_keyboard_key.xml38
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.pngbin377 -> 458 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.pngbin1275 -> 334 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.pngbin545 -> 588 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin1641 -> 373 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.pngbin806 -> 960 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin1865 -> 422 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.pngbin514 -> 849 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin1511 -> 392 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.pngbin687 -> 957 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin1861 -> 453 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.pngbin940 -> 1293 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin1984 -> 500 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.pngbin1068 -> 1553 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin1021 -> 1461 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.pngbin355 -> 454 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.pngbin1329 -> 332 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.pngbin389 -> 258 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.pngbin526 -> 717 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.pngbin1469 -> 369 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal.9.pngbin726 -> 991 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.pngbin860 -> 1083 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.pngbin2389 -> 2389 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.pngbin926 -> 1151 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.pngbin2408 -> 2409 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.pngbin2213 -> 2213 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_popup_background_holo.9.pngbin0 -> 581 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.pngbin1101 -> 257 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed.9.pngbin664 -> 956 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.pngbin836 -> 1078 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.pngbin886 -> 1119 bytes
-rw-r--r--java/res/drawable-mdpi/hint_popup.9.pngbin202 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/hint_popup_holo.9.pngbin1168 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_at_holo.9.pngbin481 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_at_large_holo.9.pngbin497 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_colon_holo.9.pngbin266 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_colon_large_holo.9.pngbin285 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_comma_holo.9.pngbin246 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_comma_large_holo.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_exclamation_holo.9.pngbin305 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_exclamation_large_holo.9.pngbin312 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num0.9.pngbin307 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num0_holo.9.pngbin379 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num1.9.pngbin302 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num1_holo.9.pngbin301 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num2.9.pngbin334 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num2_holo.9.pngbin404 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num3.9.pngbin327 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num3_holo.9.pngbin413 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num4.9.pngbin329 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num4_holo.9.pngbin341 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num5.9.pngbin334 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num5_holo.9.pngbin388 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num6.9.pngbin329 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num6_holo.9.pngbin413 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num7.9.pngbin334 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num7_holo.9.pngbin367 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num8.9.pngbin332 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num8_holo.9.pngbin417 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num9.9.pngbin339 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_num9_holo.9.pngbin417 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_plus_holo.9.pngbin277 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_plus_large_holo.9.pngbin303 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_question_holo.9.pngbin368 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_question_large_holo.9.pngbin383 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_quote_holo.9.pngbin264 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_quote_large_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_underline_holo.9.pngbin196 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/key_hint_underline_large_holo.9.pngbin199 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_background_holo.9.pngbin1108 -> 211 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.pngbin83 -> 1335 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.pngbin0 -> 1325 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin0 -> 1436 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.pngbin3814 -> 1431 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.pngbin0 -> 1309 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin0 -> 1412 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_suggest_strip_holo.9.pngbin1003 -> 159 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_delete_rtl.pngbin0 -> 718 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num0.pngbin1148 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num1.pngbin493 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num2.pngbin1785 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num3.pngbin1675 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num4.pngbin1530 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num5.pngbin1411 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num6.pngbin1943 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num7.pngbin2040 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num8.pngbin1618 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_num9.pngbin2167 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_numalt.pngbin1670 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_numpound.pngbin910 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_numstar.pngbin943 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_123_mic_holo.pngbin0 -> 1449 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_holo.pngbin1419 -> 673 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_rtl.pngbin0 -> 3470 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_rtl_holo.pngbin0 -> 812 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.pngbin4640 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_delete.pngbin3414 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.pngbin3126 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.pngbin3121 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_numalt.pngbin4679 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_return.pngbin3613 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_search.pngbin3793 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_feedback_shift.pngbin3320 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_arrows_left.pngbin3001 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_arrows_right.pngbin3032 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num0.pngbin1160 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num0_holo.pngbin1759 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num1.pngbin506 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num1_holo.pngbin1324 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num2.pngbin1778 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num2_holo.pngbin2397 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num3.pngbin1676 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num3_holo.pngbin2143 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num4.pngbin1540 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num4_holo.pngbin2063 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num5.pngbin1417 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num5_holo.pngbin2021 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num6.pngbin1952 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num6_holo.pngbin2502 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num7.pngbin2051 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num7_holo.pngbin2540 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num8.pngbin1605 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num8_holo.pngbin2226 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num9.pngbin2173 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_num9_holo.pngbin2699 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numalt.pngbin1673 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numbpound_holo.pngbin1548 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numbstar_holo.pngbin1414 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numpound.pngbin963 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_numstar.pngbin954 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return_holo.pngbin1391 -> 619 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search_holo.pngbin0 -> 819 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings_holo.pngbin1865 -> 878 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_holo.pngbin1683 -> 623 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.pngbin1480 -> 547 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_holo.pngbin1195 -> 402 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.pngbin0 -> 201 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab_holo.pngbin0 -> 642 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_holo.pngbin1678 -> 695 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo.pngbin1587 -> 619 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/btn_keyboard_key_popup_selected_holo.9.pngbin250 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/hint_popup_holo.9.pngbin333 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_background_holo.9.pngbin3573 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_more_background_holo.9.pngbin3691 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_holo.pngbin0 -> 951 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_rtl_holo.pngbin0 -> 1111 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_numsymbol_holo.pngbin4137 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_return_holo.pngbin0 -> 846 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_search_holo.pngbin0 -> 1448 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_settings_holo.pngbin0 -> 1312 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_holo.pngbin0 -> 1010 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_locked_holo.pngbin0 -> 807 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_smiley_holo.pngbin0 -> 796 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_space_holo.pngbin0 -> 486 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_tab_holo.pngbin1361 -> 873 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_holo.pngbin0 -> 1020 bytes
-rw-r--r--java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_off_holo.pngbin0 -> 880 bytes
-rw-r--r--java/res/drawable-sw600dp-land-hdpi/hint_popup_holo.9.pngbin333 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-land-mdpi/hint_popup_holo.9.pngbin206 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-land-xhdpi/hint_popup_holo.9.pngbin379 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin597 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin751 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin295 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin626 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin739 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_normal_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_pressed_holo.9.pngbin233 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/btn_keyboard_key_popup_selected_holo.9.pngbin151 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/hint_popup_holo.9.pngbin206 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_at_holo.9.pngbin481 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_at_large_holo.9.pngbin497 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_colon_holo.9.pngbin266 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_colon_large_holo.9.pngbin285 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_comma_holo.9.pngbin246 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_comma_large_holo.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_exclamation_holo.9.pngbin305 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_exclamation_large_holo.9.pngbin312 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_plus_holo.9.pngbin277 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_plus_large_holo.9.pngbin303 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_question_holo.9.pngbin368 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_question_large_holo.9.pngbin383 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_quote_holo.9.pngbin264 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_quote_large_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_underline_holo.9.pngbin196 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/key_hint_underline_large_holo.9.pngbin199 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/keyboard_background_holo.9.pngbin1108 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_background_holo.9.pngbin2014 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_more_background_holo.9.pngbin2100 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/keyboard_popup_panel_background_holo.9.pngbin3730 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/keyboard_suggest_strip_holo.9.pngbin1003 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_holo.pngbin1419 -> 673 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_rtl_holo.pngbin0 -> 812 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num0_holo.pngbin1759 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num1_holo.pngbin1324 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num2_holo.pngbin2397 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num3_holo.pngbin2143 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num4_holo.pngbin2063 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num5_holo.pngbin2021 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num6_holo.pngbin2502 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num7_holo.pngbin2540 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num8_holo.pngbin2226 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_num9_holo.pngbin2699 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_numbpound_holo.pngbin1548 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_numbstar_holo.pngbin1414 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_numsymbol_holo.pngbin830 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_return_holo.pngbin1391 -> 619 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_search_holo.pngbin0 -> 941 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_settings_holo.pngbin1865 -> 878 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_holo.pngbin1683 -> 678 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_locked_holo.pngbin1480 -> 610 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_smiley_holo.pngbin0 -> 563 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_space_holo.pngbin1195 -> 399 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_tab_holo.pngbin387 -> 642 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_holo.pngbin1678 -> 695 bytes
-rw-r--r--java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_off_holo.pngbin1587 -> 619 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/hint_popup_holo.9.pngbin379 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_background_holo.9.pngbin3659 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_more_background_holo.9.pngbin3774 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_holo.pngbin0 -> 1271 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_rtl_holo.pngbin0 -> 1485 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_numsymbol_holo.pngbin6242 -> 0 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_return_holo.pngbin0 -> 1141 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_search_holo.pngbin0 -> 2095 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_settings_holo.pngbin0 -> 1872 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_holo.pngbin0 -> 1336 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_locked_holo.pngbin0 -> 1073 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_smiley_holo.pngbin0 -> 1024 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_space_holo.pngbin0 -> 523 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_tab_holo.pngbin1803 -> 1186 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_holo.pngbin0 -> 1427 bytes
-rw-r--r--java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_off_holo.pngbin0 -> 1192 bytes
-rw-r--r--java/res/drawable-sw768dp-hdpi/btn_keyboard_key_popup_selected_holo.9.pngbin250 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-hdpi/hint_popup_holo.9.pngbin333 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_background_holo.9.pngbin4105 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_more_background_holo.9.pngbin4190 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-hdpi/hint_popup_holo.9.pngbin321 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/hint_popup_holo.9.pngbin1180 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_at_holo.9.pngbin1621 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_at_large_holo.9.pngbin1651 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_colon_holo.9.pngbin1279 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_colon_large_holo.9.pngbin1318 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_comma_holo.9.pngbin1216 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_comma_large_holo.9.pngbin1226 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_holo.9.pngbin1317 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_large_holo.9.pngbin1338 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_plus_holo.9.pngbin1275 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_plus_large_holo.9.pngbin1328 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_question_holo.9.pngbin1433 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_question_large_holo.9.pngbin1473 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_quote_holo.9.pngbin1238 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_quote_large_holo.9.pngbin1249 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_underline_holo.9.pngbin1140 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-mdpi/key_hint_underline_large_holo.9.pngbin1154 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-land-xhdpi/hint_popup_holo.9.pngbin373 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin597 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin751 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin295 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin626 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin739 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_normal_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_pressed_holo.9.pngbin233 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/btn_keyboard_key_popup_selected_holo.9.pngbin151 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/hint_popup_holo.9.pngbin1168 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_at_holo.9.pngbin481 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_at_large_holo.9.pngbin497 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_colon_holo.9.pngbin266 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_colon_large_holo.9.pngbin285 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_comma_holo.9.pngbin246 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_comma_large_holo.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_exclamation_holo.9.pngbin305 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_exclamation_large_holo.9.pngbin312 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_plus_holo.9.pngbin277 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_plus_large_holo.9.pngbin303 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_question_holo.9.pngbin368 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_question_large_holo.9.pngbin383 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_quote_holo.9.pngbin264 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_quote_large_holo.9.pngbin268 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_underline_holo.9.pngbin196 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/key_hint_underline_large_holo.9.pngbin199 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/keyboard_background_holo.9.pngbin1108 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_background_holo.9.pngbin3804 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_more_background_holo.9.pngbin3814 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/keyboard_popup_panel_background_holo.9.pngbin3730 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/keyboard_suggest_strip_holo.9.pngbin1003 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_delete_holo.pngbin1419 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num0_holo.pngbin1759 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num1_holo.pngbin1324 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num2_holo.pngbin2397 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num3_holo.pngbin2143 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num4_holo.pngbin2063 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num5_holo.pngbin2021 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num6_holo.pngbin2502 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num7_holo.pngbin2540 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num8_holo.pngbin2226 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_num9_holo.pngbin2699 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_numbpound_holo.pngbin1548 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_numbstar_holo.pngbin1414 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_return_holo.pngbin1391 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_settings_holo.pngbin1865 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_holo.pngbin1683 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_locked_holo.pngbin1480 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_space_holo.pngbin1195 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_tab_holo.pngbin387 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_holo.pngbin1678 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_off_holo.pngbin1587 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-xhdpi/hint_popup_holo.9.pngbin379 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_background_holo.9.pngbin4228 -> 0 bytes
-rw-r--r--java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_more_background_holo.9.pngbin4317 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_candidate_pressed.9.pngbin0 -> 1266 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_center_default.9.pngbin0 -> 178 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_center_pressed.9.pngbin0 -> 196 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_center_selected.9.pngbin0 -> 196 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.pngbin546 -> 571 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.pngbin476 -> 568 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.pngbin735 -> 727 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin867 -> 655 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.pngbin1069 -> 1110 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin1143 -> 775 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.pngbin709 -> 1007 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin821 -> 755 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.pngbin924 -> 1128 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin1323 -> 881 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.pngbin1244 -> 1486 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin1486 -> 1029 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.pngbin0 -> 1441 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin0 -> 1869 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.pngbin529 -> 548 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.pngbin589 -> 591 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.pngbin535 -> 359 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.pngbin722 -> 860 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.pngbin794 -> 669 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal.9.pngbin0 -> 1172 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.pngbin0 -> 1278 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.pngbin0 -> 2833 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.pngbin0 -> 1345 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.pngbin0 -> 2867 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.pngbin0 -> 2658 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_popup_background_holo.9.pngbin0 -> 1224 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin243 -> 366 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.pngbin0 -> 1131 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.pngbin0 -> 1273 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.pngbin0 -> 1312 bytes
-rw-r--r--java/res/drawable-xhdpi/candidate_feedback_background.9.pngbin0 -> 1676 bytes
-rw-r--r--java/res/drawable-xhdpi/caution.pngbin0 -> 3207 bytes
-rw-r--r--java/res/drawable-xhdpi/hint_popup_holo.9.pngbin379 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_dialog_keyboard.pngbin0 -> 1589 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_mic_dialog.pngbin0 -> 4755 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_subtype_keyboard.pngbin0 -> 1056 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_subtype_mic.pngbin0 -> 1099 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_suggest_strip_microphone.pngbin0 -> 1334 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_suggest_strip_microphone_swipe.pngbin0 -> 982 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_at_holo.9.pngbin1048 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_at_large_holo.9.pngbin1101 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_colon_holo.9.pngbin586 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_colon_large_holo.9.pngbin573 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_comma_holo.9.pngbin411 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_comma_large_holo.9.pngbin430 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_exclamation_holo.9.pngbin559 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_exclamation_large_holo.9.pngbin588 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_plus_holo.9.pngbin595 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_plus_large_holo.9.pngbin630 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_question_holo.9.pngbin739 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_question_large_holo.9.pngbin776 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_quote_holo.9.pngbin438 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_quote_large_holo.9.pngbin459 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_underline_holo.9.pngbin368 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/key_hint_underline_large_holo.9.pngbin389 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_background.9.pngbin0 -> 222 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_background_holo.9.pngbin0 -> 297 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_dark_background.9.pngbin0 -> 241 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.pngbin136 -> 2996 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.pngbin0 -> 2945 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin0 -> 3141 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.pngbin4317 -> 3211 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.pngbin0 -> 2892 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin0 -> 3101 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_popup_panel_background.9.pngbin0 -> 1365 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_suggest_strip.9.pngbin0 -> 289 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_suggest_strip_holo.9.pngbin0 -> 180 bytes
-rw-r--r--java/res/drawable-xhdpi/mic_base.pngbin0 -> 6497 bytes
-rw-r--r--java/res/drawable-xhdpi/mic_full.pngbin0 -> 7100 bytes
-rw-r--r--java/res/drawable-xhdpi/mic_slash.pngbin0 -> 17757 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_123_mic.pngbin0 -> 3765 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_delete.pngbin0 -> 2413 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_delete_rtl.pngbin0 -> 2656 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_mic.pngbin0 -> 2090 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_return.pngbin0 -> 2018 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_search.pngbin0 -> 2889 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_settings.pngbin0 -> 2539 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_shift.pngbin0 -> 2640 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.pngbin0 -> 2076 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_space.pngbin0 -> 1072 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_tab.pngbin0 -> 1544 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_voice_off.pngbin0 -> 1137 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_123_mic.pngbin0 -> 3682 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.pngbin0 -> 3115 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete.pngbin0 -> 4589 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_holo.pngbin0 -> 1271 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_rtl.pngbin0 -> 5522 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_rtl_holo.pngbin0 -> 1485 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_feedback_mic.pngbin0 -> 5610 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_feedback_settings.pngbin0 -> 5616 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_feedback_space.pngbin0 -> 4446 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_feedback_tab.pngbin0 -> 4732 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_mic.pngbin0 -> 4487 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return.pngbin0 -> 4559 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return_holo.pngbin0 -> 1141 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search.pngbin0 -> 4990 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search_holo.pngbin0 -> 1769 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings.pngbin0 -> 4639 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings_holo.pngbin0 -> 1872 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift.pngbin0 -> 4186 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_holo.pngbin0 -> 1195 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked.pngbin0 -> 4119 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.pngbin0 -> 909 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space.pngbin0 -> 3526 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_holo.pngbin0 -> 523 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_led.9.pngbin0 -> 617 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.pngbin0 -> 381 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab.pngbin0 -> 4157 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab_holo.pngbin0 -> 1186 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_holo.pngbin0 -> 1427 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.pngbin0 -> 1192 bytes
-rw-r--r--java/res/drawable-xhdpi/vs_dialog_blue.9.pngbin0 -> 11547 bytes
-rw-r--r--java/res/drawable-xhdpi/vs_dialog_red.9.pngbin0 -> 11400 bytes
-rw-r--r--java/res/drawable-xhdpi/vs_dialog_yellow.9.pngbin0 -> 10921 bytes
-rw-r--r--java/res/drawable-xhdpi/vs_popup_mic_edge.pngbin0 -> 4670 bytes
-rw-r--r--java/res/drawable/btn_candidate_ics.xml (renamed from java/res/drawable/btn_candidate_holo.xml)2
-rw-r--r--java/res/drawable/btn_keyboard_key_ics.xml (renamed from java/res/drawable/btn_keyboard_key_honeycomb.xml)3
-rw-r--r--java/res/drawable/btn_keyboard_key_popup.xml (renamed from java/res/drawable/btn_keyboard_key_gingerbread_popup.xml)4
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_ics.xml (renamed from java/res/drawable/btn_keyboard_key_honeycomb_popup.xml)3
-rw-r--r--java/res/drawable/btn_keyboard_key_stone.xml7
-rw-r--r--java/res/drawable/keyboard_key_feedback_ics.xml (renamed from java/res/drawable/keyboard_key_feedback_honeycomb.xml)2
-rw-r--r--java/res/drawable/keyboard_key_feedback_left_ics.xml (renamed from java/res/drawable/btn_keyboard_key_fulltrans.xml)13
-rw-r--r--java/res/drawable/keyboard_key_feedback_right_ics.xml21
-rw-r--r--java/res/drawable/transparent.xml (renamed from java/res/anim/key_preview_fadeout.xml)17
-rw-r--r--java/res/layout-sw600dp/candidate.xml60
-rw-r--r--java/res/layout-sw600dp/candidates.xml45
-rw-r--r--java/res/layout-sw600dp/keyboard_popup_honeycomb.xml41
-rw-r--r--java/res/layout-sw768dp/candidate.xml60
-rw-r--r--java/res/layout-sw768dp/candidates.xml45
-rw-r--r--java/res/layout-sw768dp/keyboard_popup_honeycomb.xml41
-rw-r--r--java/res/layout-sw768dp/recognition_status.xml101
-rw-r--r--java/res/layout/candidate.xml60
-rw-r--r--java/res/layout/candidate_divider.xml (renamed from java/res/anim/key_preview_fadein.xml)14
-rw-r--r--java/res/layout/candidate_info.xml (renamed from java/res/layout-sw600dp/candidate_preview.xml)8
-rw-r--r--java/res/layout/candidate_preview.xml5
-rw-r--r--java/res/layout/candidate_word.xml (renamed from java/res/layout-sw768dp/candidate_preview.xml)19
-rw-r--r--java/res/layout/candidates.xml45
-rw-r--r--java/res/layout/candidates_strip.xml84
-rw-r--r--java/res/layout/input_basic.xml31
-rw-r--r--java/res/layout/input_basic_highcontrast.xml32
-rw-r--r--java/res/layout/input_gingerbread.xml34
-rw-r--r--java/res/layout/input_honeycomb.xml39
-rw-r--r--java/res/layout/input_stone_bold.xml37
-rw-r--r--java/res/layout/input_stone_normal.xml36
-rw-r--r--java/res/layout/input_stone_popup.xml41
-rw-r--r--java/res/layout/input_view.xml82
-rw-r--r--java/res/layout/key_preview.xml2
-rw-r--r--java/res/layout/key_preview_honeycomb.xml29
-rw-r--r--java/res/layout/keyboard_popup.xml17
-rw-r--r--java/res/layout/keyboard_popup_honeycomb.xml41
-rw-r--r--java/res/layout/recognition_status.xml29
-rw-r--r--java/res/values-af/strings.xml256
-rw-r--r--java/res/values-am/strings.xml256
-rw-r--r--java/res/values-ar/strings.xml80
-rw-r--r--java/res/values-bg/strings.xml80
-rw-r--r--java/res/values-ca/strings.xml80
-rw-r--r--java/res/values-cs/strings.xml80
-rw-r--r--java/res/values-da/strings.xml80
-rw-r--r--java/res/values-de-rZZ/donottranslate-altchars.xml29
-rw-r--r--java/res/values-de/config.xml (renamed from java/res/values-sw600dp/donottranslate.xml)6
-rw-r--r--java/res/values-de/strings.xml80
-rw-r--r--java/res/values-el/strings.xml80
-rw-r--r--java/res/values-en-rGB/strings.xml80
-rw-r--r--java/res/values-en/whitelist.xml38
-rw-r--r--java/res/values-es-rUS/strings.xml80
-rw-r--r--java/res/values-es/donottranslate-altchars.xml2
-rw-r--r--java/res/values-es/strings.xml80
-rw-r--r--java/res/values-fa/strings.xml80
-rw-r--r--java/res/values-fi/strings.xml80
-rw-r--r--java/res/values-fr/donottranslate-altchars.xml10
-rw-r--r--java/res/values-fr/donottranslate.xml12
-rw-r--r--java/res/values-fr/strings.xml80
-rw-r--r--java/res/values-hdpi/config.xml (renamed from java/res/values-sw768dp/donottranslate.xml)9
-rw-r--r--java/res/values-hr/donottranslate-altchars.xml27
-rw-r--r--java/res/values-hr/strings.xml80
-rw-r--r--java/res/values-hu/strings.xml80
-rw-r--r--java/res/values-in/strings.xml80
-rw-r--r--java/res/values-it/donottranslate.xml4
-rw-r--r--java/res/values-it/strings.xml80
-rw-r--r--java/res/values-iw/strings.xml80
-rw-r--r--java/res/values-ja/strings.xml80
-rw-r--r--java/res/values-ko/strings.xml80
-rw-r--r--java/res/values-land/dimens.xml52
-rw-r--r--java/res/values-lt/strings.xml80
-rw-r--r--java/res/values-lv/strings.xml80
-rw-r--r--java/res/values-ms/strings.xml237
-rw-r--r--java/res/values-nb/strings.xml80
-rw-r--r--java/res/values-nl/strings.xml80
-rw-r--r--java/res/values-pl/strings.xml80
-rw-r--r--java/res/values-pt-rPT/strings.xml80
-rw-r--r--java/res/values-pt/strings.xml80
-rw-r--r--java/res/values-rm/strings.xml128
-rw-r--r--java/res/values-ro/strings.xml80
-rw-r--r--java/res/values-ru/strings.xml80
-rw-r--r--java/res/values-sk/strings.xml80
-rw-r--r--java/res/values-sl/strings.xml80
-rw-r--r--java/res/values-sr/strings.xml80
-rw-r--r--java/res/values-sv/strings.xml80
-rw-r--r--java/res/values-sw/strings.xml256
-rw-r--r--java/res/values-sw600dp-land/dimens.xml38
-rw-r--r--java/res/values-sw600dp/config.xml4
-rw-r--r--java/res/values-sw600dp/dimens.xml51
-rw-r--r--java/res/values-sw768dp-land/dimens.xml48
-rw-r--r--java/res/values-sw768dp/config.xml9
-rw-r--r--java/res/values-sw768dp/dimens.xml61
-rw-r--r--java/res/values-th/strings.xml80
-rw-r--r--java/res/values-tl/strings.xml80
-rw-r--r--java/res/values-tr/strings.xml80
-rw-r--r--java/res/values-uk/strings.xml80
-rw-r--r--java/res/values-vi/strings.xml82
-rw-r--r--java/res/values-zh-rCN/strings.xml80
-rw-r--r--java/res/values-zh-rTW/strings.xml80
-rw-r--r--java/res/values-zu/strings.xml256
-rw-r--r--java/res/values/attrs.xml229
-rw-r--r--java/res/values/colors.xml31
-rw-r--r--java/res/values/config.xml32
-rw-r--r--java/res/values/dimens.xml79
-rw-r--r--java/res/values/donottranslate.xml37
-rw-r--r--java/res/values/keyboard-icons-black.xml44
-rw-r--r--java/res/values/keyboard-icons-ics.xml43
-rw-r--r--java/res/values/keyboard-icons-white.xml40
-rw-r--r--java/res/values/keycodes.xml24
-rw-r--r--java/res/values/strings.xml164
-rw-r--r--java/res/values/styles.xml178
-rw-r--r--java/res/values/themes-basic-highcontrast.xml29
-rw-r--r--java/res/values/themes-basic.xml29
-rw-r--r--java/res/values/themes-gingerbread.xml29
-rw-r--r--java/res/values/themes-ics.xml29
-rw-r--r--java/res/values/themes-stone-bold.xml29
-rw-r--r--java/res/values/themes-stone.xml29
-rw-r--r--java/res/values/whitelist.xml9
-rw-r--r--java/res/xml-ar/kbd_qwerty.xml (renamed from java/res/xml-sw600dp/kbd_qwerty.xml)11
-rw-r--r--java/res/xml-cs/kbd_qwerty.xml11
-rw-r--r--java/res/xml-da/kbd_qwerty.xml10
-rw-r--r--java/res/xml-de-rZZ/kbd_qwerty.xml27
-rw-r--r--java/res/xml-de/kbd_qwerty.xml11
-rw-r--r--java/res/xml-es/kbd_qwerty.xml27
-rw-r--r--java/res/xml-fi/kbd_qwerty.xml10
-rw-r--r--java/res/xml-fr-rCA/kbd_qwerty.xml11
-rw-r--r--java/res/xml-fr-rCH/kbd_qwerty.xml11
-rw-r--r--java/res/xml-fr/kbd_qwerty.xml11
-rw-r--r--java/res/xml-hr/kbd_qwerty.xml28
-rw-r--r--java/res/xml-hu/kbd_qwerty.xml11
-rw-r--r--java/res/xml-iw/kbd_qwerty.xml107
-rw-r--r--java/res/xml-nb/kbd_qwerty.xml10
-rw-r--r--java/res/xml-pl/kbd_qwerty.xml27
-rw-r--r--java/res/xml-pt/kbd_qwerty.xml27
-rw-r--r--java/res/xml-ru/kbd_qwerty.xml10
-rw-r--r--java/res/xml-sr/kbd_qwerty.xml10
-rw-r--r--java/res/xml-sv/kbd_qwerty.xml10
-rw-r--r--java/res/xml-sw600dp/kbd_key_styles.xml180
-rw-r--r--java/res/xml-sw600dp/kbd_number.xml70
-rw-r--r--java/res/xml-sw600dp/kbd_numkey_styles.xml150
-rw-r--r--java/res/xml-sw600dp/kbd_phone.xml42
-rw-r--r--java/res/xml-sw600dp/kbd_phone_symbols.xml48
-rw-r--r--java/res/xml-sw600dp/kbd_popup_template.xml2
-rw-r--r--java/res/xml-sw600dp/kbd_qwerty_f2.xml12
-rw-r--r--java/res/xml-sw600dp/kbd_qwerty_row1.xml2
-rw-r--r--java/res/xml-sw600dp/kbd_qwerty_row2.xml2
-rw-r--r--java/res/xml-sw600dp/kbd_qwerty_row3.xml10
-rw-r--r--java/res/xml-sw600dp/kbd_qwerty_row4.xml37
-rw-r--r--java/res/xml-sw600dp/kbd_row3_right.xml18
-rw-r--r--java/res/xml-sw600dp/kbd_rows_arabic.xml134
-rw-r--r--java/res/xml-sw600dp/kbd_rows_azerty.xml (renamed from java/res/xml-sw600dp/kbd_azerty_rows.xml)23
-rw-r--r--java/res/xml-sw600dp/kbd_rows_hebrew.xml122
-rw-r--r--java/res/xml-sw600dp/kbd_rows_qwerty.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_rows.xml)0
-rw-r--r--java/res/xml-sw600dp/kbd_rows_qwertz.xml (renamed from java/res/xml-sw600dp/kbd_qwertz_rows.xml)12
-rw-r--r--java/res/xml-sw600dp/kbd_rows_russian.xml (renamed from java/res/xml-sw600dp/kbd_ru_rows.xml)9
-rw-r--r--java/res/xml-sw600dp/kbd_rows_scandinavian.xml (renamed from java/res/xml-sw600dp/kbd_qwerty_rows_scandinavia.xml)66
-rw-r--r--java/res/xml-sw600dp/kbd_rows_serbian.xml (renamed from java/res/xml-sw600dp/kbd_sr_rows.xml)14
-rw-r--r--java/res/xml-sw600dp/kbd_rows_spanish.xml69
-rw-r--r--java/res/xml-sw600dp/kbd_symbols.xml15
-rw-r--r--java/res/xml-sw600dp/kbd_symbols_shift.xml13
-rw-r--r--java/res/xml-sw768dp/kbd_key_styles.xml162
-rw-r--r--java/res/xml-sw768dp/kbd_number.xml64
-rw-r--r--java/res/xml-sw768dp/kbd_numkey_styles.xml148
-rw-r--r--java/res/xml-sw768dp/kbd_phone.xml60
-rw-r--r--java/res/xml-sw768dp/kbd_phone_symbols.xml58
-rw-r--r--java/res/xml-sw768dp/kbd_qwerty.xml33
-rw-r--r--java/res/xml-sw768dp/kbd_qwerty_row1.xml2
-rw-r--r--java/res/xml-sw768dp/kbd_qwerty_row2.xml2
-rw-r--r--java/res/xml-sw768dp/kbd_qwerty_row3.xml28
-rw-r--r--java/res/xml-sw768dp/kbd_qwerty_row4.xml233
-rw-r--r--java/res/xml-sw768dp/kbd_row3_right2.xml46
-rw-r--r--java/res/xml-sw768dp/kbd_rows_arabic.xml140
-rw-r--r--java/res/xml-sw768dp/kbd_rows_azerty.xml (renamed from java/res/xml-sw768dp/kbd_azerty_rows.xml)21
-rw-r--r--java/res/xml-sw768dp/kbd_rows_hebrew.xml127
-rw-r--r--java/res/xml-sw768dp/kbd_rows_qwerty.xml (renamed from java/res/xml-sw768dp/kbd_qwerty_rows.xml)0
-rw-r--r--java/res/xml-sw768dp/kbd_rows_qwertz.xml (renamed from java/res/xml-sw768dp/kbd_qwertz_rows.xml)14
-rw-r--r--java/res/xml-sw768dp/kbd_rows_russian.xml (renamed from java/res/xml-sw768dp/kbd_ru_rows.xml)34
-rw-r--r--java/res/xml-sw768dp/kbd_rows_scandinavian.xml (renamed from java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml)52
-rw-r--r--java/res/xml-sw768dp/kbd_rows_serbian.xml (renamed from java/res/xml-sw768dp/kbd_sr_rows.xml)78
-rw-r--r--java/res/xml-sw768dp/kbd_rows_spanish.xml72
-rw-r--r--java/res/xml-sw768dp/kbd_symbols.xml97
-rw-r--r--java/res/xml-sw768dp/kbd_symbols_shift.xml21
-rw-r--r--java/res/xml-tr/kbd_qwerty.xml27
-rw-r--r--java/res/xml/kbd_currency_key_styles.xml232
-rw-r--r--java/res/xml/kbd_key_styles.xml296
-rw-r--r--java/res/xml/kbd_number.xml51
-rw-r--r--java/res/xml/kbd_numkey_styles.xml209
-rw-r--r--java/res/xml/kbd_phone.xml21
-rw-r--r--java/res/xml/kbd_phone_symbols.xml44
-rw-r--r--java/res/xml/kbd_popup_template.xml2
-rw-r--r--java/res/xml/kbd_qwerty.xml11
-rw-r--r--java/res/xml/kbd_qwerty_f1.xml91
-rw-r--r--java/res/xml/kbd_qwerty_row1.xml22
-rw-r--r--java/res/xml/kbd_qwerty_row2.xml4
-rw-r--r--java/res/xml/kbd_qwerty_row3.xml4
-rw-r--r--java/res/xml/kbd_qwerty_row4.xml113
-rw-r--r--java/res/xml/kbd_rows_arabic.xml122
-rw-r--r--java/res/xml/kbd_rows_azerty.xml (renamed from java/res/xml/kbd_azerty_rows.xml)31
-rw-r--r--java/res/xml/kbd_rows_hebrew.xml111
-rw-r--r--java/res/xml/kbd_rows_qwerty.xml (renamed from java/res/xml/kbd_qwerty_rows.xml)0
-rw-r--r--java/res/xml/kbd_rows_qwertz.xml (renamed from java/res/xml/kbd_qwertz_rows.xml)26
-rw-r--r--java/res/xml/kbd_rows_russian.xml (renamed from java/res/xml/kbd_ru_rows.xml)26
-rw-r--r--java/res/xml/kbd_rows_scandinavian.xml (renamed from java/res/xml/kbd_qwerty_rows_scandinavia.xml)24
-rw-r--r--java/res/xml/kbd_rows_serbian.xml (renamed from java/res/xml/kbd_sr_rows.xml)26
-rw-r--r--java/res/xml/kbd_rows_spanish.xml64
-rw-r--r--java/res/xml/kbd_symbols.xml15
-rw-r--r--java/res/xml/kbd_symbols_f1.xml39
-rw-r--r--java/res/xml/kbd_symbols_row4.xml73
-rw-r--r--java/res/xml/kbd_symbols_shift.xml15
-rw-r--r--java/res/xml/kbd_symbols_shift_row4.xml70
-rw-r--r--java/res/xml/method.xml248
-rw-r--r--java/res/xml/prefs.xml192
-rw-r--r--java/res/xml/prefs_for_debug.xml7
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java133
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java172
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java48
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java220
-rw-r--r--java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java227
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java227
-rw-r--r--java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java39
-rw-r--r--java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java39
-rw-r--r--java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java42
-rw-r--r--java/src/com/android/inputmethod/compat/ArraysCompatUtils.java50
-rw-r--r--java/src/com/android/inputmethod/compat/CompatUtils.java156
-rw-r--r--java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java102
-rw-r--r--java/src/com/android/inputmethod/compat/FrameLayoutCompatUtils.java63
-rw-r--r--java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java80
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java59
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java227
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java84
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java161
-rw-r--r--java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java118
-rw-r--r--java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java55
-rw-r--r--java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java23
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java87
-rw-r--r--java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java47
-rw-r--r--java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java90
-rw-r--r--java/src/com/android/inputmethod/deprecated/VoiceProxy.java (renamed from java/src/com/android/inputmethod/voice/VoiceIMEConnector.java)156
-rw-r--r--java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java36
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java255
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java (renamed from java/src/com/android/inputmethod/latin/LanguageSwitcher.java)67
-rw-r--r--java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java287
-rw-r--r--java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java62
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/FieldContext.java (renamed from java/src/com/android/inputmethod/voice/FieldContext.java)2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/Hints.java (renamed from java/src/com/android/inputmethod/voice/Hints.java)2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java (renamed from java/src/com/android/inputmethod/voice/RecognitionView.java)3
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java (renamed from java/src/com/android/inputmethod/voice/SettingsUtil.java)2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java (renamed from java/src/com/android/inputmethod/voice/SoundIndicator.java)2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java (renamed from java/src/com/android/inputmethod/voice/VoiceInput.java)23
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java (renamed from java/src/com/android/inputmethod/voice/VoiceInputLogger.java)13
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java (renamed from java/src/com/android/inputmethod/voice/WaveformImage.java)2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/Whitelist.java (renamed from java/src/com/android/inputmethod/voice/Whitelist.java)2
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java184
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java177
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java158
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java111
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java466
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java1626
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboard.java332
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java621
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java70
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboard.java31
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java672
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java97
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java193
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupPanel.java45
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java69
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java126
-rw-r--r--java/src/com/android/inputmethod/keyboard/SwipeTracker.java157
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java (renamed from java/src/com/android/inputmethod/keyboard/KeyStyles.java)40
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java119
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java (renamed from java/src/com/android/inputmethod/keyboard/KeyboardParser.java)199
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java (renamed from java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java)4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java (renamed from java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java)36
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java (renamed from java/src/com/android/inputmethod/keyboard/ModifierKeyState.java)4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java (renamed from java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java)19
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java (renamed from java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java)29
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/Row.java (renamed from java/src/com/android/inputmethod/keyboard/Row.java)7
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java (renamed from java/src/com/android/inputmethod/keyboard/ShiftKeyState.java)2
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/SlidingLocaleDrawable.java (renamed from java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java)83
-rw-r--r--java/src/com/android/inputmethod/latin/AccessibilityUtils.java211
-rw-r--r--java/src/com/android/inputmethod/latin/AssetFileAddress.java52
-rw-r--r--java/src/com/android/inputmethod/latin/AutoCorrection.java10
-rw-r--r--java/src/com/android/inputmethod/latin/AutoDictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java162
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java151
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java97
-rw-r--r--java/src/com/android/inputmethod/latin/CandidateView.java658
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsDictionary.java21
-rw-r--r--java/src/com/android/inputmethod/latin/DebugSettings.java8
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java10
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryCollection.java71
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java177
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java89
-rw-r--r--java/src/com/android/inputmethod/latin/EditingUtils.java147
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java71
-rw-r--r--java/src/com/android/inputmethod/latin/Flag.java64
-rw-r--r--java/src/com/android/inputmethod/latin/InputLanguageSelection.java211
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java1512
-rw-r--r--java/src/com/android/inputmethod/latin/LatinImeLogger.java8
-rw-r--r--java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java29
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java388
-rw-r--r--java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java42
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java401
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java225
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java25
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java43
-rw-r--r--java/src/com/android/inputmethod/latin/TextEntryState.java23
-rw-r--r--java/src/com/android/inputmethod/latin/UserBigramDictionary.java12
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java40
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java267
-rw-r--r--java/src/com/android/inputmethod/latin/WhitelistDictionary.java1
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java14
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java115
974 files changed, 17912 insertions, 9042 deletions
diff --git a/java/Android.mk b/java/Android.mk
index 60c321ab2..43168e563 100644
--- a/java/Android.mk
+++ b/java/Android.mk
@@ -12,6 +12,7 @@ LOCAL_CERTIFICATE := shared
LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime
LOCAL_STATIC_JAVA_LIBRARIES := android-common
+LOCAL_STATIC_JAVA_LIBRARIES += inputmethod-common
# Do not compress dictionary files to mmap dict data runtime
LOCAL_AAPT_FLAGS := -0 .dict
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index e0eecfc7d..cb0a9a2e1 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -33,7 +33,7 @@
</intent-filter>
</activity>
- <activity android:name="InputLanguageSelection"
+ <activity android:name="com.android.inputmethod.deprecated.languageswitcher.InputLanguageSelection"
android:label="@string/language_selection_title">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -41,5 +41,11 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+
+ <receiver android:name="SuggestionSpanPickedNotificationReceiver" android:enabled="true">
+ <intent-filter>
+ <action android:name="android.text.style.SUGGESTION_PICKED" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/java/proguard.flags b/java/proguard.flags
index 729f4ad61..7ce6f41b5 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -18,3 +18,15 @@
-keep class com.android.inputmethod.latin.AutoCorrection {
java.lang.CharSequence getAutoCorrectionWord();
}
+
+-keep class com.android.inputmethod.latin.Utils {
+ boolean equalsIgnoreCase(...);
+}
+
+-keep class com.android.inputmethod.latin.spellcheck.SpellChecker {
+ *;
+}
+
+-keep class com.android.inputmethod.latin.SettingsActivity {
+ *;
+}
diff --git a/java/res/anim/mini_keyboard_fadein.xml b/java/res/anim/mini_keyboard_fadein.xml
index 9fad7b9a7..f80e8b8de 100644
--- a/java/res/anim/mini_keyboard_fadein.xml
+++ b/java/res/anim/mini_keyboard_fadein.xml
@@ -25,5 +25,5 @@
<alpha
android:fromAlpha="0.5"
android:toAlpha="1.0"
- android:duration="@integer/config_preview_fadein_anim_time" />
+ android:duration="@integer/config_mini_keyboard_fadein_anim_time" />
</set>
diff --git a/java/res/anim/mini_keyboard_fadeout.xml b/java/res/anim/mini_keyboard_fadeout.xml
index 7de5123cd..535b100ae 100644
--- a/java/res/anim/mini_keyboard_fadeout.xml
+++ b/java/res/anim/mini_keyboard_fadeout.xml
@@ -25,5 +25,5 @@
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
- android:duration="@integer/config_preview_fadeout_anim_time" />
+ android:duration="@integer/config_mini_keyboard_fadeout_anim_time" />
</set>
diff --git a/java/res/drawable-hdpi/btn_center_default.9.png b/java/res/drawable-hdpi/btn_center_default.9.png
index d5ec36ba4..4f5f01cb8 100644
--- a/java/res/drawable-hdpi/btn_center_default.9.png
+++ b/java/res/drawable-hdpi/btn_center_default.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_center_pressed.9.png b/java/res/drawable-hdpi/btn_center_pressed.9.png
index 593a679d0..213b482d4 100644
--- a/java/res/drawable-hdpi/btn_center_pressed.9.png
+++ b/java/res/drawable-hdpi/btn_center_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_center_selected.9.png b/java/res/drawable-hdpi/btn_center_selected.9.png
index f1914a886..213b482d4 100644
--- a/java/res/drawable-hdpi/btn_center_selected.9.png
+++ b/java/res/drawable-hdpi/btn_center_selected.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
index 50cc49fdb..bc130cab6 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
index a8c1688f7..5e6a9d6a4 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
index dabf77ec6..43099899c 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index 829647663..eb9d7406a 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
index 6e7d74c88..2d1acf22f 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index 020a65d6e..869a33080 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
index ddb77c224..af5ea6bd2 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 88b27c07b..1195a42c1 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
index 1e9227e1c..3e25a9817 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 87497bc1f..0a9d4b453 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
index 7207b2ece..fc7ba2aeb 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index f0d76dfa2..fac757a03 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
index b6c234c04..116329016 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
index 73a8cd1c3..207c90d6c 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
index 9d85c7b74..005c4e498 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
index 3115fa436..baff85873 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
index 77e17dbae..9a07acd91 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
index a409639e7..be420a7af 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
index dc08102a7..f0ebdafbb 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png
index 42c7c146d..3e25180f0 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
index 01e2506b0..bad360f77 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
index fad0ec458..cdd6c8b79 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
index 83c6eb3fc..49f519860 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
index 215f8157c..d8421746a 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
index 88acdd748..44c2ad637 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_popup_background_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_popup_background_holo.9.png
new file mode 100644
index 000000000..d3d831484
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_popup_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
index 5ecdaf428..1ab6160b2 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
index e047eaff1..e784eddf8 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
index 218a2d29e..a4731cf1a 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
index afe49512e..03e163c9c 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/candidate_feedback_background.9.png b/java/res/drawable-hdpi/candidate_feedback_background.9.png
index 203c4e640..16499002e 100644
--- a/java/res/drawable-hdpi/candidate_feedback_background.9.png
+++ b/java/res/drawable-hdpi/candidate_feedback_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/caution.png b/java/res/drawable-hdpi/caution.png
index 5cb6c54b9..61eb4dd62 100644
--- a/java/res/drawable-hdpi/caution.png
+++ b/java/res/drawable-hdpi/caution.png
Binary files differ
diff --git a/java/res/drawable-hdpi/hint_popup.9.png b/java/res/drawable-hdpi/hint_popup.9.png
deleted file mode 100644
index b5ec003e6..000000000
--- a/java/res/drawable-hdpi/hint_popup.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/hint_popup_holo.9.png b/java/res/drawable-hdpi/hint_popup_holo.9.png
deleted file mode 100644
index 2ffc6ea2b..000000000
--- a/java/res/drawable-hdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_dialog_keyboard.png b/java/res/drawable-hdpi/ic_dialog_keyboard.png
index c7729566c..305441633 100644
--- a/java/res/drawable-hdpi/ic_dialog_keyboard.png
+++ b/java/res/drawable-hdpi/ic_dialog_keyboard.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_mic_dialog.png b/java/res/drawable-hdpi/ic_mic_dialog.png
index 349dc4b37..6107f876e 100644
--- a/java/res/drawable-hdpi/ic_mic_dialog.png
+++ b/java/res/drawable-hdpi/ic_mic_dialog.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png
index 7015e266a..484305655 100644
--- a/java/res/drawable-hdpi/ic_subtype_keyboard.png
+++ b/java/res/drawable-hdpi/ic_subtype_keyboard.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_mic.png b/java/res/drawable-hdpi/ic_subtype_mic.png
index cb86a5598..25c9ee2ab 100644
--- a/java/res/drawable-hdpi/ic_subtype_mic.png
+++ b/java/res/drawable-hdpi/ic_subtype_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_suggest_strip_microphone.png b/java/res/drawable-hdpi/ic_suggest_strip_microphone.png
index c00b4aaa6..189a861fb 100644
--- a/java/res/drawable-hdpi/ic_suggest_strip_microphone.png
+++ b/java/res/drawable-hdpi/ic_suggest_strip_microphone.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png b/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png
index 256dc3d61..b4a6e373b 100644
--- a/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png
+++ b/java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_at_holo.9.png b/java/res/drawable-hdpi/key_hint_at_holo.9.png
deleted file mode 100644
index b93c2d3cf..000000000
--- a/java/res/drawable-hdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_at_large_holo.9.png b/java/res/drawable-hdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index 2b9295158..000000000
--- a/java/res/drawable-hdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_colon_holo.9.png b/java/res/drawable-hdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 8fa17e583..000000000
--- a/java/res/drawable-hdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-hdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 1271341e6..000000000
--- a/java/res/drawable-hdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_comma_holo.9.png b/java/res/drawable-hdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index 44220ec96..000000000
--- a/java/res/drawable-hdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-hdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 444b4d029..000000000
--- a/java/res/drawable-hdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-hdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index d5e688400..000000000
--- a/java/res/drawable-hdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-hdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 5dab2f646..000000000
--- a/java/res/drawable-hdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num0.9.png b/java/res/drawable-hdpi/key_hint_num0.9.png
deleted file mode 100644
index 271264e92..000000000
--- a/java/res/drawable-hdpi/key_hint_num0.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num1.9.png b/java/res/drawable-hdpi/key_hint_num1.9.png
deleted file mode 100644
index eaf374262..000000000
--- a/java/res/drawable-hdpi/key_hint_num1.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num2.9.png b/java/res/drawable-hdpi/key_hint_num2.9.png
deleted file mode 100644
index 8a1657117..000000000
--- a/java/res/drawable-hdpi/key_hint_num2.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num3.9.png b/java/res/drawable-hdpi/key_hint_num3.9.png
deleted file mode 100644
index 34b501109..000000000
--- a/java/res/drawable-hdpi/key_hint_num3.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num4.9.png b/java/res/drawable-hdpi/key_hint_num4.9.png
deleted file mode 100644
index d4cc250dd..000000000
--- a/java/res/drawable-hdpi/key_hint_num4.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num5.9.png b/java/res/drawable-hdpi/key_hint_num5.9.png
deleted file mode 100644
index 6a054b42f..000000000
--- a/java/res/drawable-hdpi/key_hint_num5.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num6.9.png b/java/res/drawable-hdpi/key_hint_num6.9.png
deleted file mode 100644
index 66e91400a..000000000
--- a/java/res/drawable-hdpi/key_hint_num6.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num7.9.png b/java/res/drawable-hdpi/key_hint_num7.9.png
deleted file mode 100644
index 5eae24f4f..000000000
--- a/java/res/drawable-hdpi/key_hint_num7.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num8.9.png b/java/res/drawable-hdpi/key_hint_num8.9.png
deleted file mode 100644
index ea7f512fd..000000000
--- a/java/res/drawable-hdpi/key_hint_num8.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_num9.9.png b/java/res/drawable-hdpi/key_hint_num9.9.png
deleted file mode 100644
index 0bf85de93..000000000
--- a/java/res/drawable-hdpi/key_hint_num9.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_plus_holo.9.png b/java/res/drawable-hdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index a11b4ac07..000000000
--- a/java/res/drawable-hdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-hdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index 3c87c1f7e..000000000
--- a/java/res/drawable-hdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_question_holo.9.png b/java/res/drawable-hdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 670b4b902..000000000
--- a/java/res/drawable-hdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_question_large_holo.9.png b/java/res/drawable-hdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 692f4a68b..000000000
--- a/java/res/drawable-hdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_quote_holo.9.png b/java/res/drawable-hdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 9cc86156e..000000000
--- a/java/res/drawable-hdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-hdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index 664467b3e..000000000
--- a/java/res/drawable-hdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_underline_holo.9.png b/java/res/drawable-hdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 2cb4077a7..000000000
--- a/java/res/drawable-hdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-hdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index 6b9a49170..000000000
--- a/java/res/drawable-hdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background.9.png
index edffac5b8..d57463fb6 100644
--- a/java/res/drawable-hdpi/keyboard_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_background_holo.9.png b/java/res/drawable-hdpi/keyboard_background_holo.9.png
index 76fe2c8b8..39746ffd2 100644
--- a/java/res/drawable-hdpi/keyboard_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_dark_background.9.png b/java/res/drawable-hdpi/keyboard_dark_background.9.png
index f315cbdd4..fa3d449f7 100644
--- a/java/res/drawable-hdpi/keyboard_dark_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_dark_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
index 943f9e4bc..36809d483 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
new file mode 100644
index 000000000..59c8fd2e4
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
new file mode 100644
index 000000000..875c65695
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
index c21240f17..4bd774395 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
new file mode 100644
index 000000000..e4ae59db5
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
new file mode 100644
index 000000000..9af394e95
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png b/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png
index d6b2c7936..baff80950 100644
--- a/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip.9.png
index 0ccdb6ab2..7cab5a899 100644
--- a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
index f55bcc933..85b6360c5 100644
--- a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/mic_base.png b/java/res/drawable-hdpi/mic_base.png
index 53e29ff4b..504a1aa2a 100644
--- a/java/res/drawable-hdpi/mic_base.png
+++ b/java/res/drawable-hdpi/mic_base.png
Binary files differ
diff --git a/java/res/drawable-hdpi/mic_full.png b/java/res/drawable-hdpi/mic_full.png
index e3e3dfac3..3f4a67657 100644
--- a/java/res/drawable-hdpi/mic_full.png
+++ b/java/res/drawable-hdpi/mic_full.png
Binary files differ
diff --git a/java/res/drawable-hdpi/mic_slash.png b/java/res/drawable-hdpi/mic_slash.png
index 1dd05c5b4..c3b10929b 100644
--- a/java/res/drawable-hdpi/mic_slash.png
+++ b/java/res/drawable-hdpi/mic_slash.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_delete_rtl.png b/java/res/drawable-hdpi/sym_bkeyboard_delete_rtl.png
new file mode 100644
index 000000000..102eac781
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_bkeyboard_delete_rtl.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num0.png b/java/res/drawable-hdpi/sym_bkeyboard_num0.png
deleted file mode 100644
index 678a790de..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num0.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num1.png b/java/res/drawable-hdpi/sym_bkeyboard_num1.png
deleted file mode 100644
index 4e68e35b3..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num1.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num2.png b/java/res/drawable-hdpi/sym_bkeyboard_num2.png
deleted file mode 100644
index 546663fda..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num2.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num3.png b/java/res/drawable-hdpi/sym_bkeyboard_num3.png
deleted file mode 100644
index 57f9a8d8e..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num3.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num4.png b/java/res/drawable-hdpi/sym_bkeyboard_num4.png
deleted file mode 100644
index de504388f..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num4.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num5.png b/java/res/drawable-hdpi/sym_bkeyboard_num5.png
deleted file mode 100644
index 1d2e1ef89..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num5.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num6.png b/java/res/drawable-hdpi/sym_bkeyboard_num6.png
deleted file mode 100644
index 39788b727..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num6.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num7.png b/java/res/drawable-hdpi/sym_bkeyboard_num7.png
deleted file mode 100644
index fff6f27bf..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num7.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num8.png b/java/res/drawable-hdpi/sym_bkeyboard_num8.png
deleted file mode 100644
index 8cc1a955e..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num8.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num9.png b/java/res/drawable-hdpi/sym_bkeyboard_num9.png
deleted file mode 100644
index 021742509..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_num9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_numalt.png b/java/res/drawable-hdpi/sym_bkeyboard_numalt.png
deleted file mode 100644
index 200714f66..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_numalt.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_numpound.png b/java/res/drawable-hdpi/sym_bkeyboard_numpound.png
deleted file mode 100644
index 0a46122b2..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_numpound.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_numstar.png b/java/res/drawable-hdpi/sym_bkeyboard_numstar.png
deleted file mode 100644
index ca22bd535..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_numstar.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_123_mic.png
index 62669803d..6f0aec24c 100644
--- a/java/res/drawable-hdpi/sym_keyboard_123_mic.png
+++ b/java/res/drawable-hdpi/sym_keyboard_123_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_123_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_123_mic_holo.png
new file mode 100644
index 000000000..3b32171ec
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_123_mic_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png
index 459ebcff8..0591b82cd 100644
--- a/java/res/drawable-hdpi/sym_keyboard_delete.png
+++ b/java/res/drawable-hdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
index ff2a4acbb..11ed0b3fe 100644
--- a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_rtl.png b/java/res/drawable-hdpi/sym_keyboard_delete_rtl.png
new file mode 100644
index 000000000..a508452bd
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_delete_rtl.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_rtl_holo.png b/java/res/drawable-hdpi/sym_keyboard_delete_rtl_holo.png
new file mode 100644
index 000000000..a77e4a00e
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_delete_rtl_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png
deleted file mode 100644
index eef789680..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png
deleted file mode 100644
index 8322e8e1d..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png
deleted file mode 100644
index 889477cfb..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png
deleted file mode 100644
index b0f6d7feb..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png b/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png
index f82c33ae3..a88a19d0d 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png b/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png
deleted file mode 100644
index 819236c8e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_return.png b/java/res/drawable-hdpi/sym_keyboard_feedback_return.png
deleted file mode 100644
index f038d3abe..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_search.png b/java/res/drawable-hdpi/sym_keyboard_feedback_search.png
deleted file mode 100644
index 337f9e4fe..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png b/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png
index 8a02be07e..6304b00ed 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_settings.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png b/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png
deleted file mode 100644
index abf15f8f9..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_space.png b/java/res/drawable-hdpi/sym_keyboard_feedback_space.png
index 70debca9b..67311fc8f 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_space.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png b/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png
index d2efb1619..d75fcacd5 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_tab.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png b/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png
deleted file mode 100644
index dcc4bd59b..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png b/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png
deleted file mode 100644
index ecf61a98e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png
index c8dca62a0..520a40f09 100644
--- a/java/res/drawable-hdpi/sym_keyboard_mic.png
+++ b/java/res/drawable-hdpi/sym_keyboard_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num0.png b/java/res/drawable-hdpi/sym_keyboard_num0.png
deleted file mode 100644
index 10ac70b9d..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num0.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num0_holo.png b/java/res/drawable-hdpi/sym_keyboard_num0_holo.png
deleted file mode 100644
index ec8b5a8d2..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num0_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num1.png b/java/res/drawable-hdpi/sym_keyboard_num1.png
deleted file mode 100644
index 0fc03efa5..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num1.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num1_holo.png b/java/res/drawable-hdpi/sym_keyboard_num1_holo.png
deleted file mode 100644
index 60c8ab8a8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num1_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num2.png b/java/res/drawable-hdpi/sym_keyboard_num2.png
deleted file mode 100644
index 283560b35..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num2.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num2_holo.png b/java/res/drawable-hdpi/sym_keyboard_num2_holo.png
deleted file mode 100644
index 578e37d6e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num2_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num3.png b/java/res/drawable-hdpi/sym_keyboard_num3.png
deleted file mode 100644
index 9a3b3294b..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num3.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num3_holo.png b/java/res/drawable-hdpi/sym_keyboard_num3_holo.png
deleted file mode 100644
index fb6250699..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num3_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num4.png b/java/res/drawable-hdpi/sym_keyboard_num4.png
deleted file mode 100644
index f13ff1ae9..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num4.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num4_holo.png b/java/res/drawable-hdpi/sym_keyboard_num4_holo.png
deleted file mode 100644
index c0e54a523..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num4_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num5.png b/java/res/drawable-hdpi/sym_keyboard_num5.png
deleted file mode 100644
index c251329fa..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num5.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num5_holo.png b/java/res/drawable-hdpi/sym_keyboard_num5_holo.png
deleted file mode 100644
index b581a4657..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num5_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num6.png b/java/res/drawable-hdpi/sym_keyboard_num6.png
deleted file mode 100644
index 4acba4c91..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num6.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num6_holo.png b/java/res/drawable-hdpi/sym_keyboard_num6_holo.png
deleted file mode 100644
index 0791802ba..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num6_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num7.png b/java/res/drawable-hdpi/sym_keyboard_num7.png
deleted file mode 100644
index 14931c18c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num7.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num7_holo.png b/java/res/drawable-hdpi/sym_keyboard_num7_holo.png
deleted file mode 100644
index 7b3d3a825..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num7_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num8.png b/java/res/drawable-hdpi/sym_keyboard_num8.png
deleted file mode 100644
index d4973fdc9..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num8.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num8_holo.png b/java/res/drawable-hdpi/sym_keyboard_num8_holo.png
deleted file mode 100644
index e076aedbe..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num8_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num9.png b/java/res/drawable-hdpi/sym_keyboard_num9.png
deleted file mode 100644
index 49cec66f4..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num9_holo.png b/java/res/drawable-hdpi/sym_keyboard_num9_holo.png
deleted file mode 100644
index 4189cda79..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_num9_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numalt.png b/java/res/drawable-hdpi/sym_keyboard_numalt.png
deleted file mode 100644
index 3cc5311cd..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_numalt.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numbpound_holo.png b/java/res/drawable-hdpi/sym_keyboard_numbpound_holo.png
deleted file mode 100644
index 73f8be054..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_numbpound_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numbstar_holo.png b/java/res/drawable-hdpi/sym_keyboard_numbstar_holo.png
deleted file mode 100644
index fcb891b93..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_numbstar_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numpound.png b/java/res/drawable-hdpi/sym_keyboard_numpound.png
deleted file mode 100644
index d09133929..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_numpound.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numstar.png b/java/res/drawable-hdpi/sym_keyboard_numstar.png
deleted file mode 100644
index e838e169f..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_numstar.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png
index 9d97e1efd..9743c7f2f 100644
--- a/java/res/drawable-hdpi/sym_keyboard_return.png
+++ b/java/res/drawable-hdpi/sym_keyboard_return.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo.png b/java/res/drawable-hdpi/sym_keyboard_return_holo.png
index ca3c02dbe..090608209 100644
--- a/java/res/drawable-hdpi/sym_keyboard_return_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png
index 1aa22d7e2..8cd28c64a 100644
--- a/java/res/drawable-hdpi/sym_keyboard_search.png
+++ b/java/res/drawable-hdpi/sym_keyboard_search.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-hdpi/sym_keyboard_search_holo.png
new file mode 100644
index 000000000..86b925217
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_search_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png
index 35d1ed6e6..1e5bf939e 100644
--- a/java/res/drawable-hdpi/sym_keyboard_settings.png
+++ b/java/res/drawable-hdpi/sym_keyboard_settings.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
index 471bd0b86..c08b2b7f3 100644
--- a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png
index bf217d147..8e3d0320c 100644
--- a/java/res/drawable-hdpi/sym_keyboard_shift.png
+++ b/java/res/drawable-hdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
index 375c1b4ca..c38ef4f50 100644
--- a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
index d11b39712..d345634a6 100644
--- a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
index 57362eaf4..2754c7a99 100644
--- a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space.png b/java/res/drawable-hdpi/sym_keyboard_space.png
index fcd20de7d..780733ec5 100644
--- a/java/res/drawable-hdpi/sym_keyboard_space.png
+++ b/java/res/drawable-hdpi/sym_keyboard_space.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-hdpi/sym_keyboard_space_holo.png
index a8e5f7d5e..2c350d5bb 100644
--- a/java/res/drawable-hdpi/sym_keyboard_space_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_space_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_led.9.png b/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
index 2c6f4a925..c76f64b94 100644
--- a/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
+++ b/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.png b/java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.png
new file mode 100644
index 000000000..34a1ebde2
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo.png
new file mode 100644
index 000000000..721574366
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_tab_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
index 5ea2edc53..d5414c83f 100644
--- a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png
index 6e6279a8a..6fb538cec 100644
--- a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/vs_dialog_blue.9.png b/java/res/drawable-hdpi/vs_dialog_blue.9.png
index cf27e8f43..4f813ead3 100644
--- a/java/res/drawable-hdpi/vs_dialog_blue.9.png
+++ b/java/res/drawable-hdpi/vs_dialog_blue.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/vs_dialog_red.9.png b/java/res/drawable-hdpi/vs_dialog_red.9.png
index 6c08d5a30..a2055600e 100644
--- a/java/res/drawable-hdpi/vs_dialog_red.9.png
+++ b/java/res/drawable-hdpi/vs_dialog_red.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/vs_dialog_yellow.9.png b/java/res/drawable-hdpi/vs_dialog_yellow.9.png
index 2fb06c263..ce664b676 100644
--- a/java/res/drawable-hdpi/vs_dialog_yellow.9.png
+++ b/java/res/drawable-hdpi/vs_dialog_yellow.9.png
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png
deleted file mode 100644
index 603bf0e15..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png
deleted file mode 100644
index 6ddd516e7..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off_stone.9.png
deleted file mode 100644
index 67a204f85..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_off_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png
deleted file mode 100644
index 65fdeb353..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on_stone.9.png
deleted file mode 100644
index 63cbe60a3..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_on_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_normal_stone.9.png
deleted file mode 100644
index 0dd33b429..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_normal_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png
deleted file mode 100644
index 7ec915fe8..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png
deleted file mode 100644
index 439271723..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png
deleted file mode 100644
index c2cc32044..000000000
--- a/java/res/drawable-land-hdpi/btn_keyboard_key_pressed_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/hint_popup_holo.9.png b/java/res/drawable-land-hdpi/hint_popup_holo.9.png
deleted file mode 100644
index 2b93014e1..000000000
--- a/java/res/drawable-land-hdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_at_holo.9.png b/java/res/drawable-land-hdpi/key_hint_at_holo.9.png
deleted file mode 100644
index b93c2d3cf..000000000
--- a/java/res/drawable-land-hdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_at_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index 2b9295158..000000000
--- a/java/res/drawable-land-hdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_colon_holo.9.png b/java/res/drawable-land-hdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 8fa17e583..000000000
--- a/java/res/drawable-land-hdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 1271341e6..000000000
--- a/java/res/drawable-land-hdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_comma_holo.9.png b/java/res/drawable-land-hdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index 44220ec96..000000000
--- a/java/res/drawable-land-hdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 444b4d029..000000000
--- a/java/res/drawable-land-hdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-land-hdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index d5e688400..000000000
--- a/java/res/drawable-land-hdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 5dab2f646..000000000
--- a/java/res/drawable-land-hdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_plus_holo.9.png b/java/res/drawable-land-hdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index a11b4ac07..000000000
--- a/java/res/drawable-land-hdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index 3c87c1f7e..000000000
--- a/java/res/drawable-land-hdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_question_holo.9.png b/java/res/drawable-land-hdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 670b4b902..000000000
--- a/java/res/drawable-land-hdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_question_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 692f4a68b..000000000
--- a/java/res/drawable-land-hdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_quote_holo.9.png b/java/res/drawable-land-hdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 9cc86156e..000000000
--- a/java/res/drawable-land-hdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index 664467b3e..000000000
--- a/java/res/drawable-land-hdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_underline_holo.9.png b/java/res/drawable-land-hdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 2cb4077a7..000000000
--- a/java/res/drawable-land-hdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-hdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-land-hdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index 6b9a49170..000000000
--- a/java/res/drawable-land-hdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/hint_popup_holo.9.png b/java/res/drawable-land-mdpi/hint_popup_holo.9.png
deleted file mode 100644
index c409cea00..000000000
--- a/java/res/drawable-land-mdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_at_holo.9.png b/java/res/drawable-land-mdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 8c84654c9..000000000
--- a/java/res/drawable-land-mdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_at_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index b9e095b99..000000000
--- a/java/res/drawable-land-mdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_colon_holo.9.png b/java/res/drawable-land-mdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 3cd0e3c4b..000000000
--- a/java/res/drawable-land-mdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 01b47b25f..000000000
--- a/java/res/drawable-land-mdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_comma_holo.9.png b/java/res/drawable-land-mdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index b70f71b55..000000000
--- a/java/res/drawable-land-mdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 1ae82d404..000000000
--- a/java/res/drawable-land-mdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-land-mdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index 3409535fb..000000000
--- a/java/res/drawable-land-mdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 8dd2f27c4..000000000
--- a/java/res/drawable-land-mdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_plus_holo.9.png b/java/res/drawable-land-mdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index 51e86ba11..000000000
--- a/java/res/drawable-land-mdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index bf30f92d8..000000000
--- a/java/res/drawable-land-mdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_question_holo.9.png b/java/res/drawable-land-mdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 38b5d6102..000000000
--- a/java/res/drawable-land-mdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_question_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 448a02700..000000000
--- a/java/res/drawable-land-mdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_quote_holo.9.png b/java/res/drawable-land-mdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 92fe8eaf8..000000000
--- a/java/res/drawable-land-mdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index a777d0187..000000000
--- a/java/res/drawable-land-mdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_underline_holo.9.png b/java/res/drawable-land-mdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 7a452c5e2..000000000
--- a/java/res/drawable-land-mdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-mdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-land-mdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index f738b0202..000000000
--- a/java/res/drawable-land-mdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/hint_popup_holo.9.png b/java/res/drawable-land-xhdpi/hint_popup_holo.9.png
deleted file mode 100644
index 3cd20d34f..000000000
--- a/java/res/drawable-land-xhdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_at_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 1d257cba2..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_at_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index 53de283da..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_colon_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 73394b57b..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index a4a6acbe1..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_comma_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index d4dbdf4bf..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index aea5c8ed5..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index 078d1d8f7..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index ddd6b13cb..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_plus_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index d0ce9c948..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index 9cf20e8b1..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_question_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 1e886d897..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_question_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 826228796..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_quote_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index fd8bbad83..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index 51d5b498c..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_underline_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 37d2fa58e..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land-xhdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-land-xhdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index 4249a8edf..000000000
--- a/java/res/drawable-land-xhdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-land/btn_keyboard_key.xml b/java/res/drawable-land/btn_keyboard_key.xml
deleted file mode 100644
index 45578e582..000000000
--- a/java/res/drawable-land/btn_keyboard_key.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Toggle keys. Use checkable/checked state. -->
-
- <item android:state_checkable="true" android:state_checked="true"
- android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed_on" />
- <item android:state_checkable="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed_off" />
- <item android:state_checkable="true" android:state_checked="true"
- android:drawable="@drawable/btn_keyboard_key_normal_on" />
- <item android:state_checkable="true"
- android:drawable="@drawable/btn_keyboard_key_normal_off" />
-
- <!-- Normal keys -->
-
- <item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed" />
- <item
- android:drawable="@drawable/btn_keyboard_key_normal" />
-
-</selector>
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
index 4e337fa08..49329f094 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
index 1534d99d1..d449d7600 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
index fe18497d8..46e9db092 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index 936513a31..80fe863f5 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
index 00aab3d5a..ee60e4864 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index b071251a7..196d6d9bd 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
index ac0bfd3c1..c6876f76e 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 9fed21edf..ab0b3bed5 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
index ea2f35789..1f8f318d1 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 3fce55938..b0969a891 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
index 6195ac0d4..2bb7b64f4 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 3f82b67dd..cb49f1878 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
index 20f3d5087..4b1a78cfb 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
index 1ed3065c5..697683e29 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
index 50cd06ae3..f5ce40cf6 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
index eded1736b..976083fdf 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
index 125ff1335..ca73b9249 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
index 7ce52f0f5..73f2006d4 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
index e6a1dcecc..1de7abbd2 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png
index 7ba18dd25..12bc97928 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png
index bda9b8394..44bd414a1 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
index fad0ec458..cdd6c8b79 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png
index 0c16ed509..43fdf5b88 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
index 215f8157c..d8421746a 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
index 88acdd748..44c2ad637 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_popup_background_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_popup_background_holo.9.png
new file mode 100644
index 000000000..633aaa22b
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_popup_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
index d2f5f3bf2..7d767439a 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png
index 39b9314a1..1c1f3d711 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png
index bdcf06e1b..dacb675a9 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png
index 79621a9e6..3daa69f31 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/hint_popup.9.png b/java/res/drawable-mdpi/hint_popup.9.png
deleted file mode 100644
index 444cc26ee..000000000
--- a/java/res/drawable-mdpi/hint_popup.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/hint_popup_holo.9.png b/java/res/drawable-mdpi/hint_popup_holo.9.png
deleted file mode 100644
index 01d1139d8..000000000
--- a/java/res/drawable-mdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_at_holo.9.png b/java/res/drawable-mdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 8c84654c9..000000000
--- a/java/res/drawable-mdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_at_large_holo.9.png b/java/res/drawable-mdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index b9e095b99..000000000
--- a/java/res/drawable-mdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_colon_holo.9.png b/java/res/drawable-mdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 3cd0e3c4b..000000000
--- a/java/res/drawable-mdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-mdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 01b47b25f..000000000
--- a/java/res/drawable-mdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_comma_holo.9.png b/java/res/drawable-mdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index b70f71b55..000000000
--- a/java/res/drawable-mdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-mdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 1ae82d404..000000000
--- a/java/res/drawable-mdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-mdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index 3409535fb..000000000
--- a/java/res/drawable-mdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-mdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 8dd2f27c4..000000000
--- a/java/res/drawable-mdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num0.9.png b/java/res/drawable-mdpi/key_hint_num0.9.png
deleted file mode 100644
index 61ad1b50a..000000000
--- a/java/res/drawable-mdpi/key_hint_num0.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num0_holo.9.png b/java/res/drawable-mdpi/key_hint_num0_holo.9.png
deleted file mode 100644
index 271264e92..000000000
--- a/java/res/drawable-mdpi/key_hint_num0_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num1.9.png b/java/res/drawable-mdpi/key_hint_num1.9.png
deleted file mode 100644
index cd7772e71..000000000
--- a/java/res/drawable-mdpi/key_hint_num1.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num1_holo.9.png b/java/res/drawable-mdpi/key_hint_num1_holo.9.png
deleted file mode 100644
index eaf374262..000000000
--- a/java/res/drawable-mdpi/key_hint_num1_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num2.9.png b/java/res/drawable-mdpi/key_hint_num2.9.png
deleted file mode 100644
index fa5f8b79c..000000000
--- a/java/res/drawable-mdpi/key_hint_num2.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num2_holo.9.png b/java/res/drawable-mdpi/key_hint_num2_holo.9.png
deleted file mode 100644
index 8a1657117..000000000
--- a/java/res/drawable-mdpi/key_hint_num2_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num3.9.png b/java/res/drawable-mdpi/key_hint_num3.9.png
deleted file mode 100644
index 0c7336cb7..000000000
--- a/java/res/drawable-mdpi/key_hint_num3.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num3_holo.9.png b/java/res/drawable-mdpi/key_hint_num3_holo.9.png
deleted file mode 100644
index 34b501109..000000000
--- a/java/res/drawable-mdpi/key_hint_num3_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num4.9.png b/java/res/drawable-mdpi/key_hint_num4.9.png
deleted file mode 100644
index 73ef06c0e..000000000
--- a/java/res/drawable-mdpi/key_hint_num4.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num4_holo.9.png b/java/res/drawable-mdpi/key_hint_num4_holo.9.png
deleted file mode 100644
index d4cc250dd..000000000
--- a/java/res/drawable-mdpi/key_hint_num4_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num5.9.png b/java/res/drawable-mdpi/key_hint_num5.9.png
deleted file mode 100644
index aea460e1c..000000000
--- a/java/res/drawable-mdpi/key_hint_num5.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num5_holo.9.png b/java/res/drawable-mdpi/key_hint_num5_holo.9.png
deleted file mode 100644
index 6a054b42f..000000000
--- a/java/res/drawable-mdpi/key_hint_num5_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num6.9.png b/java/res/drawable-mdpi/key_hint_num6.9.png
deleted file mode 100644
index 16a9237e3..000000000
--- a/java/res/drawable-mdpi/key_hint_num6.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num6_holo.9.png b/java/res/drawable-mdpi/key_hint_num6_holo.9.png
deleted file mode 100644
index 66e91400a..000000000
--- a/java/res/drawable-mdpi/key_hint_num6_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num7.9.png b/java/res/drawable-mdpi/key_hint_num7.9.png
deleted file mode 100644
index 6747a19c0..000000000
--- a/java/res/drawable-mdpi/key_hint_num7.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num7_holo.9.png b/java/res/drawable-mdpi/key_hint_num7_holo.9.png
deleted file mode 100644
index 5eae24f4f..000000000
--- a/java/res/drawable-mdpi/key_hint_num7_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num8.9.png b/java/res/drawable-mdpi/key_hint_num8.9.png
deleted file mode 100644
index 28be2fb86..000000000
--- a/java/res/drawable-mdpi/key_hint_num8.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num8_holo.9.png b/java/res/drawable-mdpi/key_hint_num8_holo.9.png
deleted file mode 100644
index ea7f512fd..000000000
--- a/java/res/drawable-mdpi/key_hint_num8_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num9.9.png b/java/res/drawable-mdpi/key_hint_num9.9.png
deleted file mode 100644
index 731d63b1b..000000000
--- a/java/res/drawable-mdpi/key_hint_num9.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_num9_holo.9.png b/java/res/drawable-mdpi/key_hint_num9_holo.9.png
deleted file mode 100644
index 0bf85de93..000000000
--- a/java/res/drawable-mdpi/key_hint_num9_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_plus_holo.9.png b/java/res/drawable-mdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index 51e86ba11..000000000
--- a/java/res/drawable-mdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-mdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index bf30f92d8..000000000
--- a/java/res/drawable-mdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_question_holo.9.png b/java/res/drawable-mdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 38b5d6102..000000000
--- a/java/res/drawable-mdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_question_large_holo.9.png b/java/res/drawable-mdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 448a02700..000000000
--- a/java/res/drawable-mdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_quote_holo.9.png b/java/res/drawable-mdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 92fe8eaf8..000000000
--- a/java/res/drawable-mdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-mdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index a777d0187..000000000
--- a/java/res/drawable-mdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_underline_holo.9.png b/java/res/drawable-mdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 7a452c5e2..000000000
--- a/java/res/drawable-mdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-mdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index f738b0202..000000000
--- a/java/res/drawable-mdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_background_holo.9.png b/java/res/drawable-mdpi/keyboard_background_holo.9.png
index a93966c92..f1d55c6dd 100644
--- a/java/res/drawable-mdpi/keyboard_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
index 3d6a76f66..cc7dd86aa 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
new file mode 100644
index 000000000..0df04cf2a
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
new file mode 100644
index 000000000..6bde3e98f
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
index e3f5be86d..3d5b788d5 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
new file mode 100644
index 000000000..a1916875a
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
new file mode 100644
index 000000000..02e84d711
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-mdpi/keyboard_suggest_strip_holo.9.png
index 1f87a68e9..e488323c9 100644
--- a/java/res/drawable-mdpi/keyboard_suggest_strip_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_suggest_strip_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_delete_rtl.png b/java/res/drawable-mdpi/sym_bkeyboard_delete_rtl.png
new file mode 100644
index 000000000..32253ea9b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_bkeyboard_delete_rtl.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num0.png b/java/res/drawable-mdpi/sym_bkeyboard_num0.png
deleted file mode 100644
index 7188f9ca5..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num0.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num1.png b/java/res/drawable-mdpi/sym_bkeyboard_num1.png
deleted file mode 100644
index 2a31bd458..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num1.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num2.png b/java/res/drawable-mdpi/sym_bkeyboard_num2.png
deleted file mode 100644
index c1e9cc9b1..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num2.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num3.png b/java/res/drawable-mdpi/sym_bkeyboard_num3.png
deleted file mode 100644
index e9987668c..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num3.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num4.png b/java/res/drawable-mdpi/sym_bkeyboard_num4.png
deleted file mode 100644
index 7f0f3cccc..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num4.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num5.png b/java/res/drawable-mdpi/sym_bkeyboard_num5.png
deleted file mode 100644
index 5f748b416..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num5.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num6.png b/java/res/drawable-mdpi/sym_bkeyboard_num6.png
deleted file mode 100644
index 78aae74a0..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num6.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num7.png b/java/res/drawable-mdpi/sym_bkeyboard_num7.png
deleted file mode 100644
index 5bb874c47..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num7.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num8.png b/java/res/drawable-mdpi/sym_bkeyboard_num8.png
deleted file mode 100644
index 6b58fdc8a..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num8.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_num9.png b/java/res/drawable-mdpi/sym_bkeyboard_num9.png
deleted file mode 100644
index f348c92af..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_num9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_numalt.png b/java/res/drawable-mdpi/sym_bkeyboard_numalt.png
deleted file mode 100644
index 4fa410b62..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_numalt.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_numpound.png b/java/res/drawable-mdpi/sym_bkeyboard_numpound.png
deleted file mode 100644
index 9126eed0d..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_numpound.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_numstar.png b/java/res/drawable-mdpi/sym_bkeyboard_numstar.png
deleted file mode 100644
index 9b9f1b986..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_numstar.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_123_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_123_mic_holo.png
new file mode 100644
index 000000000..546cce279
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_123_mic_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
index 155579169..bc3393feb 100644
--- a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_rtl.png b/java/res/drawable-mdpi/sym_keyboard_delete_rtl.png
new file mode 100644
index 000000000..d436c23a9
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_delete_rtl.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_rtl_holo.png b/java/res/drawable-mdpi/sym_keyboard_delete_rtl_holo.png
new file mode 100644
index 000000000..2e75d8536
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_delete_rtl_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png b/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png
deleted file mode 100644
index c556c35cb..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png
deleted file mode 100644
index a79f15852..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png
deleted file mode 100644
index eecb02694..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_left.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png b/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png
deleted file mode 100644
index 7e10ae3af..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_language_arrows_right.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png b/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png
deleted file mode 100644
index bc8f1cfc3..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_numalt.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_return.png b/java/res/drawable-mdpi/sym_keyboard_feedback_return.png
deleted file mode 100644
index dd99ff381..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_search.png b/java/res/drawable-mdpi/sym_keyboard_feedback_search.png
deleted file mode 100644
index 6b8e01d90..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png b/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png
deleted file mode 100644
index d56357559..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_feedback_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png b/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png
deleted file mode 100644
index 7067a8bf5..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_language_arrows_left.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png b/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png
deleted file mode 100644
index f7a133d9e..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_language_arrows_right.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num0.png b/java/res/drawable-mdpi/sym_keyboard_num0.png
deleted file mode 100644
index e7007c871..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num0.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num0_holo.png b/java/res/drawable-mdpi/sym_keyboard_num0_holo.png
deleted file mode 100644
index e1d395b45..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num0_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num1.png b/java/res/drawable-mdpi/sym_keyboard_num1.png
deleted file mode 100644
index aaac11b0c..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num1.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num1_holo.png b/java/res/drawable-mdpi/sym_keyboard_num1_holo.png
deleted file mode 100644
index 225436ac2..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num1_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num2.png b/java/res/drawable-mdpi/sym_keyboard_num2.png
deleted file mode 100644
index 4372eb8f0..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num2.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num2_holo.png b/java/res/drawable-mdpi/sym_keyboard_num2_holo.png
deleted file mode 100644
index e513fa4a0..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num2_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num3.png b/java/res/drawable-mdpi/sym_keyboard_num3.png
deleted file mode 100644
index 6f54c850f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num3.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num3_holo.png b/java/res/drawable-mdpi/sym_keyboard_num3_holo.png
deleted file mode 100644
index b91e005fc..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num3_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num4.png b/java/res/drawable-mdpi/sym_keyboard_num4.png
deleted file mode 100644
index 3e50bb957..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num4.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num4_holo.png b/java/res/drawable-mdpi/sym_keyboard_num4_holo.png
deleted file mode 100644
index 65f88245b..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num4_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num5.png b/java/res/drawable-mdpi/sym_keyboard_num5.png
deleted file mode 100644
index c39ef4404..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num5.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num5_holo.png b/java/res/drawable-mdpi/sym_keyboard_num5_holo.png
deleted file mode 100644
index b89ef07eb..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num5_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num6.png b/java/res/drawable-mdpi/sym_keyboard_num6.png
deleted file mode 100644
index ea88ceb94..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num6.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num6_holo.png b/java/res/drawable-mdpi/sym_keyboard_num6_holo.png
deleted file mode 100644
index 931275a9e..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num6_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num7.png b/java/res/drawable-mdpi/sym_keyboard_num7.png
deleted file mode 100644
index ce800ba42..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num7.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num7_holo.png b/java/res/drawable-mdpi/sym_keyboard_num7_holo.png
deleted file mode 100644
index 9396c4c8f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num7_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num8.png b/java/res/drawable-mdpi/sym_keyboard_num8.png
deleted file mode 100644
index 1a8ff94bf..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num8.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num8_holo.png b/java/res/drawable-mdpi/sym_keyboard_num8_holo.png
deleted file mode 100644
index 12e3eef45..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num8_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num9.png b/java/res/drawable-mdpi/sym_keyboard_num9.png
deleted file mode 100644
index 8b344c0a6..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_num9_holo.png b/java/res/drawable-mdpi/sym_keyboard_num9_holo.png
deleted file mode 100644
index 6911c2b4f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_num9_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numalt.png b/java/res/drawable-mdpi/sym_keyboard_numalt.png
deleted file mode 100644
index 32a2cf3ca..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_numalt.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numbpound_holo.png b/java/res/drawable-mdpi/sym_keyboard_numbpound_holo.png
deleted file mode 100644
index e3a8b4900..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_numbpound_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numbstar_holo.png b/java/res/drawable-mdpi/sym_keyboard_numbstar_holo.png
deleted file mode 100644
index e80e9345f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_numbstar_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numpound.png b/java/res/drawable-mdpi/sym_keyboard_numpound.png
deleted file mode 100644
index b2419d9ab..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_numpound.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_numstar.png b/java/res/drawable-mdpi/sym_keyboard_numstar.png
deleted file mode 100644
index cb66f968f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_numstar.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-mdpi/sym_keyboard_return_holo.png
index d519ccecf..c0a16dfd6 100644
--- a/java/res/drawable-mdpi/sym_keyboard_return_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-mdpi/sym_keyboard_search_holo.png
new file mode 100644
index 000000000..423dff7f5
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_search_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
index 784a45054..7ac90d0f5 100644
--- a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
index 91d6e32f9..2d79663d2 100644
--- a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
index 2bd053656..05252e53b 100644
--- a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-mdpi/sym_keyboard_space_holo.png
index 25e655d96..d4cbdcf38 100644
--- a/java/res/drawable-mdpi/sym_keyboard_space_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_space_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.png b/java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.png
new file mode 100644
index 000000000..abd8b742e
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo.png
new file mode 100644
index 000000000..e42432125
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_tab_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
index c1116dc17..dc5a9dd37 100644
--- a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
index 081a13096..527e832a6 100644
--- a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-sw600dp-hdpi/btn_keyboard_key_popup_selected_holo.9.png
deleted file mode 100644
index 544ed7f78..000000000
--- a/java/res/drawable-sw600dp-hdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/hint_popup_holo.9.png b/java/res/drawable-sw600dp-hdpi/hint_popup_holo.9.png
deleted file mode 100644
index 2ffc6ea2b..000000000
--- a/java/res/drawable-sw600dp-hdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_background_holo.9.png
deleted file mode 100644
index 39219a583..000000000
--- a/java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_more_background_holo.9.png
deleted file mode 100644
index e5cc5b7e2..000000000
--- a/java/res/drawable-sw600dp-hdpi/keyboard_key_feedback_more_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_holo.png
new file mode 100644
index 000000000..223fcfb3a
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_rtl_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_rtl_holo.png
new file mode 100644
index 000000000..5c19f3258
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_delete_rtl_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_numsymbol_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_numsymbol_holo.png
deleted file mode 100644
index 398eaea12..000000000
--- a/java/res/drawable-sw600dp-hdpi/sym_keyboard_numsymbol_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_return_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_return_holo.png
new file mode 100644
index 000000000..c9d3d749b
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_search_holo.png
new file mode 100644
index 000000000..5ed614a59
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_search_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_settings_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_settings_holo.png
new file mode 100644
index 000000000..00168b272
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_settings_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_holo.png
new file mode 100644
index 000000000..980547e37
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_locked_holo.png
new file mode 100644
index 000000000..868eec332
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_shift_locked_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_smiley_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_smiley_holo.png
new file mode 100644
index 000000000..27d2b7d1b
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_smiley_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_space_holo.png
new file mode 100644
index 000000000..d89bddae9
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_space_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_tab_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_tab_holo.png
index 1780f682b..e11d854e4 100644
--- a/java/res/drawable-sw600dp-hdpi/sym_keyboard_tab_holo.png
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_tab_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_holo.png
new file mode 100644
index 000000000..0eb4aa244
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_off_holo.png
new file mode 100644
index 000000000..b53456a99
--- /dev/null
+++ b/java/res/drawable-sw600dp-hdpi/sym_keyboard_voice_off_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-land-hdpi/hint_popup_holo.9.png b/java/res/drawable-sw600dp-land-hdpi/hint_popup_holo.9.png
deleted file mode 100644
index 2ffc6ea2b..000000000
--- a/java/res/drawable-sw600dp-land-hdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-land-mdpi/hint_popup_holo.9.png b/java/res/drawable-sw600dp-land-mdpi/hint_popup_holo.9.png
deleted file mode 100644
index f5d15b728..000000000
--- a/java/res/drawable-sw600dp-land-mdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-land-xhdpi/hint_popup_holo.9.png b/java/res/drawable-sw600dp-land-xhdpi/hint_popup_holo.9.png
deleted file mode 100644
index bc37fa844..000000000
--- a/java/res/drawable-sw600dp-land-xhdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_holo.9.png
deleted file mode 100644
index 2ad73041e..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
deleted file mode 100644
index fc21e79c4..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
deleted file mode 100644
index 76cfbb221..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
deleted file mode 100644
index 73748c2fb..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
deleted file mode 100644
index 059d4ac2e..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
deleted file mode 100644
index e5cfdec88..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_normal_holo.9.png
deleted file mode 100644
index 060524a53..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_pressed_holo.9.png
deleted file mode 100644
index f4b061e07..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_popup_selected_holo.9.png
deleted file mode 100644
index ffa7386df..000000000
--- a/java/res/drawable-sw600dp-mdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/hint_popup_holo.9.png b/java/res/drawable-sw600dp-mdpi/hint_popup_holo.9.png
deleted file mode 100644
index f5d15b728..000000000
--- a/java/res/drawable-sw600dp-mdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_at_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 8c84654c9..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_at_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index b9e095b99..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_colon_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 3cd0e3c4b..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 01b47b25f..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_comma_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index b70f71b55..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 1ae82d404..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index 3409535fb..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 8dd2f27c4..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_plus_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index 51e86ba11..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index bf30f92d8..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_question_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 38b5d6102..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_question_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 448a02700..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_quote_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 92fe8eaf8..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index a777d0187..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_underline_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 7a452c5e2..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-sw600dp-mdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index f738b0202..000000000
--- a/java/res/drawable-sw600dp-mdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/keyboard_background_holo.9.png b/java/res/drawable-sw600dp-mdpi/keyboard_background_holo.9.png
deleted file mode 100644
index a93966c92..000000000
--- a/java/res/drawable-sw600dp-mdpi/keyboard_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_background_holo.9.png
deleted file mode 100644
index 5f152175d..000000000
--- a/java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_more_background_holo.9.png
deleted file mode 100644
index 77a806c1e..000000000
--- a/java/res/drawable-sw600dp-mdpi/keyboard_key_feedback_more_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-sw600dp-mdpi/keyboard_popup_panel_background_holo.9.png
deleted file mode 100644
index 7be7ab7e2..000000000
--- a/java/res/drawable-sw600dp-mdpi/keyboard_popup_panel_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-sw600dp-mdpi/keyboard_suggest_strip_holo.9.png
deleted file mode 100644
index 1f87a68e9..000000000
--- a/java/res/drawable-sw600dp-mdpi/keyboard_suggest_strip_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_holo.png
index 155579169..66111eefa 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_rtl_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_rtl_holo.png
new file mode 100644
index 000000000..994854106
--- /dev/null
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_delete_rtl_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num0_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num0_holo.png
deleted file mode 100644
index e1d395b45..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num0_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num1_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num1_holo.png
deleted file mode 100644
index 225436ac2..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num1_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num2_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num2_holo.png
deleted file mode 100644
index e513fa4a0..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num2_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num3_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num3_holo.png
deleted file mode 100644
index b91e005fc..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num3_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num4_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num4_holo.png
deleted file mode 100644
index 65f88245b..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num4_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num5_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num5_holo.png
deleted file mode 100644
index b89ef07eb..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num5_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num6_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num6_holo.png
deleted file mode 100644
index 931275a9e..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num6_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num7_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num7_holo.png
deleted file mode 100644
index 9396c4c8f..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num7_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num8_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num8_holo.png
deleted file mode 100644
index 12e3eef45..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num8_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num9_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_num9_holo.png
deleted file mode 100644
index 6911c2b4f..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_num9_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_numbpound_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_numbpound_holo.png
deleted file mode 100644
index e3a8b4900..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_numbpound_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_numbstar_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_numbstar_holo.png
deleted file mode 100644
index e80e9345f..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_numbstar_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_numsymbol_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_numsymbol_holo.png
deleted file mode 100644
index 73153849c..000000000
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_numsymbol_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_return_holo.png
index d519ccecf..5420161b7 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_return_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_search_holo.png
new file mode 100644
index 000000000..182133727
--- /dev/null
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_search_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_settings_holo.png
index 784a45054..3c8166682 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_settings_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_settings_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_holo.png
index 91d6e32f9..6e3d718b2 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_locked_holo.png
index 2bd053656..ea2f0e967 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_locked_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_shift_locked_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_smiley_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_smiley_holo.png
new file mode 100644
index 000000000..9c08b5a17
--- /dev/null
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_smiley_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_space_holo.png
index 25e655d96..dac90bb87 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_space_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_space_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_tab_holo.png
index 5acd12cc4..79f3735ef 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_tab_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_tab_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_holo.png
index c1116dc17..b1678f03e 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_off_holo.png
index 081a13096..58142fa6d 100644
--- a/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_off_holo.png
+++ b/java/res/drawable-sw600dp-mdpi/sym_keyboard_voice_off_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-sw600dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
deleted file mode 100644
index 8b5d1b098..000000000
--- a/java/res/drawable-sw600dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/hint_popup_holo.9.png b/java/res/drawable-sw600dp-xhdpi/hint_popup_holo.9.png
deleted file mode 100644
index bc37fa844..000000000
--- a/java/res/drawable-sw600dp-xhdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_background_holo.9.png
deleted file mode 100644
index 8d43a4bdb..000000000
--- a/java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_more_background_holo.9.png
deleted file mode 100644
index e973c7e6a..000000000
--- a/java/res/drawable-sw600dp-xhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_holo.png
new file mode 100644
index 000000000..df64bbe9b
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_rtl_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_rtl_holo.png
new file mode 100644
index 000000000..f3310a1cd
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_delete_rtl_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_numsymbol_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_numsymbol_holo.png
deleted file mode 100644
index c7a8b286a..000000000
--- a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_numsymbol_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_return_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_return_holo.png
new file mode 100644
index 000000000..13f78c480
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_search_holo.png
new file mode 100644
index 000000000..7e0f1ae07
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_search_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_settings_holo.png
new file mode 100644
index 000000000..8c1395edf
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_settings_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_holo.png
new file mode 100644
index 000000000..a4068eae4
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_locked_holo.png
new file mode 100644
index 000000000..4cb37cdfc
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_shift_locked_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_smiley_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_smiley_holo.png
new file mode 100644
index 000000000..481d889ab
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_smiley_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_space_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_space_holo.png
new file mode 100644
index 000000000..4bfbf6651
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_space_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_tab_holo.png
index fd9f8cce6..1ea57c5cb 100644
--- a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_tab_holo.png
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_tab_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_holo.png
new file mode 100644
index 000000000..597be7d92
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_holo.png
Binary files differ
diff --git a/java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_off_holo.png
new file mode 100644
index 000000000..58fd48b4a
--- /dev/null
+++ b/java/res/drawable-sw600dp-xhdpi/sym_keyboard_voice_off_holo.png
Binary files differ
diff --git a/java/res/drawable-sw768dp-hdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-sw768dp-hdpi/btn_keyboard_key_popup_selected_holo.9.png
deleted file mode 100644
index 544ed7f78..000000000
--- a/java/res/drawable-sw768dp-hdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-hdpi/hint_popup_holo.9.png b/java/res/drawable-sw768dp-hdpi/hint_popup_holo.9.png
deleted file mode 100644
index 2ffc6ea2b..000000000
--- a/java/res/drawable-sw768dp-hdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_background_holo.9.png
deleted file mode 100644
index 099a50873..000000000
--- a/java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_more_background_holo.9.png
deleted file mode 100644
index c21240f17..000000000
--- a/java/res/drawable-sw768dp-hdpi/keyboard_key_feedback_more_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-hdpi/hint_popup_holo.9.png b/java/res/drawable-sw768dp-land-hdpi/hint_popup_holo.9.png
deleted file mode 100644
index 2b93014e1..000000000
--- a/java/res/drawable-sw768dp-land-hdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/hint_popup_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/hint_popup_holo.9.png
deleted file mode 100644
index c409cea00..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_at_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 5b946ff9b..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_at_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index 852f899ed..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_colon_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 1d9346e6f..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 17e9091b4..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_comma_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index c2a913c04..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 846f213f1..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index ce8e8de43..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 035dcf85d..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_plus_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index 931390b45..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index e6f9f8a9c..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_question_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 6cbeb5993..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_question_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index bfd58de09..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_quote_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 3b361b71c..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index 2a08aa12e..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_underline_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 06f3efb7e..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-mdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-sw768dp-land-mdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index 50f99a191..000000000
--- a/java/res/drawable-sw768dp-land-mdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-land-xhdpi/hint_popup_holo.9.png b/java/res/drawable-sw768dp-land-xhdpi/hint_popup_holo.9.png
deleted file mode 100644
index 3cd20d34f..000000000
--- a/java/res/drawable-sw768dp-land-xhdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_holo.9.png
deleted file mode 100644
index 2ad73041e..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
deleted file mode 100644
index fc21e79c4..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
deleted file mode 100644
index 76cfbb221..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
deleted file mode 100644
index 73748c2fb..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
deleted file mode 100644
index 059d4ac2e..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
deleted file mode 100644
index e5cfdec88..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_normal_holo.9.png
deleted file mode 100644
index 060524a53..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_pressed_holo.9.png
deleted file mode 100644
index f4b061e07..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_popup_selected_holo.9.png
deleted file mode 100644
index ffa7386df..000000000
--- a/java/res/drawable-sw768dp-mdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/hint_popup_holo.9.png b/java/res/drawable-sw768dp-mdpi/hint_popup_holo.9.png
deleted file mode 100644
index 01d1139d8..000000000
--- a/java/res/drawable-sw768dp-mdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_at_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 8c84654c9..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_at_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index b9e095b99..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_colon_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 3cd0e3c4b..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index 01b47b25f..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_comma_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index b70f71b55..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index 1ae82d404..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index 3409535fb..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index 8dd2f27c4..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_plus_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index 51e86ba11..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index bf30f92d8..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_question_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 38b5d6102..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_question_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 448a02700..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_quote_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index 92fe8eaf8..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index a777d0187..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_underline_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 7a452c5e2..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-sw768dp-mdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index f738b0202..000000000
--- a/java/res/drawable-sw768dp-mdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/keyboard_background_holo.9.png b/java/res/drawable-sw768dp-mdpi/keyboard_background_holo.9.png
deleted file mode 100644
index a93966c92..000000000
--- a/java/res/drawable-sw768dp-mdpi/keyboard_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_background_holo.9.png
deleted file mode 100644
index 286cf84fc..000000000
--- a/java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_more_background_holo.9.png
deleted file mode 100644
index e3f5be86d..000000000
--- a/java/res/drawable-sw768dp-mdpi/keyboard_key_feedback_more_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-sw768dp-mdpi/keyboard_popup_panel_background_holo.9.png
deleted file mode 100644
index 7be7ab7e2..000000000
--- a/java/res/drawable-sw768dp-mdpi/keyboard_popup_panel_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-sw768dp-mdpi/keyboard_suggest_strip_holo.9.png
deleted file mode 100644
index 1f87a68e9..000000000
--- a/java/res/drawable-sw768dp-mdpi/keyboard_suggest_strip_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index 155579169..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num0_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num0_holo.png
deleted file mode 100644
index e1d395b45..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num0_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num1_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num1_holo.png
deleted file mode 100644
index 225436ac2..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num1_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num2_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num2_holo.png
deleted file mode 100644
index e513fa4a0..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num2_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num3_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num3_holo.png
deleted file mode 100644
index b91e005fc..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num3_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num4_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num4_holo.png
deleted file mode 100644
index 65f88245b..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num4_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num5_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num5_holo.png
deleted file mode 100644
index b89ef07eb..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num5_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num6_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num6_holo.png
deleted file mode 100644
index 931275a9e..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num6_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num7_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num7_holo.png
deleted file mode 100644
index 9396c4c8f..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num7_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num8_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num8_holo.png
deleted file mode 100644
index 12e3eef45..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num8_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num9_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_num9_holo.png
deleted file mode 100644
index 6911c2b4f..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_num9_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_numbpound_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_numbpound_holo.png
deleted file mode 100644
index e3a8b4900..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_numbpound_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_numbstar_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_numbstar_holo.png
deleted file mode 100644
index e80e9345f..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_numbstar_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index d519ccecf..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 784a45054..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 91d6e32f9..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 2bd053656..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 25e655d96..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 5acd12cc4..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index c1116dc17..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index 081a13096..000000000
--- a/java/res/drawable-sw768dp-mdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-sw768dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
deleted file mode 100644
index 8b5d1b098..000000000
--- a/java/res/drawable-sw768dp-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-xhdpi/hint_popup_holo.9.png b/java/res/drawable-sw768dp-xhdpi/hint_popup_holo.9.png
deleted file mode 100644
index bc37fa844..000000000
--- a/java/res/drawable-sw768dp-xhdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_background_holo.9.png
deleted file mode 100644
index 38c84e81b..000000000
--- a/java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_more_background_holo.9.png
deleted file mode 100644
index f66e54538..000000000
--- a/java/res/drawable-sw768dp-xhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_candidate_pressed.9.png b/java/res/drawable-xhdpi/btn_candidate_pressed.9.png
new file mode 100644
index 000000000..41e126a73
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_candidate_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_center_default.9.png b/java/res/drawable-xhdpi/btn_center_default.9.png
new file mode 100644
index 000000000..e847425f8
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_center_default.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_center_pressed.9.png b/java/res/drawable-xhdpi/btn_center_pressed.9.png
new file mode 100644
index 000000000..facfd4323
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_center_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_center_selected.9.png b/java/res/drawable-xhdpi/btn_center_selected.9.png
new file mode 100644
index 000000000..facfd4323
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_center_selected.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png
index eae1e3a54..d0090a305 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
index 3e4a81247..d2cd029bb 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png
index 13bad8f1a..2baf7d90c 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index d61dd2b88..0f709eb02 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png
index 853b8bc6e..6812f9e8f 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index c127e2ad0..2f4de8ee7 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png
index 1edfd64fe..a932249a8 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
index ac3f3581b..aefb21bb3 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png
index dfdbfadd3..16416f000 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index e5de3b0a2..b49ba10bd 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png
index 0e2733e17..3ca93fdb3 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index c63b69a6c..e9c73878c 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 000000000..f7e32f764
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 000000000..df3b5ba2d
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png
index ea13a7fdf..aa4f44fdd 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
index e1361edf2..b26f1d27a 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png
index 057c5716e..4539255c2 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png
index 5d8e46de0..568392444 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
index 6efd3a759..b6ab8150b 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png
new file mode 100644
index 000000000..026005d6f
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png
new file mode 100644
index 000000000..38c5f244b
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png
new file mode 100644
index 000000000..dec219304
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png
new file mode 100644
index 000000000..f1223e50e
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png
new file mode 100644
index 000000000..3c77b3ccd
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png
new file mode 100644
index 000000000..099472889
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_popup_background_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_popup_background_holo.9.png
new file mode 100644
index 000000000..45401af34
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_popup_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
index 3ed9b1e7c..47eee3296 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png
new file mode 100644
index 000000000..ec35db54d
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png
new file mode 100644
index 000000000..bd30464d6
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png
new file mode 100644
index 000000000..a3ff5d1bb
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/candidate_feedback_background.9.png b/java/res/drawable-xhdpi/candidate_feedback_background.9.png
new file mode 100644
index 000000000..0ec90e5ea
--- /dev/null
+++ b/java/res/drawable-xhdpi/candidate_feedback_background.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/caution.png b/java/res/drawable-xhdpi/caution.png
new file mode 100644
index 000000000..cfc3f7547
--- /dev/null
+++ b/java/res/drawable-xhdpi/caution.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/hint_popup_holo.9.png b/java/res/drawable-xhdpi/hint_popup_holo.9.png
deleted file mode 100644
index bc37fa844..000000000
--- a/java/res/drawable-xhdpi/hint_popup_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_dialog_keyboard.png b/java/res/drawable-xhdpi/ic_dialog_keyboard.png
new file mode 100644
index 000000000..f114c93b6
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_dialog_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_mic_dialog.png b/java/res/drawable-xhdpi/ic_mic_dialog.png
new file mode 100644
index 000000000..5d6399c0a
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_mic_dialog.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_subtype_keyboard.png b/java/res/drawable-xhdpi/ic_subtype_keyboard.png
new file mode 100644
index 000000000..a79bb3458
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_subtype_keyboard.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_subtype_mic.png b/java/res/drawable-xhdpi/ic_subtype_mic.png
new file mode 100644
index 000000000..fc8d18cc2
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_subtype_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_suggest_strip_microphone.png b/java/res/drawable-xhdpi/ic_suggest_strip_microphone.png
new file mode 100644
index 000000000..d65d28708
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_suggest_strip_microphone.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_suggest_strip_microphone_swipe.png b/java/res/drawable-xhdpi/ic_suggest_strip_microphone_swipe.png
new file mode 100644
index 000000000..889378a6a
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_suggest_strip_microphone_swipe.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_at_holo.9.png b/java/res/drawable-xhdpi/key_hint_at_holo.9.png
deleted file mode 100644
index 1d257cba2..000000000
--- a/java/res/drawable-xhdpi/key_hint_at_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_at_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_at_large_holo.9.png
deleted file mode 100644
index 53de283da..000000000
--- a/java/res/drawable-xhdpi/key_hint_at_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_colon_holo.9.png b/java/res/drawable-xhdpi/key_hint_colon_holo.9.png
deleted file mode 100644
index 73394b57b..000000000
--- a/java/res/drawable-xhdpi/key_hint_colon_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_colon_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_colon_large_holo.9.png
deleted file mode 100644
index a4a6acbe1..000000000
--- a/java/res/drawable-xhdpi/key_hint_colon_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_comma_holo.9.png b/java/res/drawable-xhdpi/key_hint_comma_holo.9.png
deleted file mode 100644
index d4dbdf4bf..000000000
--- a/java/res/drawable-xhdpi/key_hint_comma_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_comma_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_comma_large_holo.9.png
deleted file mode 100644
index aea5c8ed5..000000000
--- a/java/res/drawable-xhdpi/key_hint_comma_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_exclamation_holo.9.png b/java/res/drawable-xhdpi/key_hint_exclamation_holo.9.png
deleted file mode 100644
index 078d1d8f7..000000000
--- a/java/res/drawable-xhdpi/key_hint_exclamation_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_exclamation_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_exclamation_large_holo.9.png
deleted file mode 100644
index ddd6b13cb..000000000
--- a/java/res/drawable-xhdpi/key_hint_exclamation_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_plus_holo.9.png b/java/res/drawable-xhdpi/key_hint_plus_holo.9.png
deleted file mode 100644
index d0ce9c948..000000000
--- a/java/res/drawable-xhdpi/key_hint_plus_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_plus_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_plus_large_holo.9.png
deleted file mode 100644
index 9cf20e8b1..000000000
--- a/java/res/drawable-xhdpi/key_hint_plus_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_question_holo.9.png b/java/res/drawable-xhdpi/key_hint_question_holo.9.png
deleted file mode 100644
index 1e886d897..000000000
--- a/java/res/drawable-xhdpi/key_hint_question_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_question_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_question_large_holo.9.png
deleted file mode 100644
index 826228796..000000000
--- a/java/res/drawable-xhdpi/key_hint_question_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_quote_holo.9.png b/java/res/drawable-xhdpi/key_hint_quote_holo.9.png
deleted file mode 100644
index fd8bbad83..000000000
--- a/java/res/drawable-xhdpi/key_hint_quote_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_quote_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_quote_large_holo.9.png
deleted file mode 100644
index 51d5b498c..000000000
--- a/java/res/drawable-xhdpi/key_hint_quote_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_underline_holo.9.png b/java/res/drawable-xhdpi/key_hint_underline_holo.9.png
deleted file mode 100644
index 37d2fa58e..000000000
--- a/java/res/drawable-xhdpi/key_hint_underline_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/key_hint_underline_large_holo.9.png b/java/res/drawable-xhdpi/key_hint_underline_large_holo.9.png
deleted file mode 100644
index 4249a8edf..000000000
--- a/java/res/drawable-xhdpi/key_hint_underline_large_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_background.9.png b/java/res/drawable-xhdpi/keyboard_background.9.png
new file mode 100644
index 000000000..263996322
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_background.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_background_holo.9.png
new file mode 100644
index 000000000..58d15142b
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_dark_background.9.png b/java/res/drawable-xhdpi/keyboard_dark_background.9.png
new file mode 100644
index 000000000..27b7a108c
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_dark_background.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
index 943f9e4bc..ba2835960 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
new file mode 100644
index 000000000..4929780ff
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
new file mode 100644
index 000000000..8676746c7
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
index f66e54538..ab9ba45c2 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
new file mode 100644
index 000000000..a46979def
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
new file mode 100644
index 000000000..63a5f459e
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_popup_panel_background.9.png b/java/res/drawable-xhdpi/keyboard_popup_panel_background.9.png
new file mode 100644
index 000000000..79f7ab00a
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_popup_panel_background.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png b/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png
new file mode 100644
index 000000000..1b568df03
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-xhdpi/keyboard_suggest_strip_holo.9.png
new file mode 100644
index 000000000..b40f76662
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_suggest_strip_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/mic_base.png b/java/res/drawable-xhdpi/mic_base.png
new file mode 100644
index 000000000..5c060bec9
--- /dev/null
+++ b/java/res/drawable-xhdpi/mic_base.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/mic_full.png b/java/res/drawable-xhdpi/mic_full.png
new file mode 100644
index 000000000..32ffe124e
--- /dev/null
+++ b/java/res/drawable-xhdpi/mic_full.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/mic_slash.png b/java/res/drawable-xhdpi/mic_slash.png
new file mode 100644
index 000000000..18b22542b
--- /dev/null
+++ b/java/res/drawable-xhdpi/mic_slash.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_123_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_123_mic.png
new file mode 100644
index 000000000..0aefaa1c3
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_123_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_delete.png b/java/res/drawable-xhdpi/sym_bkeyboard_delete.png
new file mode 100644
index 000000000..b84ee76dc
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_delete.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_delete_rtl.png b/java/res/drawable-xhdpi/sym_bkeyboard_delete_rtl.png
new file mode 100644
index 000000000..23aee2b3b
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_delete_rtl.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_mic.png
new file mode 100644
index 000000000..8c3f11dd4
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_return.png b/java/res/drawable-xhdpi/sym_bkeyboard_return.png
new file mode 100644
index 000000000..1632ecd8e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_return.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_search.png b/java/res/drawable-xhdpi/sym_bkeyboard_search.png
new file mode 100644
index 000000000..69d8b22d1
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_search.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_settings.png b/java/res/drawable-xhdpi/sym_bkeyboard_settings.png
new file mode 100644
index 000000000..050154a3a
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_settings.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_shift.png b/java/res/drawable-xhdpi/sym_bkeyboard_shift.png
new file mode 100644
index 000000000..d15d11a50
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_shift.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png
new file mode 100644
index 000000000..83b287fea
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_space.png b/java/res/drawable-xhdpi/sym_bkeyboard_space.png
new file mode 100644
index 000000000..5ca62c7b7
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_space.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_tab.png b/java/res/drawable-xhdpi/sym_bkeyboard_tab.png
new file mode 100644
index 000000000..6ca199755
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_tab.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png
new file mode 100644
index 000000000..fc6a4eb59
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_123_mic.png b/java/res/drawable-xhdpi/sym_keyboard_123_mic.png
new file mode 100644
index 000000000..bcb097967
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_123_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.png
new file mode 100644
index 000000000..9306903ee
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete.png b/java/res/drawable-xhdpi/sym_keyboard_delete.png
new file mode 100644
index 000000000..3c0b8b186
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png
new file mode 100644
index 000000000..53479ab85
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_rtl.png b/java/res/drawable-xhdpi/sym_keyboard_delete_rtl.png
new file mode 100644
index 000000000..3f9d3dd65
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete_rtl.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_rtl_holo.png b/java/res/drawable-xhdpi/sym_keyboard_delete_rtl_holo.png
new file mode 100644
index 000000000..1f4890c89
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete_rtl_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_feedback_mic.png b/java/res/drawable-xhdpi/sym_keyboard_feedback_mic.png
new file mode 100644
index 000000000..5ac27ebad
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_feedback_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_feedback_settings.png b/java/res/drawable-xhdpi/sym_keyboard_feedback_settings.png
new file mode 100644
index 000000000..021cafacb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_feedback_settings.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_feedback_space.png b/java/res/drawable-xhdpi/sym_keyboard_feedback_space.png
new file mode 100644
index 000000000..cee10568d
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_feedback_tab.png b/java/res/drawable-xhdpi/sym_keyboard_feedback_tab.png
new file mode 100644
index 000000000..0650e01cb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_feedback_tab.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic.png b/java/res/drawable-xhdpi/sym_keyboard_mic.png
new file mode 100644
index 000000000..1323b6d1e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return.png b/java/res/drawable-xhdpi/sym_keyboard_return.png
new file mode 100644
index 000000000..ad061227e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_return.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo.png
new file mode 100644
index 000000000..6b0021d42
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search.png b/java/res/drawable-xhdpi/sym_keyboard_search.png
new file mode 100644
index 000000000..aa785a221
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_search.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png
new file mode 100644
index 000000000..118f4f9aa
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings.png b/java/res/drawable-xhdpi/sym_keyboard_settings.png
new file mode 100644
index 000000000..50704255d
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_settings.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png
new file mode 100644
index 000000000..16a8aea32
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift.png b/java/res/drawable-xhdpi/sym_keyboard_shift.png
new file mode 100644
index 000000000..290170619
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png
new file mode 100644
index 000000000..b88fa1367
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png
new file mode 100644
index 000000000..a5deb60e9
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png
new file mode 100644
index 000000000..fc2998fc6
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space.png b/java/res/drawable-xhdpi/sym_keyboard_space.png
new file mode 100644
index 000000000..66fc3e9d3
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_space.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo.png
new file mode 100644
index 000000000..6d7f13e6f
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_space_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_led.9.png b/java/res/drawable-xhdpi/sym_keyboard_space_led.9.png
new file mode 100644
index 000000000..6525fefab
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_space_led.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.png b/java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.png
new file mode 100644
index 000000000..ba4e9ec49
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab.png b/java/res/drawable-xhdpi/sym_keyboard_tab.png
new file mode 100644
index 000000000..0ef2ab5b9
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_tab.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png
new file mode 100644
index 000000000..166643418
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png
new file mode 100644
index 000000000..fc05b9c6c
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png
new file mode 100644
index 000000000..6a5b1217d
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/vs_dialog_blue.9.png b/java/res/drawable-xhdpi/vs_dialog_blue.9.png
new file mode 100644
index 000000000..3284d78ef
--- /dev/null
+++ b/java/res/drawable-xhdpi/vs_dialog_blue.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/vs_dialog_red.9.png b/java/res/drawable-xhdpi/vs_dialog_red.9.png
new file mode 100644
index 000000000..5af2465b5
--- /dev/null
+++ b/java/res/drawable-xhdpi/vs_dialog_red.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/vs_dialog_yellow.9.png b/java/res/drawable-xhdpi/vs_dialog_yellow.9.png
new file mode 100644
index 000000000..4f50439de
--- /dev/null
+++ b/java/res/drawable-xhdpi/vs_dialog_yellow.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/vs_popup_mic_edge.png b/java/res/drawable-xhdpi/vs_popup_mic_edge.png
new file mode 100644
index 000000000..1063cb464
--- /dev/null
+++ b/java/res/drawable-xhdpi/vs_popup_mic_edge.png
Binary files differ
diff --git a/java/res/drawable/btn_candidate_holo.xml b/java/res/drawable/btn_candidate_ics.xml
index 66cd2460b..e4257e327 100644
--- a/java/res/drawable/btn_candidate_holo.xml
+++ b/java/res/drawable/btn_candidate_ics.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.
diff --git a/java/res/drawable/btn_keyboard_key_honeycomb.xml b/java/res/drawable/btn_keyboard_key_ics.xml
index 3dab8430f..7335cc299 100644
--- a/java/res/drawable/btn_keyboard_key_honeycomb.xml
+++ b/java/res/drawable/btn_keyboard_key_ics.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -14,7 +14,6 @@
limitations under the License.
-->
-<!-- TODO: Remove "gingerbread" from file name and rename this to "btn_keyboard_key.xml". -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Functional keys. -->
diff --git a/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml b/java/res/drawable/btn_keyboard_key_popup.xml
index 9b6d23beb..9e3670d22 100644
--- a/java/res/drawable/btn_keyboard_key_gingerbread_popup.xml
+++ b/java/res/drawable/btn_keyboard_key_popup.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -17,5 +17,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_light_popup_selected" />
- <item android:drawable="@drawable/btn_keyboard_key_light_popup_normal" />
+ <item android:drawable="@drawable/transparent" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_honeycomb_popup.xml b/java/res/drawable/btn_keyboard_key_popup_ics.xml
index 6c2713650..b99679ba1 100644
--- a/java/res/drawable/btn_keyboard_key_honeycomb_popup.xml
+++ b/java/res/drawable/btn_keyboard_key_popup_ics.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -17,4 +17,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_popup_selected_holo" />
+ <item android:drawable="@drawable/transparent" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_stone.xml b/java/res/drawable/btn_keyboard_key_stone.xml
index a6040a04e..27932e8da 100644
--- a/java/res/drawable/btn_keyboard_key_stone.xml
+++ b/java/res/drawable/btn_keyboard_key_stone.xml
@@ -16,6 +16,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Functional keys. -->
+
+ <item android:state_single="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
+ <item android:state_single="true"
+ android:drawable="@drawable/btn_keyboard_key_normal_stone" />
+
<!-- Toggle keys. Use checkable/checked state. -->
<item android:state_checkable="true" android:state_checked="true"
diff --git a/java/res/drawable/keyboard_key_feedback_honeycomb.xml b/java/res/drawable/keyboard_key_feedback_ics.xml
index a3ea140cd..04c86794f 100644
--- a/java/res/drawable/keyboard_key_feedback_honeycomb.xml
+++ b/java/res/drawable/keyboard_key_feedback_ics.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
diff --git a/java/res/drawable/btn_keyboard_key_fulltrans.xml b/java/res/drawable/keyboard_key_feedback_left_ics.xml
index bad2a931d..b68b37f6b 100644
--- a/java/res/drawable/btn_keyboard_key_fulltrans.xml
+++ b/java/res/drawable/keyboard_key_feedback_left_ics.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -15,12 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Normal keys -->
-
- <item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
- <item
- android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
-
+ <item android:state_long_pressable="true"
+ android:drawable="@drawable/keyboard_key_feedback_left_more_background_holo" />
+ <item android:drawable="@drawable/keyboard_key_feedback_left_background_holo" />
</selector>
diff --git a/java/res/drawable/keyboard_key_feedback_right_ics.xml b/java/res/drawable/keyboard_key_feedback_right_ics.xml
new file mode 100644
index 000000000..830678a5a
--- /dev/null
+++ b/java/res/drawable/keyboard_key_feedback_right_ics.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_long_pressable="true"
+ android:drawable="@drawable/keyboard_key_feedback_right_more_background_holo" />
+ <item android:drawable="@drawable/keyboard_key_feedback_right_background_holo" />
+</selector>
diff --git a/java/res/anim/key_preview_fadeout.xml b/java/res/drawable/transparent.xml
index 7de5123cd..855cf2ad5 100644
--- a/java/res/anim/key_preview_fadeout.xml
+++ b/java/res/drawable/transparent.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,12 +18,13 @@
*/
-->
-<set
+<shape
xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator"
+ android:shape="rectangle"
>
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="0.0"
- android:duration="@integer/config_preview_fadeout_anim_time" />
-</set>
+ <solid
+ android:color="@android:color/transparent" />
+ <size
+ android:width="50dp"
+ android:height="40dp" />
+</shape>
diff --git a/java/res/layout-sw600dp/candidate.xml b/java/res/layout-sw600dp/candidate.xml
deleted file mode 100644
index e672707a1..000000000
--- a/java/res/layout-sw600dp/candidate.xml
+++ /dev/null
@@ -1,60 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:orientation="horizontal"
- android:paddingRight="@dimen/candidate_padding"
->
- <ImageView
- android:id="@+id/candidate_divider"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:visibility="gone"
- android:focusable="false"
- android:clickable="false"
- android:src="@drawable/keyboard_suggest_strip_divider"
- android:gravity="center_vertical|center_horizontal" />
- <Button
- android:id="@+id/candidate_word"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:minWidth="@dimen/candidate_min_width"
- android:textSize="@dimen/candidate_text_size"
- android:textColor="@color/candidate_normal"
- android:background="@drawable/btn_candidate_holo"
- android:focusable="true"
- android:clickable="true"
- android:gravity="center_vertical|center_horizontal"
- android:paddingLeft="@dimen/candidate_padding" />
- <TextView
- android:id="@+id/candidate_debug_info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:textSize="10dip"
- android:textColor="#ff808080"
- android:focusable="false"
- android:clickable="false"
- android:gravity="bottom"
- android:paddingLeft="4dip" />
-</LinearLayout>
diff --git a/java/res/layout-sw600dp/candidates.xml b/java/res/layout-sw600dp/candidates.xml
deleted file mode 100644
index 26d6822e9..000000000
--- a/java/res/layout-sw600dp/candidates.xml
+++ /dev/null
@@ -1,45 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip_holo"
- android:paddingRight="@dimen/candidate_strip_padding"
- android:paddingLeft="@dimen/candidate_strip_padding"
->
- <HorizontalScrollView
- android:id="@+id/candidates_scroll_view"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:fadingEdge="horizontal"
- android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
- android:scrollbars="none"
- >
- <com.android.inputmethod.latin.CandidateView
- android:id="@+id/candidates"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip_holo" />
- </HorizontalScrollView>
-</LinearLayout>
diff --git a/java/res/layout-sw600dp/keyboard_popup_honeycomb.xml b/java/res/layout-sw600dp/keyboard_popup_honeycomb.xml
deleted file mode 100644
index 49eb936d6..000000000
--- a/java/res/layout-sw600dp/keyboard_popup_honeycomb.xml
+++ /dev/null
@@ -1,41 +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.
-*/
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:background="@drawable/keyboard_popup_panel_background_holo"
- android:paddingLeft="40dip"
- android:paddingRight="40dip"
- >
- <com.android.inputmethod.keyboard.KeyboardView
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/KeyboardView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/latinkeyboard_transparent"
-
- latin:keyBackground="@drawable/btn_keyboard_key_honeycomb_popup"
- latin:keyHysteresisDistance="0dip"
- latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction"
- />
-</LinearLayout>
diff --git a/java/res/layout-sw768dp/candidate.xml b/java/res/layout-sw768dp/candidate.xml
deleted file mode 100644
index 74532a1e2..000000000
--- a/java/res/layout-sw768dp/candidate.xml
+++ /dev/null
@@ -1,60 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:orientation="horizontal"
- android:paddingRight="@dimen/candidate_padding"
->
- <ImageView
- android:id="@+id/candidate_divider"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:visibility="gone"
- android:focusable="false"
- android:clickable="false"
- android:src="@drawable/keyboard_suggest_strip_divider"
- android:gravity="center_vertical|center_horizontal" />
- <Button
- android:id="@+id/candidate_word"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:minWidth="@dimen/candidate_min_width"
- android:textSize="@dimen/candidate_text_size"
- android:textColor="@color/candidate_normal"
- android:background="@drawable/btn_candidate_holo"
- android:focusable="true"
- android:clickable="true"
- android:gravity="center_vertical|center_horizontal"
- android:paddingLeft="@dimen/candidate_padding" />
- <TextView
- android:id="@+id/candidate_debug_info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:textSize="10dip"
- android:textColor="#ff808080"
- android:focusable="false"
- android:clickable="false"
- android:gravity="bottom"
- android:paddingLeft="4dip" />
-</LinearLayout>
diff --git a/java/res/layout-sw768dp/candidates.xml b/java/res/layout-sw768dp/candidates.xml
deleted file mode 100644
index e2ddb84b1..000000000
--- a/java/res/layout-sw768dp/candidates.xml
+++ /dev/null
@@ -1,45 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip_holo"
- android:paddingRight="@dimen/candidate_strip_padding"
- android:paddingLeft="@dimen/candidate_strip_padding"
->
- <HorizontalScrollView
- android:id="@+id/candidates_scroll_view"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:fadingEdge="horizontal"
- android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
- android:scrollbars="none"
- >
- <com.android.inputmethod.latin.CandidateView
- android:id="@+id/candidates"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip_holo" />
- </HorizontalScrollView>
-</LinearLayout>
diff --git a/java/res/layout-sw768dp/keyboard_popup_honeycomb.xml b/java/res/layout-sw768dp/keyboard_popup_honeycomb.xml
deleted file mode 100644
index 0b8229ca5..000000000
--- a/java/res/layout-sw768dp/keyboard_popup_honeycomb.xml
+++ /dev/null
@@ -1,41 +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.
-*/
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:background="@drawable/keyboard_popup_panel_background_holo"
- android:paddingLeft="40dip"
- android:paddingRight="40dip"
- >
- <com.android.inputmethod.keyboard.KeyboardView
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/KeyboardView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/latinkeyboard_transparent"
-
- latin:keyBackground="@drawable/btn_keyboard_key_honeycomb_popup"
- latin:keyHysteresisDistance="0dip"
- latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction"
- />
-</LinearLayout>
diff --git a/java/res/layout-sw768dp/recognition_status.xml b/java/res/layout-sw768dp/recognition_status.xml
new file mode 100644
index 000000000..40bc09823
--- /dev/null
+++ b/java/res/layout-sw768dp/recognition_status.xml
@@ -0,0 +1,101 @@
+<?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.
+*/
+-->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="@drawable/background_voice">
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/popup_layout"
+ android:orientation="vertical"
+ android:layout_height="371dip"
+ android:layout_width="500dip"
+ android:layout_centerInParent="true"
+ android:background="@drawable/vs_dialog_red">
+ <TextView
+ android:id="@+id/text"
+ android:text="@string/voice_error"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:singleLine="true"
+ android:layout_marginTop="10dip"
+ android:textSize="28sp"
+ android:textColor="#ffffff"
+ android:layout_gravity="center"
+ android:visibility="invisible"/>
+ <RelativeLayout
+ android:layout_height="0dip"
+ android:layout_width="match_parent"
+ android:layout_weight="1.0">
+ <com.android.inputmethod.deprecated.voice.SoundIndicator
+ android:id="@+id/sound_indicator"
+ android:src="@drawable/mic_full"
+ android:background="@drawable/mic_base"
+ android:adjustViewBounds="true"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_centerInParent="true"
+ android:visibility="gone"/>
+ <ImageView
+ android:id="@+id/image"
+ android:src="@drawable/mic_slash"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_centerInParent="true"
+ android:visibility="visible"/>
+ <ProgressBar
+ android:id="@+id/progress"
+ android:indeterminate="true"
+ android:indeterminateOnly="false"
+ android:layout_height="60dip"
+ android:layout_width="60dip"
+ android:layout_centerInParent="true"
+ android:visibility="gone"/>
+ </RelativeLayout>
+ <!--
+ The text is set by the code. We specify a random text (voice_error), so the
+ text view does not have a zero height. This is necessary to keep the slash
+ mic and the recording mic is the same position
+ -->
+ <TextView
+ android:id="@+id/language"
+ android:text="@string/voice_error"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:singleLine="true"
+ android:textSize="14sp"
+ android:layout_marginBottom="3dip"
+ android:layout_gravity="center"
+ android:textColor="#ffffff"
+ android:visibility="invisible"/>
+ <Button
+ android:id="@+id/button"
+ android:layout_width="match_parent"
+ android:layout_height="54dip"
+ android:singleLine="true"
+ android:focusable="true"
+ android:text="@string/cancel"
+ android:layout_gravity="center_horizontal"
+ android:background="@drawable/btn_center"
+ android:textColor="#ffffff"
+ android:textSize="19sp" />
+ </LinearLayout>
+</RelativeLayout>
diff --git a/java/res/layout/candidate.xml b/java/res/layout/candidate.xml
deleted file mode 100644
index f2c4126b3..000000000
--- a/java/res/layout/candidate.xml
+++ /dev/null
@@ -1,60 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:orientation="horizontal"
- android:paddingRight="@dimen/candidate_padding"
->
- <ImageView
- android:id="@+id/candidate_divider"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:visibility="gone"
- android:focusable="false"
- android:clickable="false"
- android:src="@drawable/keyboard_suggest_strip_divider"
- android:gravity="center_vertical|center_horizontal" />
- <Button
- android:id="@+id/candidate_word"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:minWidth="@dimen/candidate_min_width"
- android:textSize="@dimen/candidate_text_size"
- android:textColor="@color/candidate_normal"
- android:background="@drawable/btn_candidate"
- android:focusable="true"
- android:clickable="true"
- android:gravity="center_vertical|center_horizontal"
- android:paddingLeft="@dimen/candidate_padding" />
- <TextView
- android:id="@+id/candidate_debug_info"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:textSize="10dip"
- android:textColor="#ff808080"
- android:focusable="false"
- android:clickable="false"
- android:gravity="bottom"
- android:paddingLeft="4dip" />
-</LinearLayout>
diff --git a/java/res/anim/key_preview_fadein.xml b/java/res/layout/candidate_divider.xml
index 9fad7b9a7..dc5e77966 100644
--- a/java/res/anim/key_preview_fadein.xml
+++ b/java/res/layout/candidate_divider.xml
@@ -18,12 +18,10 @@
*/
-->
-<set
+<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/decelerate_interpolator"
->
- <alpha
- android:fromAlpha="0.5"
- android:toAlpha="1.0"
- android:duration="@integer/config_preview_fadein_anim_time" />
-</set>
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:src="@drawable/keyboard_suggest_strip_divider"
+ android:padding="0dp"
+ android:gravity="center" />
diff --git a/java/res/layout-sw600dp/candidate_preview.xml b/java/res/layout/candidate_info.xml
index 3ef2e6ed4..a364d46aa 100644
--- a/java/res/layout-sw600dp/candidate_preview.xml
+++ b/java/res/layout/candidate_info.xml
@@ -22,8 +22,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="18sp"
- android:textColor="?android:attr/textColorPrimaryInverse"
- android:minWidth="32dip"
- android:gravity="center"
- android:background="@drawable/keyboard_popup_panel_background_holo" />
+ android:textSize="6sp"
+ android:textColor="@android:color/white"
+ style="?attr/suggestionBackgroundStyle" />
diff --git a/java/res/layout/candidate_preview.xml b/java/res/layout/candidate_preview.xml
index fe2002d46..32705c996 100644
--- a/java/res/layout/candidate_preview.xml
+++ b/java/res/layout/candidate_preview.xml
@@ -19,11 +19,10 @@
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="?android:attr/textColorPrimaryInverse"
android:minWidth="32dip"
android:gravity="center"
- android:background="@drawable/candidate_feedback_background"
- />
+ style="?attr/suggestionPreviewBackgroundStyle" />
diff --git a/java/res/layout-sw768dp/candidate_preview.xml b/java/res/layout/candidate_word.xml
index 61d5f8e7b..b711e8f29 100644
--- a/java/res/layout-sw768dp/candidate_preview.xml
+++ b/java/res/layout/candidate_word.xml
@@ -20,10 +20,17 @@
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:textColor="?android:attr/textColorPrimaryInverse"
- android:minWidth="32dip"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:minWidth="@dimen/candidate_min_width"
+ android:textSize="@dimen/candidate_text_size"
android:gravity="center"
- android:background="@drawable/keyboard_popup_panel_background_holo" />
+ android:paddingLeft="@dimen/candidate_padding"
+ android:paddingTop="0dp"
+ android:paddingRight="@dimen/candidate_padding"
+ android:paddingBottom="0dp"
+ android:focusable="false"
+ android:clickable="false"
+ android:singleLine="true"
+ android:ellipsize="none"
+ style="?attr/suggestionBackgroundStyle" />
diff --git a/java/res/layout/candidates.xml b/java/res/layout/candidates.xml
deleted file mode 100644
index 1b8d04183..000000000
--- a/java/res/layout/candidates.xml
+++ /dev/null
@@ -1,45 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip"
- android:paddingRight="@dimen/candidate_strip_padding"
- android:paddingLeft="@dimen/candidate_strip_padding"
->
- <HorizontalScrollView
- android:id="@+id/candidates_scroll_view"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/candidate_strip_height"
- android:fadingEdge="horizontal"
- android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
- android:scrollbars="none"
- >
- <com.android.inputmethod.latin.CandidateView
- android:id="@+id/candidates"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip" />
- </HorizontalScrollView>
-</LinearLayout>
diff --git a/java/res/layout/candidates_strip.xml b/java/res/layout/candidates_strip.xml
new file mode 100644
index 000000000..269bc1bc3
--- /dev/null
+++ b/java/res/layout/candidates_strip.xml
@@ -0,0 +1,84 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <LinearLayout
+ android:id="@+id/candidates_strip"
+ android:orientation="horizontal"
+ android:layout_weight="1.0"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+ <LinearLayout
+ android:id="@+id/candidates_pane_control"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ >
+ <TextView
+ android:id="@+id/expand_candidates_pane"
+ android:text="@string/label_expand_candidates_pane"
+ android:gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="28dp"
+ android:textSize="@dimen/candidate_text_size"
+ android:visibility="visible" />
+ <TextView
+ android:id="@+id/close_candidates_pane"
+ android:text="@string/label_close_candidates_pane"
+ android:gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="28dp"
+ android:textSize="@dimen/candidate_text_size"
+ android:visibility="gone" />
+ </LinearLayout>
+ <LinearLayout
+ android:id="@+id/touch_to_save"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ >
+ <Button
+ android:id="@+id/word_to_save"
+ android:layout_weight="1.0"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:textSize="@dimen/candidate_text_size"
+ android:singleLine="true"
+ android:ellipsize="middle"
+ style="?attr/suggestionBackgroundStyle" />
+ <include
+ layout="@layout/candidate_divider" />
+ <TextView
+ android:layout_weight="2.0"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:gravity="left|center_vertical"
+ android:text="@string/hint_add_to_dictionary"
+ android:textSize="@dimen/candidate_text_size"
+ android:background="@null" />
+ </LinearLayout>
+</merge>
diff --git a/java/res/layout/input_basic.xml b/java/res/layout/input_basic.xml
deleted file mode 100644
index 7b85bae94..000000000
--- a/java/res/layout/input_basic.xml
+++ /dev/null
@@ -1,31 +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.
-*/
--->
-
-<com.android.inputmethod.keyboard.LatinKeyboardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/LatinkeyboardBaseView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/keyboard_background"
-
- latin:keyBackground="@drawable/btn_keyboard_key"
- />
diff --git a/java/res/layout/input_basic_highcontrast.xml b/java/res/layout/input_basic_highcontrast.xml
deleted file mode 100644
index d9200fd5e..000000000
--- a/java/res/layout/input_basic_highcontrast.xml
+++ /dev/null
@@ -1,32 +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.
-*/
--->
-
-<com.android.inputmethod.keyboard.LatinKeyboardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-
- android:id="@+id/LatinkeyboardBaseView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/black"
-
- latin:keyBackground="@drawable/btn_keyboard_key3"
- />
diff --git a/java/res/layout/input_gingerbread.xml b/java/res/layout/input_gingerbread.xml
deleted file mode 100644
index 6233e6dc6..000000000
--- a/java/res/layout/input_gingerbread.xml
+++ /dev/null
@@ -1,34 +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.
-*/
--->
-
-<com.android.inputmethod.keyboard.LatinKeyboardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/LatinkeyboardBaseView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/keyboard_top_padding"
- android:paddingBottom="@dimen/keyboard_bottom_padding"
- android:background="@drawable/keyboard_dark_background"
-
- latin:keyBackground="@drawable/btn_keyboard_key_gingerbread"
- latin:keyLetterStyle="bold"
- />
diff --git a/java/res/layout/input_honeycomb.xml b/java/res/layout/input_honeycomb.xml
deleted file mode 100644
index 6ccc63c2b..000000000
--- a/java/res/layout/input_honeycomb.xml
+++ /dev/null
@@ -1,39 +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.
-*/
--->
-
-<com.android.inputmethod.keyboard.LatinKeyboardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/LatinkeyboardBaseView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/keyboard_top_padding"
- android:paddingBottom="@dimen/keyboard_bottom_padding"
- android:background="@drawable/keyboard_background_holo"
-
- latin:keyBackground="@drawable/btn_keyboard_key_honeycomb"
- latin:keyPreviewLayout="@layout/key_preview_honeycomb"
- latin:popupLayout="@layout/keyboard_popup_honeycomb"
- latin:keyTextColorDisabled="#FF63666D"
- latin:keyLetterStyle="bold"
- latin:shadowColor="#00000000"
- latin:shadowRadius="0.0"
- />
diff --git a/java/res/layout/input_stone_bold.xml b/java/res/layout/input_stone_bold.xml
deleted file mode 100644
index 6fdc93855..000000000
--- a/java/res/layout/input_stone_bold.xml
+++ /dev/null
@@ -1,37 +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.
-*/
--->
-
-<com.android.inputmethod.keyboard.LatinKeyboardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/LatinkeyboardBaseView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/keyboard_background"
-
- latin:keyBackground="@drawable/btn_keyboard_key_stone"
- latin:keyTextColor="@color/latinkeyboard_key_color_black"
- latin:keyTextColorDisabled="#FF808080"
- latin:shadowColor="@color/latinkeyboard_key_color_white"
- latin:keyLetterStyle="bold"
- latin:colorScheme="black"
- latin:popupLayout="@layout/input_stone_popup"
- />
diff --git a/java/res/layout/input_stone_normal.xml b/java/res/layout/input_stone_normal.xml
deleted file mode 100644
index 6ae9aed55..000000000
--- a/java/res/layout/input_stone_normal.xml
+++ /dev/null
@@ -1,36 +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.
-*/
--->
-
-<com.android.inputmethod.keyboard.LatinKeyboardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/LatinkeyboardBaseView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/keyboard_background"
-
- latin:keyBackground="@drawable/btn_keyboard_key_stone"
- latin:keyTextColor="@color/latinkeyboard_key_color_black"
- latin:keyTextColorDisabled="#FF808080"
- latin:shadowColor="@color/latinkeyboard_key_color_white"
- latin:colorScheme="black"
- latin:popupLayout="@layout/input_stone_popup"
- />
diff --git a/java/res/layout/input_stone_popup.xml b/java/res/layout/input_stone_popup.xml
deleted file mode 100644
index b4da04536..000000000
--- a/java/res/layout/input_stone_popup.xml
+++ /dev/null
@@ -1,41 +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.
-*/
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:background="@drawable/keyboard_popup_panel_background"
- >
- <com.android.inputmethod.keyboard.KeyboardView
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/KeyboardView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/keyboard_background"
-
- latin:keyBackground="@drawable/btn_keyboard_key_stone"
- latin:keyTextColor="@color/latinkeyboard_key_color_black"
- latin:shadowColor="@color/latinkeyboard_key_color_white"
- latin:popupLayout="@layout/input_stone_popup"
- />
-</LinearLayout>
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
new file mode 100644
index 000000000..821082f91
--- /dev/null
+++ b/java/res/layout/input_view.xml
@@ -0,0 +1,82 @@
+<?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.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+>
+ <!-- On tablets, the candidate strip is centered with horizontal paddings on both sides because
+ width of the landscape mode is too long for the candidate strip. This LinearLayout is
+ required to hold the paddings. -->
+ <LinearLayout
+ android:id="@+id/candidates_container"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/candidate_strip_minimum_height"
+ android:gravity="bottom"
+ >
+ <View
+ android:layout_width="@dimen/candidate_strip_padding"
+ android:layout_height="@dimen/candidate_strip_height"
+ style="?attr/suggestionsStripBackgroundStyle" />
+ <com.android.inputmethod.latin.CandidateView
+ android:id="@+id/candidates"
+ android:layout_weight="1.0"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/candidate_strip_height"
+ android:gravity="center_vertical"
+ style="?attr/candidateViewStyle" />
+ <View
+ android:layout_width="@dimen/candidate_strip_padding"
+ android:layout_height="@dimen/candidate_strip_height"
+ style="?attr/suggestionsStripBackgroundStyle" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/candidates_pane_container"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?attr/suggestionsStripBackgroundStyle"
+ >
+ <View
+ android:layout_width="@dimen/candidate_strip_padding"
+ android:layout_height="@dimen/candidate_strip_height" />
+ <FrameLayout
+ android:id="@+id/candidates_pane"
+ android:layout_weight="1.0"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+ <View
+ android:layout_width="@dimen/candidate_strip_padding"
+ android:layout_height="@dimen/candidate_strip_height" />
+ </LinearLayout>
+
+ <com.android.inputmethod.keyboard.LatinKeyboardView
+ android:id="@+id/keyboard_view"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/java/res/layout/key_preview.xml b/java/res/layout/key_preview.xml
index de03506ad..b620d07d8 100644
--- a/java/res/layout/key_preview.xml
+++ b/java/res/layout/key_preview.xml
@@ -22,8 +22,6 @@
android:layout_width="wrap_content"
android:layout_height="80sp"
android:textSize="40sp"
- android:textColor="@color/latinkeyboard_key_color_white"
android:minWidth="32dip"
android:gravity="center"
- android:background="@drawable/keyboard_key_feedback"
/>
diff --git a/java/res/layout/key_preview_honeycomb.xml b/java/res/layout/key_preview_honeycomb.xml
deleted file mode 100644
index a90fe5588..000000000
--- a/java/res/layout/key_preview_honeycomb.xml
+++ /dev/null
@@ -1,29 +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.
-*/
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="80sp"
- android:textSize="40sp"
- android:textColor="@color/latinkeyboard_key_color_white"
- android:minWidth="24dip"
- android:gravity="center"
- android:background="@drawable/keyboard_key_feedback_honeycomb"
- />
diff --git a/java/res/layout/keyboard_popup.xml b/java/res/layout/keyboard_popup.xml
index ac8134bfb..e2508da78 100644
--- a/java/res/layout/keyboard_popup.xml
+++ b/java/res/layout/keyboard_popup.xml
@@ -19,23 +19,16 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:background="@drawable/keyboard_popup_panel_background"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
+ style="?attr/popupMiniKeyboardPanelStyle"
>
- <com.android.inputmethod.keyboard.KeyboardView
+ <com.android.inputmethod.keyboard.PopupMiniKeyboardView
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/KeyboardView"
+ android:id="@+id/mini_keyboard_view"
android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@color/latinkeyboard_transparent"
-
- latin:keyBackground="@drawable/btn_keyboard_key_gingerbread_popup"
- latin:keyHysteresisDistance="0dip"
- latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction"
/>
</LinearLayout>
diff --git a/java/res/layout/keyboard_popup_honeycomb.xml b/java/res/layout/keyboard_popup_honeycomb.xml
deleted file mode 100644
index e5fcbd44c..000000000
--- a/java/res/layout/keyboard_popup_honeycomb.xml
+++ /dev/null
@@ -1,41 +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.
-*/
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:background="@drawable/keyboard_popup_panel_background_holo"
- android:paddingLeft="24dip"
- android:paddingRight="24dip"
- >
- <com.android.inputmethod.keyboard.KeyboardView
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/KeyboardView"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/latinkeyboard_transparent"
-
- latin:keyBackground="@drawable/btn_keyboard_key_honeycomb_popup"
- latin:keyHysteresisDistance="0dip"
- latin:verticalCorrection="@dimen/mini_keyboard_vertical_correction"
- />
-</LinearLayout>
diff --git a/java/res/layout/recognition_status.xml b/java/res/layout/recognition_status.xml
index 9474d6f58..a2ddb7c50 100644
--- a/java/res/layout/recognition_status.xml
+++ b/java/res/layout/recognition_status.xml
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/*
+/*
**
** Copyright 2009, 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
+** 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
+** 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
+** 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.
*/
-->
@@ -37,7 +37,7 @@
android:layout_width="wrap_content"
android:singleLine="true"
android:layout_marginTop="10dip"
- android:textSize="28sp"
+ android:textSize="20sp"
android:textColor="#ffffff"
android:layout_gravity="center"
android:visibility="invisible"/>
@@ -45,7 +45,7 @@
android:layout_height="0dip"
android:layout_width="match_parent"
android:layout_weight="1.0">
- <com.android.inputmethod.voice.SoundIndicator
+ <com.android.inputmethod.deprecated.voice.SoundIndicator
android:id="@+id/sound_indicator"
android:src="@drawable/mic_full"
android:background="@drawable/mic_base"
@@ -81,7 +81,8 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:singleLine="true"
- android:textSize="14sp"
+ android:textSize="15sp"
+ android:layout_marginTop="3dip"
android:layout_marginBottom="3dip"
android:layout_gravity="center"
android:textColor="#ffffff"
@@ -89,13 +90,13 @@
<Button
android:id="@+id/button"
android:layout_width="match_parent"
- android:layout_height="54dip"
+ android:layout_height="30dip"
android:singleLine="true"
android:focusable="true"
android:text="@string/cancel"
android:layout_gravity="center_horizontal"
android:background="@drawable/btn_center"
android:textColor="#ffffff"
- android:textSize="19sp" />
+ android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
new file mode 100644
index 000000000..02950338d
--- /dev/null
+++ b/java/res/values-af/strings.xml
@@ -0,0 +1,256 @@
+<?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.
+*/
+ -->
+
+<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="english_ime_settings" msgid="6661589557206947774">"Android-sleutelbordinstellings"</string>
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Invoeropsies"</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 by druk van sleutel"</string>
+ <!-- no translation found for general_category (1859088467017573195) -->
+ <skip />
+ <!-- no translation found for correction_category (2236750915056607613) -->
+ <skip />
+ <!-- no translation found for ngram_category (5337109164339320257) -->
+ <skip />
+ <!-- no translation found for misc_category (6894192814868233453) -->
+ <skip />
+ <!-- no translation found for advanced_settings (362895144495591463) -->
+ <skip />
+ <!-- no translation found for advanced_settings_summary (5193513161106637254) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict (4435317977804180815) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict_summary (6599983334507879959) -->
+ <skip />
+ <string name="auto_cap" msgid="1719746674854628252">"Outohoofletters"</string>
+ <!-- no translation found for configure_dictionaries_title (3758288002414557345) -->
+ <skip />
+ <string name="quick_fixes" msgid="5353213327680897927">"Vinnige oplossings"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Korrigeer algemene tikfoute"</string>
+ <!-- no translation found for prefs_show_suggestions (8026799663445531637) -->
+ <skip />
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Wys voorgestelde woorde terwyl jy tik"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Wys altyd"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Wys in portretmodus"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Versteek altyd"</string>
+ <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) -->
+ <skip />
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Wys instellingsleutel"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Outomaties"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Wys altyd"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Versteek altyd"</string>
+ <string name="auto_correction" msgid="4979925752001319458">"Outokorrigering"</string>
+ <!-- outdated translation 6881047311475758267 --> <string name="auto_correction_summary" msgid="5625751551134658006">"Korrigeer outomaties die vorige woord"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Af"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Nederig"</string>
+ <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressief"</string>
+ <!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) -->
+ <skip />
+ <!-- outdated translation 1323347224043514969 --> <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-voorstelle"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gebruik vorige woord om voorstel te verbeter"</string>
+ <!-- no translation found for bigram_prediction (8914273444762259739) -->
+ <skip />
+ <!-- no translation found for bigram_prediction_summary (1747261921174300098) -->
+ <skip />
+ <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>
+ <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>
+ <string name="label_more_key" msgid="3760239494604948502">"Meer"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Laat wag"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Wag"</string>
+ <!-- no translation found for spoken_current_text_is (2485723011272583845) -->
+ <skip />
+ <!-- no translation found for spoken_no_text_entered (7479685225597344496) -->
+ <skip />
+ <!-- no translation found for spoken_description_unknown (3197434010402179157) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift (244197883292549308) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift_shifted (954941524766465022) -->
+ <skip />
+ <!-- no translation found for spoken_description_caps_lock (5660626444912131764) -->
+ <skip />
+ <!-- no translation found for spoken_description_delete (8740376944276199801) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_symbol (5486340107500448969) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_alpha (23129338819771807) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_numeric (591752092685161732) -->
+ <skip />
+ <!-- no translation found for spoken_description_settings (4627462689603838099) -->
+ <skip />
+ <!-- no translation found for spoken_description_tab (2667716002663482248) -->
+ <skip />
+ <!-- no translation found for spoken_description_space (2582521050049860859) -->
+ <skip />
+ <!-- no translation found for spoken_description_mic (615536748882611950) -->
+ <skip />
+ <!-- no translation found for spoken_description_smiley (2256309826200113918) -->
+ <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) -->
+ <skip />
+ <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <skip />
+ <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
+ <skip />
+ <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>
+ <string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"Om steminvoer af te skakel, gaan na invoermetode-instellings."</string>
+ <string name="voice_hint_dialog_message" msgid="1420686286820661548">"Om steminvoer te gebruik, druk die mikrofoonknoppie."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Praat nou"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Werkend"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Fout. Probeer asseblief weer."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Kon nie koppel nie"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Fout, te veel spraak."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Oudioprobleem"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Bedienerfout"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Geen spraak gehoor nie"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Geen passings gevind nie"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Stemsoek nie geïnstalleer nie"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Wenk:"</b>" Sleep oor die sleutelbord om te praat"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Wenk:"</b>" Probeer volgende keer om leestekens soos \"punt\", \"komma\" of \"vraagteken\" hardop te sê."</string>
+ <string name="cancel" msgid="6830980399865683324">"Kanselleer"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Steminvoering"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Op hoofsleutelbord"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Op simbolesleutelbord"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Af"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mikrofoon op hoofsleutelbord"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mikrofoon op simbolesleutelbord"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Steminvoer is gedeaktiveer"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Kies invoermetode"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Invoertale"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Raak weer om te stoor"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Woordeboek beskikbaar"</string>
+ <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="prefs_enable_recorrection" msgid="4588408906649533582">"Raak om woorde reg te maak"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Raak ingevoerde woorde om hulle te korrigeer, net wanneer voorstelle sigbaar is"</string>
+ <!-- outdated translation 437433231038683666 --> <string name="keyboard_layout" msgid="8451164783510487501">"Sleutelbordtema"</string>
+ <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tsjeggiese sleutelbord"</string>
+ <!-- no translation found for subtype_mode_ar_keyboard (2655338636329774995) -->
+ <skip />
+ <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Deense sleutelbord"</string>
+ <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Duitse sleutelbord"</string>
+ <!-- no translation found for subtype_mode_de_qwerty_keyboard (54890770769303956) -->
+ <skip />
+ <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelse (VK) sleutelbord"</string>
+ <string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Engelse (VS) sleutelbord"</string>
+ <string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spaanse sleutelbord"</string>
+ <!-- no translation found for subtype_mode_fi_keyboard (3198596464082614532) -->
+ <skip />
+ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Franse sleutelbord"</string>
+ <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Franse (Kanada) sleutelbord"</string>
+ <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Franse (Switserland) sleutelbord"</string>
+ <!-- no translation found for subtype_mode_hr_keyboard (7177182405440070112) -->
+ <skip />
+ <!-- no translation found for subtype_mode_hu_keyboard (8843338355732633647) -->
+ <skip />
+ <!-- no translation found for subtype_mode_iw_keyboard (1787536828253289950) -->
+ <skip />
+ <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiaanse sleutelbord"</string>
+ <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Noorweegse sleutelbord"</string>
+ <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nederlandse sleutelbord"</string>
+ <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) -->
+ <skip />
+ <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) -->
+ <skip />
+ <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russiese sleutelbord"</string>
+ <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serwiese sleutelbord"</string>
+ <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Sweedse sleutelbord"</string>
+ <!-- no translation found for subtype_mode_tr_keyboard (3155981874829226370) -->
+ <skip />
+ <!-- no translation found for subtype_mode_af_voice (7542487489657902699) -->
+ <skip />
+ <string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Tsjeggiese stem"</string>
+ <string name="subtype_mode_de_voice" msgid="8378803143958089866">"Duitse stem"</string>
+ <!-- no translation found for subtype_mode_en_voice (6643420989651848728) -->
+ <skip />
+ <string name="subtype_mode_es_voice" msgid="1323473601346507487">"Spaanse stem"</string>
+ <string name="subtype_mode_fr_voice" msgid="4675914209337824269">"Franse stem"</string>
+ <!-- no translation found for subtype_mode_it_voice (5077373057157441323) -->
+ <skip />
+ <string name="subtype_mode_ja_voice" msgid="6604859132669646367">"Japannese stem"</string>
+ <string name="subtype_mode_ko_voice" msgid="4890391190762324561">"Koreaanse stem"</string>
+ <!-- no translation found for subtype_mode_nl_voice (2603552312869575021) -->
+ <skip />
+ <string name="subtype_mode_pl_voice" msgid="2076196021014840487">"Poolse stem"</string>
+ <string name="subtype_mode_pt_voice" msgid="8036522712795994397">"Portugese stem"</string>
+ <string name="subtype_mode_ru_voice" msgid="8034596947963787529">"Russiese stem"</string>
+ <string name="subtype_mode_tr_voice" msgid="3402067436761140005">"Turkse stem"</string>
+ <!-- no translation found for subtype_mode_yue_voice (1576887891614624263) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zh_voice (4360533229467271152) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zu_voice (1146122571698884636) -->
+ <skip />
+ <!-- outdated translation 6937813623647419810 --> <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruikbaarheidsmodus"</string>
+</resources>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
new file mode 100644
index 000000000..10aa8aea3
--- /dev/null
+++ b/java/res/values-am/strings.xml
@@ -0,0 +1,256 @@
+<?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.
+*/
+ -->
+
+<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="vibrate_on_keypress" msgid="5258079494276955460">"በቁልፍመጫንጊዜ አንዝር"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"በቁልፍ መጫን ላይ የሚወጣ ድምፅ"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"ቁልፍ ጫን ላይ ብቅ ባይ"</string>
+ <!-- no translation found for general_category (1859088467017573195) -->
+ <skip />
+ <!-- no translation found for correction_category (2236750915056607613) -->
+ <skip />
+ <!-- no translation found for ngram_category (5337109164339320257) -->
+ <skip />
+ <!-- no translation found for misc_category (6894192814868233453) -->
+ <skip />
+ <!-- no translation found for advanced_settings (362895144495591463) -->
+ <skip />
+ <!-- no translation found for advanced_settings_summary (5193513161106637254) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict (4435317977804180815) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict_summary (6599983334507879959) -->
+ <skip />
+ <string name="auto_cap" msgid="1719746674854628252">"ራስ-ሰር አቢይ ማድረግ"</string>
+ <!-- no translation found for configure_dictionaries_title (3758288002414557345) -->
+ <skip />
+ <string name="quick_fixes" msgid="5353213327680897927">"ፈጣንጥገና"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">" የተለመዱ የትየባ ስህተቶችንያስተካክላል"</string>
+ <!-- no translation found for prefs_show_suggestions (8026799663445531637) -->
+ <skip />
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"እየተየብክ ተመራጭ ቃላትን አሳይ"</string>
+ <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>
+ <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) -->
+ <skip />
+ <string name="prefs_settings_key" msgid="4623341240804046498">"የቅንብሮች ቁልፍ አሳይ"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"ራስ ሰር"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"ሁልጊዜ አሳይ"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"ሁልጊዜ ደብቅ"</string>
+ <string name="auto_correction" msgid="4979925752001319458">"በራስ ማስተካከል"</string>
+ <!-- outdated translation 6881047311475758267 --> <string name="auto_correction_summary" msgid="5625751551134658006">"የቀደመውን ቃል በራስሰር አስተካክል"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ውጪ"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"መጠነኛ"</string>
+ <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"ኃይለኛ"</string>
+ <!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) -->
+ <skip />
+ <!-- outdated translation 1323347224043514969 --> <string name="bigram_suggestion" msgid="2636414079905220518">"ቢግራም ምክሮች"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"ምክርን ለማሻሻል የቀደመ ቃልን ተጠቀም"</string>
+ <!-- no translation found for bigram_prediction (8914273444762259739) -->
+ <skip />
+ <!-- no translation found for bigram_prediction_summary (1747261921174300098) -->
+ <skip />
+ <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>
+ <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>
+ <string name="label_more_key" msgid="3760239494604948502">"ተጨማሪ"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"ላፍታ አቁም"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"ቆይ"</string>
+ <!-- no translation found for spoken_current_text_is (2485723011272583845) -->
+ <skip />
+ <!-- no translation found for spoken_no_text_entered (7479685225597344496) -->
+ <skip />
+ <!-- no translation found for spoken_description_unknown (3197434010402179157) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift (244197883292549308) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift_shifted (954941524766465022) -->
+ <skip />
+ <!-- no translation found for spoken_description_caps_lock (5660626444912131764) -->
+ <skip />
+ <!-- no translation found for spoken_description_delete (8740376944276199801) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_symbol (5486340107500448969) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_alpha (23129338819771807) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_numeric (591752092685161732) -->
+ <skip />
+ <!-- no translation found for spoken_description_settings (4627462689603838099) -->
+ <skip />
+ <!-- no translation found for spoken_description_tab (2667716002663482248) -->
+ <skip />
+ <!-- no translation found for spoken_description_space (2582521050049860859) -->
+ <skip />
+ <!-- no translation found for spoken_description_mic (615536748882611950) -->
+ <skip />
+ <!-- no translation found for spoken_description_smiley (2256309826200113918) -->
+ <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) -->
+ <skip />
+ <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <skip />
+ <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
+ <skip />
+ <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>
+ <string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"የድምፅ ግቤት ለማጥፋት፣ወደ ግቤት ሜተድ ቅንብሮች ሂድ።"</string>
+ <string name="voice_hint_dialog_message" msgid="1420686286820661548">"የድምፅግቤት ለመጠቀም፣ የማይክራፎንየድምፅ ማጉያ አዝራር ተጫን።"</string>
+ <string name="voice_listening" msgid="467518160751321844">"አሁን ተናገር"</string>
+ <string name="voice_working" msgid="6666937792815731889">"ሥራ ላይ"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"ስህተት፣ እባክዎ እንደገና ይሞክሩ።"</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"ማያያዝ አልተቻለም"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"ስህተት፣ በጣም ብዙ ንግግር።"</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"የድምፅ ችግር"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"የአገልጋይ ስህተት"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"ምንም ንግግር አልተሰማም"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"ምንም ተመሳሳይ አልተገኘም።"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"የድምፅ ፍለጋአልተጫነም"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"ምክር፡"</b>" ለመናገር በቁልፍሰሌዳ ላይ አንሸራት"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"ምክር፡"</b>" ሌላ ጊዜ፣ እንደ \"period\", \"comma\", ወይም \"question mark\" ያሉ ስርዓተ ነጥቦችን ለመናገር ሞክር።"</string>
+ <string name="cancel" msgid="6830980399865683324">"ይቅር"</string>
+ <string name="ok" msgid="7898366843681727667">"እሺ"</string>
+ <string name="voice_input" msgid="2466640768843347841">"የድምፅ ግቤት"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"በዋናቁልፍ ሰሌዳ ላይ"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"በምልክቶች ቁልፍ ሰሌዳ ላይ"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"ውጪ"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"ድምፅ ማጉያ በዋናው ቁልፍሰሌዳው ላይ"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"የድምፅ ማጉያ ምልክትበቁልፍ ሰሌዳላይ"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"የድምፅ ግቤት ቦዝኗል"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"የግቤት ሜተድ ምረጥ"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"ቋንቋዎች አግቤት"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← ለማስቀመጥ ድጋሚ ንካ"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"መዝገበ ቃላት አለ"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"የተጠቃሚ ግብረ ምላሽ አንቃ"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"ወደ Google የተሰናከለ ሪፖርቶች እና አጠቃቀም ስታስቲክስ በራስ ሰር በመላክ ይህን ግቤት ሜተድ አርትኢ እገዛ ያሻሽላል።"</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"ቃላትን ለማስተካከል ንካ"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"የገቡ ቃላትን ለማስተካከል ንካ፣ አማራጮች ሲታዩብቻ"</string>
+ <!-- outdated translation 437433231038683666 --> <string name="keyboard_layout" msgid="8451164783510487501">"የቁልፍ ሰሌዳ ገጽታ"</string>
+ <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"የቼክ ቁልፍሰሌዳ"</string>
+ <!-- no translation found for subtype_mode_ar_keyboard (2655338636329774995) -->
+ <skip />
+ <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"የዳኒሽኛ ቁልፍሰሌዳ"</string>
+ <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"የጀርመንኛ ቁልፍሰሌዳ"</string>
+ <!-- no translation found for subtype_mode_de_qwerty_keyboard (54890770769303956) -->
+ <skip />
+ <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"የእንግሊዘኛ(ዩኬ) ቁልፍሰሌዳ"</string>
+ <string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"የእንግሊዘኛ(ዩኤስ) ቁልፍሰሌዳ"</string>
+ <string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"የስፖኒሽኛቁልፍ ሰሌዳ"</string>
+ <!-- no translation found for subtype_mode_fi_keyboard (3198596464082614532) -->
+ <skip />
+ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"የፈረንሳይኛ ቁልፍሰሌዳ"</string>
+ <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"የፈረንሳይኛ(ካናዳ) ቁልፍሰሌዳ"</string>
+ <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"የፈረንሳይኛ(ስዊዘርላንድ) ቁልፍሰሌዳ"</string>
+ <!-- no translation found for subtype_mode_hr_keyboard (7177182405440070112) -->
+ <skip />
+ <!-- no translation found for subtype_mode_hu_keyboard (8843338355732633647) -->
+ <skip />
+ <!-- no translation found for subtype_mode_iw_keyboard (1787536828253289950) -->
+ <skip />
+ <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"የጣሊያንኛ ቁልፍ ሰሌዳ"</string>
+ <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"የኖርዌጂኛ ቁልፍሰሌዳ"</string>
+ <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"የደች ቁልፍሰሌዳ"</string>
+ <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) -->
+ <skip />
+ <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) -->
+ <skip />
+ <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"የራሽኛቁልፍ ሰሌዳ"</string>
+ <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"የሩሲኪኛቁልፍ ሰሌዳ"</string>
+ <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"የሲውድናዊ ቁልፍሰሌዳ"</string>
+ <!-- no translation found for subtype_mode_tr_keyboard (3155981874829226370) -->
+ <skip />
+ <!-- no translation found for subtype_mode_af_voice (7542487489657902699) -->
+ <skip />
+ <string name="subtype_mode_cs_voice" msgid="1136386688120958641">"የቼክ ድምፅ"</string>
+ <string name="subtype_mode_de_voice" msgid="8378803143958089866">"የጀርመናዊ ድምፅ"</string>
+ <!-- no translation found for subtype_mode_en_voice (6643420989651848728) -->
+ <skip />
+ <string name="subtype_mode_es_voice" msgid="1323473601346507487">"የስፔናዊ ድምፅ"</string>
+ <string name="subtype_mode_fr_voice" msgid="4675914209337824269">"የፈረንሳዊ ድምፅ"</string>
+ <!-- no translation found for subtype_mode_it_voice (5077373057157441323) -->
+ <skip />
+ <string name="subtype_mode_ja_voice" msgid="6604859132669646367">"የጃፓናዊ ድምፅ"</string>
+ <string name="subtype_mode_ko_voice" msgid="4890391190762324561">"የኮሪያዊ ድምፅ"</string>
+ <!-- no translation found for subtype_mode_nl_voice (2603552312869575021) -->
+ <skip />
+ <string name="subtype_mode_pl_voice" msgid="2076196021014840487">"የፖሊሽኛ ድምፅ"</string>
+ <string name="subtype_mode_pt_voice" msgid="8036522712795994397">"የፖርቹጊኛ ድምፅ"</string>
+ <string name="subtype_mode_ru_voice" msgid="8034596947963787529">"የራሽኛድምፅ"</string>
+ <string name="subtype_mode_tr_voice" msgid="3402067436761140005">"የቱርካዊ ድምፅ"</string>
+ <!-- no translation found for subtype_mode_yue_voice (1576887891614624263) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zh_voice (4360533229467271152) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zu_voice (1146122571698884636) -->
+ <skip />
+ <!-- outdated translation 6937813623647419810 --> <string name="prefs_usability_study_mode" msgid="1261130555134595254">"የተገልጋይነት ጥናት ሁነታ"</string>
+</resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index f4bc3cac9..af7328916 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"صوت عند الضغط على مفتاح"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"انبثاق عند الضغط على المفاتيح"</string>
<string name="general_category" msgid="1859088467017573195">"عام"</string>
- <string name="prediction_category" msgid="6361242011806282176">"تصحيح النص"</string>
+ <string name="correction_category" msgid="2236750915056607613">"تصحيح النص"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"الاقتراحات بناءً على الكلمات السابقة"</string>
+ <string name="misc_category" msgid="6894192814868233453">"خيارات أخرى"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"الإعدادات المتقدمة"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"خيارات للمستخدمين الخبراء"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"تأخير إزالة النافذة المنبثقة الأساسية"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"بلا تأخير"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"افتراضي"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"اقتراح أسماء جهات الاتصال"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"استخدام الأسماء من جهات الاتصال للاقتراحات والتصحيحات"</string>
<string name="auto_cap" msgid="1719746674854628252">"استخدام الأحرف الكبيرة تلقائيًا"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"تهيئة القواميس"</string>
<string name="quick_fixes" msgid="5353213327680897927">"إصلاحات سريعة"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"تصحيح الأخطاء المكتوبة الشائعة"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"عرض اقتراحات التصحيح"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"استخدام مفتاح المسافة لتبديل اللغة"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"عرض مفتاح الإعدادات"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"تلقائي"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"إظهار بشكل دائم"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"إيقاف"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"معتدل"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"حاد"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"اقتراحات ثنائية"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"شديد الصرامة"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"اقتراحات ثنائية"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"استخدام الكلمة السابقة لتحسين الاقتراح"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"التنبؤ الثنائي"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"استخدام الكلمة السابقة أيضًا للتنبؤ"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"المزيد"</string>
<string name="label_pause_key" msgid="181098308428035340">"توقف مؤقت"</string>
<string name="label_wait_key" msgid="6402152600878093134">"انتظار"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"حذف"</string>
- <string name="description_return_key" msgid="8750044000806461678">"رجوع"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"الإعدادات"</string>
- <string name="description_shift_key" msgid="346906866277787836">"العالي"</string>
- <string name="description_space_key" msgid="8512130111575878517">"مسافة"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"الرموز"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"الإدخال الصوتي"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"تشغيل الرموز"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"إيقاف الرموز"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"تشغيل العالي"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"إيقاف العالي"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"النص الحالي هو %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"لم يتم إدخال نص"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"رمز المفتاح %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"العالي"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"تم تمكين العالي"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"تمكين Caps lock"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"حذف"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"الرموز"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"أحرف"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"أرقام"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"الإعدادات"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"علامة تبويب"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"مسافة"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"الإدخال الصوتي مُعطل"</string>
<string name="selectInputMethod" msgid="315076553378705821">"تحديد طريقة الإرسال"</string>
<string name="language_selection_title" msgid="1651299598555326750">"لغات الإدخال"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"مرر إصبعك على مفتاح المسافة لتغيير اللغة"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← المس مرة أخرى للحفظ"</string>
<string name="has_dictionary" msgid="6071847973466625007">"القاموس متاح"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"تمكين ملاحظات المستخدم"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"المساعدة في تحسين محرر طريقة الإرسال هذا من خلال إرسال إحصاءات الاستخدام وتقارير الأعطال تلقائيًا إلى Google."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"المس لتصحيح الكلمات"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"المس الكلمات التي تم إدخالها لتصحيحها، وذلك فقط عندما تكون الاقتراحات مرئية."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"مظهر لوحة المفاتيح"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"مظهر لوحة المفاتيح"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"لوحة مفاتيح تشيكية"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"لوحة المفاتيح العربية"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"لوحة مفاتيح دانماركية"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"لوحة مفاتيح ألمانية"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"لوحة مفاتيح QWERTY ألمانية"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"لوحة مفاتيح إنجليزية (بريطانيا)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"لوحة مفاتيح إنجليزية (الولايات المتحدة)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"لوحة مفاتيح إسبانية"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"لوحة المفاتيح الفنلندية"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"لوحة مفاتيح فرنسية"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"لوحة مفاتيح فرنسية (كندا)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"لوحة مفاتيح فرنسية (سويسرا)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"لوحة المفاتيح الكرواتية"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"لوحة المفاتيح المجرية"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"لوحة المفاتيح العبرية"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"لوحة مفاتيح إيطالية"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"لوحة مفاتيح نرويجية"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"لوحة مفاتيح بولندية"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"لوحة المفاتيح البولندية"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"لوحة المفاتيح البرتغالية"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"لوحة مفاتيح روسية"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"لوحة مفاتيح صربية"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"لوحة مفاتيح سويدية"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"لوحة المفاتيح التركية"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"صوت أفريقاني"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"صوت تشيكي"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"صوت ألماني"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"صوت صيني، يوي"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"صوت صيني، الماندارين"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"صوت زولوي"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"وضع دراسة الاستخدام"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"وضع دراسة سهولة الاستخدام"</string>
</resources>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 939fd75c8..bd65b9df8 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натискане на клавиш"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Изскачащ прозорец при натискане на клавиш"</string>
<string name="general_category" msgid="1859088467017573195">"Общи"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Корекция на текста"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Корекция на текста"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Предложения въз основа на предишни думи"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Други опции"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Разширени настройки"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Опции за потребителите експерти"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Отхвърляне на подсказката"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без задържане"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По подразбиране"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Предложения за контакти"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Използване на имена от „Контакти“ за предложения и поправки"</string>
<string name="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Конфигуриране на речници"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Бързи корекции"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Коригира най-честите грешки при въвеждане"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Показване на предложения за поправка"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"Смяна на езика с клавиша за интервал"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Показване на клавиша за настройки"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматично"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Да се показва винаги"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Изкл."</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агресивно"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Предложения за биграми"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Много агресивно"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Предложения за биграми"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Използване на предишната дума за подобряване на предложението"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Предвиждане за биграми"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Използване на предишната дума и за предвиждане"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Още"</string>
<string name="label_pause_key" msgid="181098308428035340">"Пауза"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Чака"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Изтриване"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Настройки"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Интервал"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Символи"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Гласово въвеждане"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Символите са включени"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Символите са изключени"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift е включен"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift е изключен"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Текущият текст е %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Няма въведен текст"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Код на клавишa %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"„Shift“ е активиран"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"„Caps Lock“ е активиран"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Символи"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Букви"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Цифри"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Настройки"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Интервал"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Глас. въвежд. е деакт."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Избор на метод на въвеждане"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Входни езици"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Плъзнете пръст по клавиша за интервал за промяна на езика"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Докоснете отново, за да запазите"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Има достъп до речник"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Активиране на отзивите от потребителите"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Помогнете за подобряването на този редактор за въвеждане чрез автоматично изпращане до Google на статистически данни за употребата и сигнали за сривове."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"Докоснете, за да поправите думите"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Докоснете въведените думи, за да ги поправите – само когато предложенията са видими"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Тема на клавиатурата"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Тема на клавиатурата"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"чешка клавиатура"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"клавиатура на арабски"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"датска клавиатура"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"немска клавиатура"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Немска клавиатура „QWERTY“"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"английска (Великобрит.) клавиатура"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"английска (САЩ) клавиатура"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"испанска клавиатура"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Финландска клавиатура"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"френска клавиатура"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"френска (Канада) клавиатура"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"френска (Швейцария) клавиатура"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Хърватска клавиатура"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Унгарска клавиатура"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"клавиатура на иврит"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"италианска клавиатура"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"норвежка клавиатура"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"нидерландска клавиатура"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Полска клавиатура"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Португалска клавиатура"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"руска клавиатура"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"сръбска клавиатура"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"шведска клавиатура"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Турска клавиатура"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"африкаанс, гласово"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"чешки, гласово"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"немски, гласово"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"китайски, кантонски, гласово"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"китайски, мандарин, гласово"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"зулуски, гласово"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Режим за изследване на използваемостта"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за изследване на използваемостта"</string>
</resources>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 8a0b84590..9e99c9b39 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"General"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Correcció de text"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Correcció de text"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Suggeriments basats en paraules anteriors"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Altres opcions"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Configuració avançada"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opcions per a usuaris experts"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Retard d\'om. em. de tecla"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sense retard"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminat"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Suggereix noms contactes"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilitza els noms de Contactes per a suggeriments i correccions"</string>
<string name="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configura diccionaris"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Correccions ràpides"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corregeix els errors d\'ortografia habituals"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Mostra els suggeriments de correcció"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostra sempre"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostra en mode vertical"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Amaga sempre"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Canvi d\'idioma amb la barra espaiadora"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostra la tecla de configuració"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automàtic"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostra sempre"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactiva"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Suggeriments Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Molt agressiu"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Suggeriments Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilitza la paraula anterior per millorar el suggeriment"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Predicció Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilitza també la paraula anterior per a la predicció"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Més"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Espera"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Suprimeix"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Retorn"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Configuració"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Majúscules"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Espai"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbols"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulador"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Entrada de veu"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Símbols activats"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Símbols desactivats"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Majúscules activades"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Majúscules desactivades"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"El text actual és %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"No s\'ha introduït cap text"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Clau de codi %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Maj"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Maj activat"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Bloq Maj activat"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Supr"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Símbols"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Lletres"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Números"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Configuració"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Pestanya"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Espai"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Entr. veu desactiv."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Selecciona el mètode d\'entrada"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Idiomes d\'entrada"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Feu lliscar el dit a la barra espaiadora per canviar l\'idioma"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Torna a tocar per desar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Diccionari disponible"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Toca per corregir paraules"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toca les paraules introduïdes per corregir-les, només quan els suggeriments siguin visibles"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema del teclat"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclat"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclat txec"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclat àrab"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclat danès"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclat alemany"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Teclat alemany QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclat anglès (Regne Unit)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Teclat anglès (Estats Units)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Teclat espanyol"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Teclat finès"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclat francès"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclat francès (Canadà)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclat francès (Suïssa)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Teclat croat"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Teclat hongarès"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclat hebreu"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclat italià"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclat noruec"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclat holandès"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclat polonès"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Teclat portuguès"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclat rus"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclat serbi"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclat suec"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Teclat turc"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Veu en afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Veu txeca"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Veu alemanya"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Veu xinesa (Yue)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Veu xinesa (mandarí)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Veu en zulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Mode d\'estudi d\'usabilitat"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'estudi d\'usabilitat"</string>
</resources>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index a8091bb57..5eb5d4bd2 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Obecné"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Oprava textu"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Oprava textu"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Návrhy na základě předchozích slov"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Další možnosti"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Pokročilá nastavení"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Možnosti pro zkušené uživatele"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Prodleva vysk. okna kláv."</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez prodlevy"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Výchozí"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhovat jména kontaktů"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Použít jména ze seznamu kontaktů k návrhům a opravám"</string>
<string name="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurovat slovníky"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Rychlé opravy"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje nejčastější chyby při psaní"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Zobrazit návrhy oprav"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vždy zobrazovat"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Zobrazit v režimu na výšku"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vždy skrývat"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Přepínání jazyků mezerníkem"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Zobrazit klávesu Nastavení"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaticky"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vždy zobrazovat"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Vypnuto"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mírné"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivní"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Návrh Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Velmi agresivní"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Návrhy Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Použít předchozí slovo ke zlepšení návrhu"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Odhady Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Použít předchozí slovo také pro odhad"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Další"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pauza"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Čekat"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Smazat"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Nastavení"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"mezera"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboly"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Karta"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Hlasový vstup"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symboly jsou zapnuty"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symboly jsou vypnuty"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Režim Shift je zapnutý"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Režim Shift je vypnutý"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Aktuální text je %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Není zadán žádný text"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Kód klávesy %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Klávesa Shift je aktivní"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Klávesa Caps Lock je aktivní"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboly"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Písmena"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Čísla"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Nastavení"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulátor"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Mezerník"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Hlasový vstup vypnut"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Výběr metody zadávání dat"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Vstupní jazyky"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Jazyk můžete změnit posunutím prstu po mezerníku."</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Dalším dotykem slovo uložíte"</string>
<string name="has_dictionary" msgid="6071847973466625007">"K dispozici je slovník"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Dotykem aktivovat opravy"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Klepnutím na zadaná slova tato slova opravíte, musí však být viditelné návrhy."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Motiv klávesnice"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Motiv klávesnice"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Klávesnice – čeština"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Klávesnice – arabština"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Klávesnice – dánština"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Klávesnice – němčina"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Německá klávesnice QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Klávesnice – angličtina (VB)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Klávesnice – angličtina (USA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Klávesnice – španělština"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finská klávesnice"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Klávesnice – francouzština"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Klávesnice – francouzština (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Klávesnice – francouzština (Švýc.)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Chorvatská klávesnice"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Maďarská klávesnice"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Klávesnice – hebrejština"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Klávesnice – italština"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Klávesnice – norština"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Klávesnice – holandština"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polská klávesnice"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugalská klávesnice"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Klávesnice – ruština"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Klávesnice – srbština"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Klávesnice – švédština"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turecká klávesnice"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voice – afrikánština"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voice – čeština"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voice – němčina"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voice – čínština, kantonština"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voice – čínština, mandarínština"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voice – zulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Režim studie použitelnosti"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim studie použitelnosti"</string>
</resources>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index 5c23ccf5f..0675bc15d 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetryk"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup ved tastetryk"</string>
<string name="general_category" msgid="1859088467017573195">"Generelt"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Tekstkorrigering"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Tekstkorrigering"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Forslag baseret på tidligere ord"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Andre valgmuligheder"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Avancerede indstillinger"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Muligheder for ekspertbrugere"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Forsink. afvis. af taste-popup"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Ingen forsink."</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå navne på kontaktpersoner"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Brug navne fra Kontaktpersoner til forslag og rettelser"</string>
<string name="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurer ordbøger"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Hurtige løsninger"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Retter almindelige stavefejl"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Vis rettelsesforslag"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vis altid"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Vis i portrættilstand"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Skjul altid"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Brug mellemrumst. som sprogskifter"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Vis indstillingsnøgle"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisk"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vis altid"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Fra"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Beskeden"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-forslag"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Meget aggressiv"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-forslag"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Brug forrige ord for at forbedre forslag"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram-forudsigelse"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Brug også tidligere ord til forudsigelse"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mere"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Vent"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Slet"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Tilbage"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Indstillinger"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Mellemrum"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboler"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Fane"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Stemmeinput"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symboler: Til"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symboler: Fra"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift: Til"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift: Fra"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Nuværende tekst er %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Der er ingen indtastet tekst"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Tastekode %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift-tast"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift-tasten er aktiveret"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock er aktiveret"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Slet"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboler"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Bogstaver"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Tal"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Indstillinger"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulatortast"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Mellemrum"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Stemmeinput deaktiveret"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Vælg inputmetode"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Inputsprog"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Træk fingeren på mellemrumstasten for at skifte sprog"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tryk igen for at gemme"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Ordbog er tilgængelig"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Tryk for at rette ord"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tryk på de indtastede ord for at rette dem. Kun når der er synlige forslag."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tastaturtema"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tjekkisk tastatur"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabisk tastatur"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dansk tastatur"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tysk tastatur"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Tysk QWERTY-tastatur"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelsk tastatur (Storbritannien)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Engelsk tastatur (USA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spansk tastatur"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finsk tastatur"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Fransk tastatur"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Fransk tastatur (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Fransk tastatur (Schweiz)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Kroatisk tastatur"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Ungarsk tastatur"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebraisk tastatur"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiensk tastatur"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norsk tastatur"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Hollandsk tastatur"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polsk tastatur"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugisisk tastatur"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russisk tastatur"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbisk tastatur"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svensk tastatur"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Tyrkisk tastatur"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikaans stemme"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Tjekkisk stemme"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Tysk stemme"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Kinesisk, Yue stemme"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Kinesisk, mandarin stemme"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu stemme"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Tilstand for brugsstudie"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tilstand for brugsstudie"</string>
</resources>
diff --git a/java/res/values-de-rZZ/donottranslate-altchars.xml b/java/res/values-de-rZZ/donottranslate-altchars.xml
new file mode 100644
index 000000000..a6f8fc810
--- /dev/null
+++ b/java/res/values-de-rZZ/donottranslate-altchars.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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="alternates_for_a">ä,â,à,á,æ,ã,å,ā</string>
+ <string name="alternates_for_e">3,ė</string>
+ <string name="alternates_for_o">9,ö,ô,ò,ó,õ,œ,ø,ō</string>
+ <string name="alternates_for_u">7,ü,û,ù,ú,ū</string>
+ <string name="alternates_for_s">ß,ś,š</string>
+ <string name="alternates_for_n">ñ,ń</string>
+ <string name="alternates_for_y">6</string>
+ <string name="alternates_for_z"></string>
+</resources>
diff --git a/java/res/values-sw600dp/donottranslate.xml b/java/res/values-de/config.xml
index 6d94c2811..272ff326f 100644
--- a/java/res/values-sw600dp/donottranslate.xml
+++ b/java/res/values-de/config.xml
@@ -17,7 +17,7 @@
** limitations under the License.
*/
-->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Default value of the visibility of the suggestion strip -->
- <string name="prefs_suggestion_visibility_default_value" translatable="false">1</string>
+
+<resources>
+ <bool name="config_require_umlaut_processing">true</bool>
</resources>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index 86adb915c..e837f1369 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Ton bei Tastendruck"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bei Tastendruck"</string>
<string name="general_category" msgid="1859088467017573195">"Allgemein"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Textkorrektur"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Textkorrektur"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Vorschläge basieren auf bisherigen Wörtern"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Sonstige Optionen"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Erweiterte Einstellungen"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Optionen für Experten"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Verzög. Schlüssel-Pop-up"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Keine Verzögerung"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Kontakte vorschlagen"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen aus \"Kontakte\" als Vorschläge und Korrekturmöglichkeiten anzeigen"</string>
<string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschr."</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Wörterbücher konfigurieren"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Quick Fixes"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Korrigiert gängige Tippfehler"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Änderungsvorschläge anzeigen"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Immer anzeigen"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Im Hochformat anzeigen"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Immer ausblenden"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Sprache mit Leertaste ändern"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Einstellungstaste anz."</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisch"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Immer anzeigen"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Aus"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mäßig"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Stark"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramm-Vorschläge"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sehr aggressiv"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramm-Vorschläge"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Zur Verbesserung des Vorschlags vorheriges Wort verwenden"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigramm-Vervollständigung"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Vorheriges Wort auch für Vervollständigung verwenden"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mehr"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Warten"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Löschen"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Eingabe"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Einstellungen"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Umschalt"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Leerzeichen"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbole"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Spracheingabe"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symbole an"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symbole aus"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Umschalt an"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Umschalt aus"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Aktueller Text lautet %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Kein Text eingegeben"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Tastencode %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Umschalttaste"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Umschalttaste aktiviert"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Feststelltaste aktiviert"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Entf"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbole"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Buchstaben"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Zahlen"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Einstellungen"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulator"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Leerzeichen"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Spracheingabe deaktiviert"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Eingabemethode auswählen"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Eingabesprachen"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Finger über die Leertaste bewegen, um die Eingabesprache zu wechseln"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Zum Speichern erneut berühren"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Wörterbuch verfügbar"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Wortkorrektur"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tippen Sie zum Korrigieren auf eingegebene Wörter (nur, wenn Vorschläge angezeigt werden)."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tastaturdesign"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tastaturdesign"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tschechische Tastatur"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabische Tastatur"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dänische Tastatur"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Deutsche Tastatur"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Deutsche QWERTZ-Tastaturbelegung"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Englische Tastatur (GB)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Englische Tastatur (USA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spanische Tastatur"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finnische Tastatur"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Französische Tastatur"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Französische Tastatur (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Französische Tastatur (Schweiz)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Kroatische Tastatur"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Ungarische Tastatur"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebräische Tastatur"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italienische Tastatur"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norwegische Tastatur"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Niederländische Tastatur"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polnische Tastatur"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugiesische Tastatur"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russische Tastatur"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbische Tastatur"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Schwedische Tastatur"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Türkische Tastatur"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Stimme in Afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Tschechische Sprache"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Deutsche Sprache"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Chinesische Stimme (Yue)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Chinesische Stimme (Mandarin)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Stimme in isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modus der Studie zur Benutzerfreundlichkeit"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus der Studie zur Benutzerfreundlichkeit"</string>
</resources>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 355d7a3c6..4a880fd42 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Ήχος κατά το πάτημα πλήκτρων"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Εμφάνιση με το πάτημα πλήκτρου"</string>
<string name="general_category" msgid="1859088467017573195">"Γενικά"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Διόρθωση κειμένου"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Διόρθωση κειμένου"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Προτάσεις που βασίζονται σε προηγούμενες λέξεις"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Άλλες επιλογές"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Σύνθετες ρυθμίσεις"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Επιλογές για έμπειρους χρήστες"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Χρόνος εξαφ. αναδ. παραθ."</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Χωρίς καθυστέρ."</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Προεπιλογή"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Πρόταση ονομάτων επαφών"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Χρησιμοποιήστε ονόματα από τις Επαφές για προτάσεις και διορθ."</string>
<string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Διαμόρφωση λεξικών"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Γρήγορες διορθώσεις"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Διορθώνει συνηθισμένα λάθη πληκτρολόγησης"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Εμφάνιση προτάσεων διόρθωσης"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"Χρησιμοποιήστε τη δυνατότητα εναλλαγής γλώσσας του πλήκτρου διαστήματος"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Εμφάνιση πλήκτρου ρυθμίσεων"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Αυτόματο"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Να εμφανίζεται πάντα"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Απενεργοποίηση"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Μέτρια"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Υψηλή"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Προτάσεις bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Πολύ επιθετική"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Προτάσεις bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Χρήση προηγούμενης λέξης για τη βελτίωση πρότασης"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Πρόβλεψη bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Χρησιμοποιήστε, επίσης, την προηγούμενη λέξη για πρόβλεψη"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Περισσότερα"</string>
<string name="label_pause_key" msgid="181098308428035340">"Παύση"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Αναμ."</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Ρυθμίσεις"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Κενό"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Σύμβολα"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Φωνητική εντολή"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Σύμβολα ενεργά"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Σύμβολα ανενεργά"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift ενεργό"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift ανενεργό"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Το τρέχον κείμενο είναι %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Δεν υπάρχει κείμενο"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Κωδικός πλήκτρου %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift ενεργοποιημένο"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock ενεργοποιημένο"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Πλήκτρο Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Σύμβολα"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Γράμματα:"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Αριθμοί"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Ρυθμίσεις"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Πλήκτρο Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Πλήκτρο διαστήματος"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Απεν. φωνητ. είσοδος"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Επιλογή μεθόδου εισόδου"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Γλώσσες εισόδου"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Σύρετε το δάχτυλο στο πλήκτρο διαστήματος για να αλλάξετε γλώσσα"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Αγγίξτε ξανά για αποθήκευση"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Λεξικό διαθέσιμο"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Ενεργοποίηση σχολίων χρηστών"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Βοηθήστε μας να βελτιώσουμε αυτό το πρόγραμμα επεξεργασίας μεθόδου εισόδου στέλνοντας αυτόματα στατιστικά στοιχεία και αναφορές σφαλμάτων στην Google."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"Αγγίξτε για διόρθωση λέξεων"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Αγγίξτε τις λέξες για να τις διορθώσετε, μόνο όταν οι προτάσεις είναι ορατές"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Θέμα πληκτρολογίου"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Θέμα πληκτρολογίου"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Τσεχικό πληκτρολόγιο"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Πληκτρολόγιο με αραβική γραφή"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Δανικό πληκτρολόγιο"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Γερμανικό πληκτρολόγιο"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Γερμανικό πληκτρολόγιο QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Αγγλικό (ΗΒ) πληκτρολόγιο"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Αγγλικό (ΗΠΑ) πληκτρολόγιο"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Ισπανικό πληκτρολόγιο"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Πληκτρ. με φινλανδικούς χαρακτήρες"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Γαλλικό πληκτρολόγιο"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Γαλλικό (Καναδάς) πληκτρολόγιο"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Γαλλικό (Ελβετία) πληκτρολόγιο"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Πληκτρολ. με κροατικούς χαρακτήρες"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Πληκτρολ. με ουγγρικούς χαρακτήρες"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Πληκτρολόγιο με εβραϊκή γραφή"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Ιταλικό πληκτρολόγιο"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Νορβηγικό πληκτρολόγιο"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Ολλανδικό πληκτρολόγιο"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Πληκτρολόγιο με πολωνικούς χαρακτήρες"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Πορτογαλικό πληκτρολόγιο"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ρωσικό πληκτρολόγιο"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Σερβικό πληκτρολόγιο"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Σουηδικό πληκτρολόγιο"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Πληκτρολόγιο με τουρκικούς χαρακτήρες"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Αφρικάανς"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Τσεχικά"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Γερμανικά"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Κινεζικά, Γιούε"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Κινεζικά, Μανδαρινικά"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Ζουλού"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Λειτουργία μελέτης χρηστικότητας"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Λειτουργία μελέτης χρηστικότητας"</string>
</resources>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 89a6a2e78..2987a46d2 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"General"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Text correction"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Text correction"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Suggestions based on previous words"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Other Options"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Advanced settings"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Options for expert users"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Key pop-up dismiss delay"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"No delay"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configure dictionaries"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Quick fixes"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrects commonly typed mistakes"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Show correction suggestions"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Always show"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Show on portrait mode"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Always hide"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Use the spacebar language switcher"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Show settings key"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatic"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Always show"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Off"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressive"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram Suggestions"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Very aggressive"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram Suggestions"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Use previous word to improve suggestion"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram prediction"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use previous word also for prediction"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"More"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Wait"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Settings"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Space"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbols"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Voice Input"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symbols on"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symbols off"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift on"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift off"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Current text is %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"No text entered"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Key code %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift enabled"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock enabled"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbols"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letters"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Numbers"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Settings"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Voice input is disabled"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Select input method"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Input languages"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Slide finger on spacebar to change language"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Touch again to save"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Touch to correct words"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Touch words entered to correct them, only when suggestions are visible"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Keyboard Theme"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Czech Keyboard"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabic Keyboard"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danish Keyboard"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"German Keyboard"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"German QWERTY Keyboard"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"English (UK) Keyboard"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"English (US) Keyboard"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spanish Keyboard"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finnish Keyboard"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"French Keyboard"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"French (Canada) Keyboard"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"French (Switzerland) Keyboard"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Croatian Keyboard"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Hungarian Keyboard"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrew Keyboard"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italian Keyboard"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norwegian Keyboard"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Dutch Keyboard"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polish keyboard"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portuguese Keyboard"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russian Keyboard"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbian Keyboard"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Swedish Keyboard"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turkish keyboard"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikaans Voice"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Czech Voice"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"German Voice"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Chinese, Yue Voice"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Chinese, Mandarin Voice"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu Voice"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Usability Study Mode"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Usability study mode"</string>
</resources>
diff --git a/java/res/values-en/whitelist.xml b/java/res/values-en/whitelist.xml
new file mode 100644
index 000000000..9395f4c88
--- /dev/null
+++ b/java/res/values-en/whitelist.xml
@@ -0,0 +1,38 @@
+<?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">
+ <!--
+ An entry of the whitelist word should be:
+ 1. (int)frequency
+ 2. (String)before
+ 3. (String)after
+ -->
+ <string-array name="wordlist_whitelist" translatable="false">
+
+ <item>255</item>
+ <item>ill</item>
+ <item>I\'ll</item>
+
+ <item>255</item>
+ <item>thisd</item>
+ <item>this\'d</item>
+
+ </string-array>
+</resources>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 9a45219b0..46c34350a 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"General"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Corrección de texto"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Corrección de texto"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Sugerencias sobre la base de palabras anteriores"</string>
+ <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_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="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configurar diccionarios"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Arreglos rápidos"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige errores de escritura comunes"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Mostrar sugerencias de correcciones"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar siempre"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar en modo retrato"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar siempre"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Usa select. de id. de barra espac."</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de configuración"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar siempre"</string>
@@ -45,8 +56,11 @@
<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>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Sugerencias de Vigoran"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muy agresivo"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Sugerencias de bigramas"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utiliza la palabra anterior para mejorar la sugerencia"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Predicción de biagramas"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usar la palabra anterior también para predicción."</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Más"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Espera"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Eliminar"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Volver"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Configuración"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Mayús"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Espacio"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Entrada de voz"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos activados"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desactivados"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Mayús activado"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Mayús desactivado"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"El texto actual es %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"No se ingresó texto."</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Clave de código %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Mayús"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Mayús habilitada"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Bloqueo de mayúsculas habilitado"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Borrar"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Símbolos"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letras"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Números"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Configuración"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Pestaña"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Espacio"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"La entrada por voz está inhabilitada"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Seleccionar método de entrada"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Deslizarse manualmente por la barra espaciadora para cambiar el idioma"</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_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="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corregir palabras"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toca las palabras ingresadas que desees corregir solo cuando las sugerencias estén visibles."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema del teclado"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclado"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado en checo"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado en danés"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado en alemán"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Teclado QWERTY alemán"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado en inglés (Reino Unido)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Teclado en inglés (EE.UU.)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Teclado en español"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Teclado finlandés"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado en francés"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado en francés (Canadá)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado en francés (Suiza)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Teclado croata"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Teclado húngaro"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebreo"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado en italiano"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado en noruego"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado en holandés"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado polaco"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Teclado en portugués"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado en ruso"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado en serbio"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado en sueco"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Teclado turco"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voz en Afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voz en checo"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voz en alemán"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voz en Yue, chino"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voz en mandarín, chino"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voz en isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modo estudio de usabilidad"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudio de usabilidad"</string>
</resources>
diff --git a/java/res/values-es/donottranslate-altchars.xml b/java/res/values-es/donottranslate-altchars.xml
index 99f1663a1..16111ec42 100644
--- a/java/res/values-es/donottranslate-altchars.xml
+++ b/java/res/values-es/donottranslate-altchars.xml
@@ -25,4 +25,6 @@
<string name="alternates_for_u">7,ú,ü,ù,û,ū</string>
<string name="alternates_for_n">ñ,ń</string>
<string name="alternates_for_c">ç,ć,č</string>
+ <string name="alternates_for_punctuation">"\\,,\?,!,¿,¡,:,-,\',\",),(,/,;,+,&amp;,\@"</string>
+ <string name="alternates_for_web_tab_punctuation">".,\\,,\?,!,¿,¡,:,-,\',\",),(,/,;,+,&amp;,\@"</string>
</resources>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 1e72a0c37..ea744b1f5 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Sonido al pulsar tecla"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup al pulsar tecla"</string>
<string name="general_category" msgid="1859088467017573195">"General"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Corrección ortográfica"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Corrección ortográfica"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Sugerencias basadas en palabras anteriores"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Otras opciones"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Ajustes avanzados"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opciones para usuarios expertos"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Retraso de rechazo"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sin retraso"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predeterminado"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nombres contactos"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nombres de contactos para sugerencias y correcciones"</string>
<string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configurar diccionarios"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Correcciones rápidas"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige los errores tipográficos que se cometen con más frecuencia."</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Mostrar sugerencias de correcciones"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar siempre"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar en modo vertical"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar siempre"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Utilizar espacio para cambiar idioma"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de ajustes"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automáticamente"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar siempre"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactivada"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Parcial"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Total"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Sugerencias de bigramas"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muy agresivo"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Sugerencias de bigramas"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palabra anterior para mejorar sugerencias"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Predicción de bigramas"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar también la palabra anterior para realizar la predicción"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Más"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Espera"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Eliminar"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Retroceso"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Ajustes"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Mayús"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Espacio"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulador"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Entrada de voz"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos activados"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desactivados"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Mayús activadas"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Mayús desactivadas"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"El texto actual es %s."</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"No se ha introducido texto."</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Código del teclado: %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Mayús"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Tecla Mayús habilitada"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Bloq Mayús habilitado"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Suprimir"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Símbolos"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letras"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Números"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Ajustes"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulador"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Barra espaciadora"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Entrada de voz inhabilitada"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Seleccionar método de introducción de texto"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Idiomas"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Deslizar el dedo por la barra espaciadora para cambiar el idioma"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Volver a tocar para guardar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Hay un diccionario disponible."</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corregir palabras"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toca las palabras introducidas para corregirlas, solo cuando las sugerencias sean visibles."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema de teclado"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema de teclado"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado checo"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado danés"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado alemán"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Teclado QWERTY alemán"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado inglés (Reino Unido)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Teclado de inglés (EE.UU.)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Teclado español"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Teclado finlandés"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado francés"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado francés (Canadá)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado francés (Suiza)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Teclado croata"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Teclado húngaro"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebreo"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado italiano"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado noruego"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado holandés"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado polaco"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Teclado portugués"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado ruso"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado serbio"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado sueco"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Teclado turco"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voz afrikáans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Google Voice en checo"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Google Voice en alemán"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voz china (cantonés)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voz china (mandarín)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voz zulú"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modo de estudio de uso"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudio de usabilidad"</string>
</resources>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index ceeee52d9..7cefe5b6c 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"صدا با فشار کلید"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"بازشو با فشار کلید"</string>
<string name="general_category" msgid="1859088467017573195">"کلی"</string>
- <string name="prediction_category" msgid="6361242011806282176">"تصحیح متن"</string>
+ <string name="correction_category" msgid="2236750915056607613">"تصحیح متن"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"پیشنهادهایی بر اساس کلمه های قبلی"</string>
+ <string name="misc_category" msgid="6894192814868233453">"سایر گزینه ها"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"تنظیمات پیشرفته"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"گزینه هایی برای کاربران حرفه ای"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"تأخیر در رد کردن کلید نمایشی"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"بدون تأخیر"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"پیش فرض"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"پیشنهاد نام های مخاطب"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"برای پیشنهاد و تصحیح از نام مخاطبین استفاده شود"</string>
<string name="auto_cap" msgid="1719746674854628252">"نوشتن با حروف بزرگ خودکار"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"پیکربندی لغت نامه ها"</string>
<string name="quick_fixes" msgid="5353213327680897927">"راه حل های سریع"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"تصحیح خطاهای تایپی رایج"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"نمایش پیشنهادات تصحیح"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"از ویژگی تعویض زبان کلید فاصله استفاده شود"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"نمایش کلید تنظیمات"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"خودکار"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"همیشه نمایش"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"خاموش"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"متوسط"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"فعال"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"توضیحات بیگرام"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"بسیار پرخاشگرانه"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"پیشنهادهای Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"برای بهبود پیشنهاد از کلمه قبلی استفاده شود"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"پیش بینی Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"استفاده از کلمه قبلی برای پیش بینی"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"بیشتر"</string>
<string name="label_pause_key" msgid="181098308428035340">"توقف موقت"</string>
<string name="label_wait_key" msgid="6402152600878093134">"منتظر بمانید"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"تنظیمات"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"فاصله"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"نمادها"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"ورودی صوتی"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"نمادها روشن"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"نمادها خاموش"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift روشن"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift خاموش"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"متن کنونی s% است"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"متنی وارد نشده است"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"کد کلید d%"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift فعال است"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock فعال شد"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"نمادها"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"حروف"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"اعداد"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"تنظیمات"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"فاصله"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"ورودی صدا غیرفعال است"</string>
<string name="selectInputMethod" msgid="315076553378705821">"انتخاب روش ورودی"</string>
<string name="language_selection_title" msgid="1651299598555326750">"زبان های ورودی"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"برای تغییر زبان انگشت را روی کلید فاصله بلغزانید"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← جهت ذخیره دوباره لمس کنید"</string>
<string name="has_dictionary" msgid="6071847973466625007">"دیکشنری موجود است"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"فعال کردن بازخورد کاربر"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"با ارسال خودکار آمارهای کاربرد و گزارش های خرابی به Google، به بهبود این ویرایشگر روش ورودی کمک کنید."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"برای تصحیح کلمات لمس کنید"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"فقط هنگامی که پیشنهادات قابل مشاهده هستند، برای تصحیح کلمات وارد شده آنها را لمس کنید"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"طرح زمینه صفحه کلید"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"طرح زمینه صفحه کلید"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"صفحه کلید چک"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"صفحه کلید عربی"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"صفحه کلید دانمارکی"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"صفحه کلید آلمانی"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"صفحه کلید QWERTY آلمانی"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"صفحه کلید انگلیسی (بریتانیایی)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"صفحه کلید انگلیسی (آمریکایی)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"صفحه کلید اسپانیایی"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"صفحه کلید فنلاندی"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"صفحه کلید فرانسوی"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"صفحه کلید فرانسوی (کانادایی)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"صفحه کلید فرانسوی (سوئیس)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"صفحه کلید کرواتی"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"صفحه کلید مجارستانی"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"صفحه کلید عبری"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"صفحه کلید ایتالیایی"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"صفحه کلید نروژی"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"صفحه کلید هلندی"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"صفحه کلید لهستانی"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"صفحه کلید پرتغالی"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"صفحه کلید روسی"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"صفحه کلید صربی"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"صفحه کلید سوئدی"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"صفحه کلید ترکی"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"صدای آفریکانس"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"صدای چک"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"صدای آلمانی"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"صدای چینی، یوئه"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"صدای چینی، ماندارین"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"صدای ایزی زولو"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"حالت تست قابلیت استفاده"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"حالت بررسی قابلیت استفاده"</string>
</resources>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index ee49c998f..ef47b2142 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Toista ääni näppäimiä painettaessa"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Ponnahdusikkuna painalluksella"</string>
<string name="general_category" msgid="1859088467017573195">"Yleinen"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Tekstin korjaus"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Tekstin korjaus"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Aiempiin sanoihin perustuvat ehdotukset"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Muut vaihtoehdot"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Lisäasetukset"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Valinnat kokeneille käyttäjille"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Näppäimen hylkäysviive"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Ei viivettä"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Oletus"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yhteystietojen nimiä"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Käytä yhteystietojen nimiä ehdotuksissa ja korjauksissa"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Määritä sanakirjat"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Pikakorjaukset"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Korjaa yleiset kirjoitusvirheet"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Näytä korjausehdotukset"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Näytä aina"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Näytä pystysuunnassa"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Piilota aina"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Vaihda kieli välil."</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Näytä asetukset-näppäin"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaattinen"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Näytä aina"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Älä käytä"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Osittainen"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Täysi"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-ehdotukset"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Hyvin aggressiivinen"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-ehdotukset"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Paranna ehdotusta aiemman sanan avulla"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram-ennakointi"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Käytä edellistä sanaa myös ennakointiin"</string>
<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">"Seuraava"</string>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Lisää"</string>
<string name="label_pause_key" msgid="181098308428035340">"Tauko"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Odota"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Poista"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Rivinvaihto"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Asetukset"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Välilyönti"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbolit"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Sarkain"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Äänisyöte"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symbolit käytössä"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symbolit pois käytöstä"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift käytössä"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift pois käytöstä"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Nykyinen teksti on %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Ei kirjoitettua tekstiä"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Näppäimen koodi %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift päällä"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock päällä"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Poisto"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbolit"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Kirjaimet"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Numerot"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Asetukset"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Sarkain"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Välilyönti"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Ääniohjaus on pois käytöstä"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Valitse syöttötapa"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Syöttökielet"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Vaihda kieltä liu\'uttamalla sormea välilyöntinäppäimellä"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tallenna koskettamalla uudelleen"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Sanakirja saatavilla"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Korjaa sanoja koskettamalla"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Korjaa annetut sanat napauttamalla. (Vain, kun ehdotuksia on näkyvillä.)"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Näppäimistön teema"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Näppäimistöteema"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Näppäimistö: tšekki"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabiankielinen näppäimistö"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Näppäimistö: tanska"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Näppäimistö: saksa"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Saksalainen QWERTY-näppäimistö"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Näppäimistö: englanti (UK)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Näppäimistö: englanti (US)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Näppäimistö: espanja"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Näppäimistö: suomi"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Näppäimistö: ranska"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Näppäimistö: ranska (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Näppäimistö: ranska (Sveitsi)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Näppäimistö: kroatia"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Näppäimistö: unkari"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hepreankielinen näppäimistö"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Näppäimistö: italia"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Näppäimistö: norja"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Näppäimistö: hollanti"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Näppäimistö: puola"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Näppäimistö: portugali"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Näppäimistö: venäjä"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Näppäimistö: serbia"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Näppäimistö: ruotsi"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Näppäimistö: turkki"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Ääni: afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Ääni: tšekki"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Ääni: saksa"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Ääni: kiina, yue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Ääni: mandariinikiina"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Ääni: isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Käytettävyystutkimustila"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Käytettävyystutkimustila"</string>
</resources>
diff --git a/java/res/values-fr/donottranslate-altchars.xml b/java/res/values-fr/donottranslate-altchars.xml
index e01f63f14..ae9292f91 100644
--- a/java/res/values-fr/donottranslate-altchars.xml
+++ b/java/res/values-fr/donottranslate-altchars.xml
@@ -18,11 +18,11 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="alternates_for_a">1,à,â,æ,á,ä,ã,å,ā,ª</string>
- <string name="alternates_for_e">3,é,è,ê,ë,ę,ė,ē</string>
- <string name="alternates_for_i">8,î,ï,ì,í,į,ī</string>
- <string name="alternates_for_o">9,ô,œ,ö,ò,ó,õ,ø,ō,º</string>
- <string name="alternates_for_u">7,û,ù,ü,ú,ū</string>
+ <string name="alternates_for_a">à,â,1,æ,á,ä,ã,å,ā,ª</string>
+ <string name="alternates_for_e">é,è,ê,ë,3,ę,ė,ē</string>
+ <string name="alternates_for_i">î,8,ï,ì,í,į,ī</string>
+ <string name="alternates_for_o">ô,œ,9,ö,ò,ó,õ,ø,ō,º</string>
+ <string name="alternates_for_u">ù,û,7,ü,ú,ū</string>
<string name="alternates_for_c">ç,ć,č</string>
<string name="alternates_for_y">6,ÿ</string>
<string name="alternates_for_q"></string>
diff --git a/java/res/values-fr/donottranslate.xml b/java/res/values-fr/donottranslate.xml
index 6c3536210..09c37e31a 100644
--- a/java/res/values-fr/donottranslate.xml
+++ b/java/res/values-fr/donottranslate.xml
@@ -18,8 +18,12 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Symbols that are commonly considered word separators in this language -->
- <string name="word_separators">.\u0009\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
- <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
- <string name="sentence_separators">.,</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 -->
+ <string name="magic_space_stripping_symbols">\u0009\u0020\u0027\n-/_</string>
+ <!-- Symbols that should promote magic spaces into real space -->
+ <string name="magic_space_promoting_symbols">;:!?([*&amp;@{&lt;&gt;+=|</string>
+ <!-- Symbols that do NOT separate words -->
+ <string name="non_word_separator_symbols">\u0027</string>
</resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 59a1387cf..004aac76a 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Son à chaque touche"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Agrandir les caractères"</string>
<string name="general_category" msgid="1859088467017573195">"Général"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Correction du texte"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Correction du texte"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Suggestions basées sur les mots précédents"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Autres options"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Paramètres avancés"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Options destinées aux utilisateurs expérimentés"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Délai masq. touche pop-up"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Aucun délai"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Par défaut"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string>
<string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configurer les dictionnaires"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Corrections rapides"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige les fautes de frappe courantes"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Afficher les suggestions de correction"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Toujours afficher"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Afficher en mode Portrait"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Toujours masquer"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Barre d\'espace pour changer langue"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Afficher touche param."</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatique"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Toujours afficher"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Désactiver"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Simple"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Proactive"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Suggestions de type bigramme"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Très exigeante"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Suggestions de type bigramme"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Améliorer la suggestion en fonction du mot précédent"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Prédiction bigramme"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utiliser le mot précédent pour la prédiction"</string>
<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">"Suivant"</string>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Plus"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Attente"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Supprimer"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Entrée"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Paramètres"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Maj"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Espace"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboles"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulation"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Saisie vocale"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symboles activés"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symboles désactivés"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Maj activée"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Maj désactivée"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Le texte actuel est %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Aucun texte saisi"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Code touche %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Maj"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Touche Maj activée"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Verrouillage des majuscules activé"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Supprimer"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboles"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Lettres"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Chiffres"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Paramètres"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulation"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Espace"</string>
+ <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">"Aux bons soins 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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Saisie vocale désactivée"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Sélectionner un mode de saisie."</string>
<string name="language_selection_title" msgid="1651299598555326750">"Langues de saisie"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Faites glisser votre doigt sur la barre d\'espacement pour changer la langue."</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Appuyer de nouveau pour enregistrer"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Appuyer pour corriger"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Appuyer sur les mots saisis pour les corriger, uniquement lorsque des suggestions sont visibles"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Thème du clavier"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Clavier tchèque"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Clavier arabe"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Clavier danois"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Clavier allemand"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Clavier QWERTY allemand"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Clavier anglais (Royaume-Uni)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Clavier anglais (États-Unis)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Clavier espagnol"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Clavier finnois"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Clavier français"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Clavier français (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Clavier français (Suisse)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Clavier croate"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Clavier hongrois"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Clavier hébreu"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Clavier italien"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Clavier norvégien"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Clavier néerlandais"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Clavier polonais"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Clavier portugais"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Clavier russe"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Clavier serbe"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Clavier suédois"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Clavier turc"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voix parlant afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voix tchèque"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voix allemande"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voix parlant chinois (cantonais)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voix parlant chinois (mandarin)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voix parlant zoulou"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Mode d\'étude de l\'utilisation"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'étude de l\'utilisation"</string>
</resources>
diff --git a/java/res/values-sw768dp/donottranslate.xml b/java/res/values-hdpi/config.xml
index 672dea589..7333e9449 100644
--- a/java/res/values-sw768dp/donottranslate.xml
+++ b/java/res/values-hdpi/config.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.
@@ -17,7 +17,8 @@
** limitations under the License.
*/
-->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Default value of the visibility of the suggestion strip -->
- <string name="prefs_suggestion_visibility_default_value" translatable="false">2</string>
+
+<resources>
+ <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" -->
+ <integer name="log_screen_metrics">1</integer>
</resources>
diff --git a/java/res/values-hr/donottranslate-altchars.xml b/java/res/values-hr/donottranslate-altchars.xml
new file mode 100644
index 000000000..d0c9d4049
--- /dev/null
+++ b/java/res/values-hr/donottranslate-altchars.xml
@@ -0,0 +1,27 @@
+<?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="alternates_for_s">š,ś,ß</string>
+ <string name="alternates_for_n">ñ,ń</string>
+ <string name="alternates_for_y"></string>
+ <string name="alternates_for_z">6,ž,ź,ż</string>
+ <string name="alternates_for_c">č,ć,ç</string>
+ <string name="alternates_for_d">đ</string>
+</resources>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 1ff4ba21a..09a9879eb 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Općenito"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Ispravak teksta"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Ispravak teksta"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Prijedlozi na temelju prethodnih riječi"</string>
+ <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_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>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Upotreba imena iz Kontakata za prijedloge i ispravke"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfiguracija rječnika"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Brzi popravci"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Ispravlja uobičajene pogreške u pisanju"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Pokaži prijedloge ispravka"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Uvijek prikaži"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Prikaži u portretnom načinu"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Uvijek sakrij"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Upotrijebite razmaknicu za prebacivanje jezika"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Prikaži tipku postavki"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatski"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Uvijek prikaži"</string>
@@ -45,8 +56,11 @@
<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>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram prijedlozi"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Vrlo agresivno"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram prijedlozi"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Upotrijebi prethodnu riječ radi poboljšanja prijedloga"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram predviđanje"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Upotrijebite prethodnu riječ i za predviđanje"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Više"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pauza"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Pričekaj"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Postavke"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Razmaknica"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboli"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulator"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Glasovni unos"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simboli uključeni"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simboli isključeni"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift uključen"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift isključen"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Trenutačni tekst je %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nije unesen tekst"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Kôd tipke %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift je omogućen"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock omogućen"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboli"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Slova"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Brojevi"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Postavke"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Kartica"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Razmaknica"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Glas. unos onemog."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Odabir ulazne metode"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Jezici unosa"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Kliznite prstom po razmaknici za promjenu jezika"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Dodirnite opet za spremanje"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Rječnik je dostupan"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Dodirnite za ispravak riječi"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dodirnite unesene riječi da biste ih ispravili samo kada su prijedlozi vidljivi"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema tipkovnice"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Češka tipkovnica"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arapska tipkovnica"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danska tipkovnica"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Njemačka tipkovnica"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Njemačka QWERTY tipkovnica"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engleska (UK) tipkovnica"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Engleska (SAD) tipkovnica"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Španjolska tipkovnica"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finska tipkovnica"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Francuska tipkovnica"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Francuska (Kanada) tipkovnica"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Francuska (Švicarska) tipkovnica"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Hrvatska tipkovnica"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Mađarska tipkovnica"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrejska tipkovnica"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Talijanska tipkovnica"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norveška tipkovnica"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nizozemska tipkovnica"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poljska tipkovnica"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugalska tipkovnica"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ruska tipkovnica"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Srpska tipkovnica"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Švedska tipkovnica"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turska tipkovnica"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"afrikaans glasovno"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Češki glasovni"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Njemački glasovni"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"kineski, Yue glasovno"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"kineski, mandarinski glasovno"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu glasovno"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Način studije upotrebljivosti"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način studije upotrebljivosti"</string>
</resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index 923103bce..e0b80dc79 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Általános"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Szövegjavítás"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Szövegjavítás"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Javaslatok korábbi szavak alapján"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Egyéb beállítások"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Speciális beállítások"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Beállítások gyakorlott felhasználóknak"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Gombeltüntetés késése"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Nincs késés"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Alapbeállítás"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Javasolt névjegyek"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"A névjegyek használata a javaslatokhoz és javításokhoz"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Szótárak konfigurálása"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Gyorsjavítások"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Kijavítja a gyakori gépelési hibákat"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Javítási ajánlások megjelenítése"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mindig látszik"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Megjelenítés álló tájolásban"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Mindig rejtve"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Nyelvváltó: szóköz"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Beállítások billentyű megjelenítése"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatikus"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mindig látszik"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Ki"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mérsékelt"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresszív"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram javaslatok"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Nagyon agresszív"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram javaslatok"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Előző szó használata a javaslatok javításához"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram előrejelzés"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Az előző szó használata a prediktív bevitelhez is"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Egyebek"</string>
<string name="label_pause_key" msgid="181098308428035340">"Szün."</string>
<string name="label_wait_key" msgid="6402152600878093134">"Vár"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Törlés"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Vissza"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Beállítások"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Szóköz"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Szimbólumok"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Hangbevitel"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Szimbólumok be"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Szimbólumok ki"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift be"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift ki"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"A jelenlegi szöveg: %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Szöveg nincs megadva"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Billentyűkód: %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift engedélyezve"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock bekapcsolva"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Törlés"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Szimbólumok"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Betűk"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Számok"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Beállítások"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Szóköz"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Hangbevivel KI"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Beviteli mód kiválasztása"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Beviteli nyelvek"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"A nyelv módosításához húzza végig az ujját a szóköz billentyűn"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Érintse meg újra a mentéshez"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Van elérhető szótár"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Javítás a szavak megérintésével"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"A beírt szavakat csak akkor javíthatja ki megérintve, ha látszanak javaslatok"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Billentyűzettéma"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Billentyűzettéma"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Cseh billentyűzet"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arab billentyűzet"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dán billentyűzet"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Német billentyűzet"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Német QWERTY billentyűzet"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Angol (UK) billentyűzet"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Angol (US) billentyűzet"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spanyol billentyűzet"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finn billentyűzet"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Francia billentyűzet"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Francia (kanadai) billentyűzet"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Francia (svájci) billentyűzet"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Horvát billentyűzet"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Magyar billentyűzet"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Héber billentyűzet"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Olasz billentyűzet"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norvég billentyűzet"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Holland billentyűzet"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Lengyel billentyűzet"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugál billentyűzet"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Orosz billentyűzet"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Szerb billentyűzet"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svéd billentyűzet"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Török billentyűzet"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikaans hang"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Cseh hang"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Német hang"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Kínai (jüe) hang"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Kínai (mandarin) hang"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu hang"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Használhatóság - tanulás mód"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Használhatósági teszt"</string>
</resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 3322109c4..bfc94684a 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Berbunyi jika tombol ditekan"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Muncul saat tombol ditekan"</string>
<string name="general_category" msgid="1859088467017573195">"Umum"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Koreksi teks"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Koreksi teks"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Saran berdasarkan kata sebelumnya"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Opsi lain"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Setelan lanjutan"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Pilihan untuk pengguna ahli"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Tundaan singkir munculan kunci"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Tanpa penundaan"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Bawaan"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Sarankan nama Kenalan"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama dari Kenalan untuk saran dan koreksi"</string>
<string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurasikan kamus"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Perbaikan cepat"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Memperbaiki kesalahan ketik umum"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Tampilkan saran koreksi"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Selalu tampilkan"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Tampilkan pada mode potret"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Selalu sembunyikan"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Gunakan pengalih bahasa bilah spasi"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Lihat tombol setelan"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Otomatis"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Selalu tampilkan"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Mati"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Saran Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sangat agresif"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Saran bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gunakan kata sebelumnya untuk meningkatkan sara"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Prediksi bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan kata sebelumnya juga untuk prediksi"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Lainnya"</string>
<string name="label_pause_key" msgid="181098308428035340">"Jeda"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Tunggu"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Hapus"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Setelan"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Spasi"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simbol"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Masukan Suara"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simbol hidup"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simbol mati"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift hidup"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift mati"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Teks saat ini adalah %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Tidak ada teks yang dimasukkan"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Kode tombol %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift diaktifkan"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock diaktifkan"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Hapus"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simbol"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Huruf"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Angka"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Setelan"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Spasi"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Masukan suara dinonaktifkan"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Pilih metode masukan"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Bahasa masukan"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Geser jari pada bilah spasi untuk mengubah bahasa"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Sentuh sekali lagi untuk menyimpan"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Kamus yang tersedia"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Sentuh untuk memperbaiki kata"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Sentuh kata yang dimasukkan untuk memperbaikinya, hanya saat saran dapat dilihat"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema Keyboard"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema keyboard"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Keyboard Cheska"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Papan Tombol Arab"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Keyboard Denmark"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Keyboard Jerman"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Keyboard QWERTY Jerman"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Keyboard Inggris (Britania Raya)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Keyboard Inggris (AS)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Keyboard Spanyol"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Keyboard Suomi"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Keyboard Prancis"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Keyboard Prancis (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Keyboard Prancis (Swiss)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Keyboard Kroat"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Keyboard Magyar"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Papan tombol Ibrani"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Keyboard Italia"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Keyboard Norwegia"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Keyboard Belanda"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Keyboard bahasa Polski"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Keyboard Portugis"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Keyboard Rusia"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Keyboard Serbia"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Keyboard Swedia"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Keyboard Bahasa Turki"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Suara Bahasa Afrika"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Suara Bahasa Cheska"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Suara Bahasa Jerman"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Suara Bahasa China, Yue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Suara Bahasa China, Mandarin"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Suara Zulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Mode Studi Daya Guna"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode studi daya guna"</string>
</resources>
diff --git a/java/res/values-it/donottranslate.xml b/java/res/values-it/donottranslate.xml
index 3e3f3ef2a..adb2a9a9d 100644
--- a/java/res/values-it/donottranslate.xml
+++ b/java/res/values-it/donottranslate.xml
@@ -18,6 +18,6 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Symbols that are commonly considered word separators in this language -->
- <string name="word_separators">.\u0009\u0020,;:!?\'\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
+ <!-- Symbols that do NOT separate words -->
+ <string name="non_word_separator_symbols"></string>
</resources>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 337a04e07..da1b001eb 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Suono tasti"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup sui tasti"</string>
<string name="general_category" msgid="1859088467017573195">"Generali"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Correzione testo"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Correzione testo"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Suggerimenti in base alle parole precedenti"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Altre opzioni"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Impostazioni avanzate"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opzioni per utenti esperti"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Ritardo eliminaz. popup tasto"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Nessun ritardo"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinito"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Suggerisci nomi di contatti"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizza nomi di Contatti per suggerimenti e correzioni"</string>
<string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configura dizionari"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Correzioni veloci"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corregge gli errori di digitazione più comuni"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Mostra suggerimenti correzioni"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostra sempre"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostra in modalità verticale"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Nascondi sempre"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Selettore lingua da barra spaziatrice"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostra tasto impostaz."</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatico"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostra sempre"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Off"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Media"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Massima"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Suggerimenti sui bigrammi"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Massima"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Suggerimenti sui bigrammi"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizza parola precedente per migliorare il suggerimento"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Previsione bigramma"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Usa anche la parola precedente per la previsione"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Altro"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Attesa"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Cancella"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Invio"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Impostazioni"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Maiuscolo"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Spazio"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboli"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulazione"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Input vocale"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simboli attivati"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simboli disattivati"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Maiuscole attivate"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Maiuscole disattivate"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Il testo attuale è %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nessun testo inserito"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Codice tasto %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Maiuscolo"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Maiuscolo attivo"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Blocco maiuscole attivo"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Cancella"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboli"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Lettere"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Numeri"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Impostazioni"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulazione"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Spazio"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Comandi vocali disatt."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Seleziona metodo di inserimento"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Lingue comandi"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Scorri il dito sulla barra spaziatrice per cambiare la lingua"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tocca di nuovo per salvare"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dizionario disponibile"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Tocca per correggere"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tocca le parole inserite per correggerle, solo quando sono visibili i suggerimenti"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema della tastiera"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema della tastiera"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tastiera ceca"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Tastiera araba"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Tastiera danese"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tastiera tedesca"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Tastiera QWERTY tedesca"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Tastiera inglese (Regno Unito)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Tastiera inglese (Stati Uniti)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Tastiera spagnola"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Tastiera finlandese"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Tastiera francese"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Tastiera francese (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Tastiera francese (Svizzera)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Tastiera croata"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Tastiera ungherese"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Tastiera ebraica"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Tastiera italiana"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Tastiera norvegese"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Tastiera olandese"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Tastiera polacca"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Tastiera portoghese"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Tastiera russa"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Tastiera serba"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Tastiera svedese"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Tastiera turca"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voce afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voce ceca"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voce tedesca"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voce cinese Yue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voce cinese mandarino"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voce isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modalità studio usabilità"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modalità Studio sull\'usabilità"</string>
</resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index e71ab56c3..15f54d615 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"צלילים עם לחיצה על מקשים"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"חלון קופץ עם לחיצה על מקשים"</string>
<string name="general_category" msgid="1859088467017573195">"כללי"</string>
- <string name="prediction_category" msgid="6361242011806282176">"תיקון טקסט"</string>
+ <string name="correction_category" msgid="2236750915056607613">"תיקון טקסט"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"הצעות המבוססות על מילים קודמות"</string>
+ <string name="misc_category" msgid="6894192814868233453">"אפשרויות אחרות"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"הגדרות מתקדמות"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"אפשרויות עבור משתמשים מתקדמים"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"עיכוב דחייה של מוקפץ ראשי"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ללא עיכוב"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ברירת מחדל"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"הצע שמות של אנשי קשר"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"השתמש בשמות מאנשי קשר עבור הצעות ותיקונים"</string>
<string name="auto_cap" msgid="1719746674854628252">"הפיכה אוטומטית של אותיות לרישיות"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"הגדרת מילונים"</string>
<string name="quick_fixes" msgid="5353213327680897927">"תיקונים מהירים"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"מתקן שגיאות הקלדה נפוצות"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"הצג הצעות לתיקונים"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"השתמש במחליף השפה שבמקש הרווח"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"הצג מקש הגדרות"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"אוטומטי"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"הצג תמיד"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"כבוי"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"מצומצם"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"מחמיר"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"הצעות של צמדי אותיות (Bigram)"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"אגרסיבי מאוד"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"הצעות של צמדי אותיות (Bigram)"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"השתמש במילה הקודמת כדי לשפר את ההצעה"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"חיזוי צמדי אותיות (Bigram)"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"השתמש במילה הקודמת גם עבור חיזוי"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"עוד"</string>
<string name="label_pause_key" msgid="181098308428035340">"השהה"</string>
<string name="label_wait_key" msgid="6402152600878093134">"המתן"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"מחק"</string>
- <string name="description_return_key" msgid="8750044000806461678">"חזור"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"הגדרות"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"רווח"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"סמלים"</string>
- <string name="description_tab_key" msgid="828186583738307137">"כרטיסייה"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"קלט קולי"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"מצב סמלים פועל"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"מצב סמלים כבוי"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift פועל"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift כבוי"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"הטקסט הנוכחי הוא %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"לא הוזן טקסט"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"קוד מקש %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift מופעל"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock מופעל"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"מחק"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"סמלים"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"אותיות"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"מספרים"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"הגדרות"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"טאב"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"רווח"</string>
+ <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">"מדיניות הפרטיות של \'Google לנייד\'"</a>" חלה במקרה זה."</string>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"הקלט הקולי מושבת"</string>
<string name="selectInputMethod" msgid="315076553378705821">"בחר שיטת קלט"</string>
<string name="language_selection_title" msgid="1651299598555326750">"שפות קלט"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"החלק את האצבע על מקש הרווח כדי לשנות שפה"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← גע שוב כדי לשמור"</string>
<string name="has_dictionary" msgid="6071847973466625007">"מילון זמין"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"הפוך משוב ממשתמשים לפעיל"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"עזור לשפר שיטת קלט זו על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסת מחשב ל-Google."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"גע כדי לתקן מילים"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"גע במילים שהוזנו כדי לתקן אותן, רק כאשר הצעות מוצגות"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"עיצוב מקלדת"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"עיצוב מקלדת"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"מקלדת צ\'כית"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"מקלדת בשפה הערבית"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"מקלדת דנית"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"מקלדת גרמנית "</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"מקלדת QWERTY גרמנית"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"מקלדת אנגלית (בריטניה)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"מקלדת אנגלית (ארה\"ב)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"מקלדת ספרדית"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"מקלדת פינית"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"מקלדת צרפתית"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"מקלדת צרפתית (קנדה)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"מקלדת צרפתית (שוויץ)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"מקלדת קרואטית"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"מקלדת הונגרית"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"מקלדת בשפה העברית"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"מקלדת איטלקית"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"מקלדת נורווגית"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"מקלדת הולנדית"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"מקלדת פולנית"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"מקלדת פורטוגזית"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"מקלדת רוסית"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"מקלדת סרבית"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"מקלדת שוודית"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"מקלדת טורקית"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Google Voice באפריקאנס"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Google Voice צ\'כי"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Google Voice גרמני"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Google Voice בסינית, יו"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Google Voice בסינית, מנדרינית"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Google Voice באיסיזולו"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"מצב מחקר שימושיות"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"מצב מחקר שימושיות"</string>
</resources>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 5d82a453b..6f903e8e5 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"キー操作音"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"キー押下時ポップアップ"</string>
<string name="general_category" msgid="1859088467017573195">"全般"</string>
- <string name="prediction_category" msgid="6361242011806282176">"テキストの修正"</string>
+ <string name="correction_category" msgid="2236750915056607613">"テキストの修正"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"前の語句に基づいた入力候補表示"</string>
+ <string name="misc_category" msgid="6894192814868233453">"他のオプション"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"詳細設定"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"上級ユーザー向けオプション"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"キーのポップアップ時間"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"すぐに消去"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"デフォルト"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"候補の連絡先名を表示"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"連絡先の名前を使用して候補表示や自動修正を行います"</string>
<string name="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"辞書を設定"</string>
<string name="quick_fixes" msgid="5353213327680897927">"クイックフィックス"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"よくある誤字・脱字を修正します"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"修正候補を表示する"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"スペースバーで切替"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"設定キーを表示"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自動"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"常に表示"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"OFF"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"中"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"強"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"バイグラム入力候補表示"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"最強"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"バイグラム入力候補表示"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"直前の単語から入力候補を予測します"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"バイグラム予測"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"前の語句も予測に使用"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Shift"</string>
<string name="label_pause_key" msgid="181098308428035340">"停止"</string>
<string name="label_wait_key" msgid="6402152600878093134">"待機"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Del"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"設定"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Space"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"記号"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"音声入力"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"記号ON"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"記号OFF"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift ON"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift OFF"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"現在のテキスト:%s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"テキストが入力されていません"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"キーコード:%d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift有効"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock有効"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"DEL"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"記号"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"英字"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"数字"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"設定"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"音声入力は無効です"</string>
<string name="selectInputMethod" msgid="315076553378705821">"入力方法の選択"</string>
<string name="language_selection_title" msgid="1651299598555326750">"入力言語"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"スペースバーで指をスライドさせて言語を変更する"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"←保存するにはもう一度タップ"</string>
<string name="has_dictionary" msgid="6071847973466625007">"辞書を利用できます"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"ユーザーフィードバックを有効にする"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"IMEの機能向上のため、使用統計状況やクラッシュレポートをGoogleに自動送信します。"</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"タップして語句を修正"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"候補が表示されているときのみ、入力した語句をタップして修正する"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"キーボードテーマ"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"キーボードのテーマ"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"チェコ語のキーボード"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"アラビア語のキーボード"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"デンマーク語のキーボード"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"ドイツ語のキーボード"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"ドイツ語QWERTYキーボード"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"英語(英国)のキーボード"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"英語(米国)のキーボード"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"スペイン語のキーボード"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"フィンランド語キーボード"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"フランス語のキーボード"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"フランス語(カナダ)のキーボード"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"フランス語(スイス)のキーボード"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"クロアチア語キーボード"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"ハンガリー語キーボード"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"ヘブライ語のキーボード"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"イタリア語のキーボード"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"ノルウェー語のキーボード"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"オランダ語のキーボード"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"ポーランド語のキーボード"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"ポルトガル語のキーボード"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"ロシア語のキーボード"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"セルビア語のキーボード"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"スウェーデン語のキーボード"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"トルコ語のキーボード"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"アフリカーンス語の音声"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"チェコ語の音声"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"ドイツ語の音声"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"中国語(広東語)の音声"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"中国語(標準語)の音声"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"ズールー語の音声"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"使いやすさの研究モード"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"使いやすさの研究モード"</string>
</resources>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index 2cf0ec2aa..34c37fe18 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"키를 누를 때 소리 발생"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"키를 누를 때 팝업"</string>
<string name="general_category" msgid="1859088467017573195">"일반"</string>
- <string name="prediction_category" msgid="6361242011806282176">"텍스트 수정"</string>
+ <string name="correction_category" msgid="2236750915056607613">"텍스트 수정"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"이전 단어에 기반한 추천"</string>
+ <string name="misc_category" msgid="6894192814868233453">"기타 옵션"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"고급 설정"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"전문 사용자용 옵션"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"키 팝업 해제 지연"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"지연 없음"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"기본값"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"연락처 이름 추천"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"추천 및 수정에 주소록의 이름 사용"</string>
<string name="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"사전 설정"</string>
<string name="quick_fixes" msgid="5353213327680897927">"빠른 수정"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"자주 발생하는 오타를 수정합니다."</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"수정 제안 표시"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"스페이스 바 언어 교환기 사용"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"설정 키 표시"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"자동"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"항상 표시"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"사용 안함"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"보통"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"적극적"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram 추천"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"매우 적극적"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram 추천"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"이전 단어를 사용하여 추천 기능 개선"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram 예측"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"이전 단어를 사용하여 예상 검색어를 표시합니다."</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"더보기"</string>
<string name="label_pause_key" msgid="181098308428035340">"일시 중지"</string>
<string name="label_wait_key" msgid="6402152600878093134">"대기"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"삭제"</string>
- <string name="description_return_key" msgid="8750044000806461678">"리턴"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"설정"</string>
- <string name="description_shift_key" msgid="346906866277787836">"시프트"</string>
- <string name="description_space_key" msgid="8512130111575878517">"스페이스"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"기호"</string>
- <string name="description_tab_key" msgid="828186583738307137">"탭"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"음성 입력"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"기호 사용"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"기호 사용 안함"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"시프트 사용"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"시프트 사용 안함"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"입력한 텍스트: %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"입력한 텍스트 없음"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"키 코드 %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"시프트 키"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift 키 누름"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock 키 켜짐"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"삭제 키"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"기호"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"문자"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"숫자"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"설정"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"탭"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"스페이스"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"음성 입력이 사용 중지됨"</string>
<string name="selectInputMethod" msgid="315076553378705821">"입력 방법 선택"</string>
<string name="language_selection_title" msgid="1651299598555326750">"입력 언어"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"손가락을 스페이스바에서 미끄러지듯 움직여 언어 변경"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← 저장하려면 다시 터치하세요."</string>
<string name="has_dictionary" msgid="6071847973466625007">"사전 사용 가능"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"사용자 의견 사용"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"사용 통계 및 충돌 보고서를 Google에 자동으로 전송하여 입력 방법 편집기의 개선에 도움을 줍니다."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"터치하여 단어 수정"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"입력한 단어를 터치하여 수정(추천 단어가 표시되는 경우에만)"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"키보드 테마"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"키보드 테마"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"체코어 키보드"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"아랍어 키보드"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"덴마크어 키보드"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"독일어 키보드"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"독일어 QWERTY 키보드"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"영어(영국) 키보드"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"영어(미국) 키보드"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"스페인어 키보드"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"핀란드어 키보드"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"프랑스어 키보드"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"프랑스어(캐나다) 키보드"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"프랑스어(스위스) 키보드"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"크로아티아어 키보드"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"헝가리어 키보드"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"히브리어 키보드"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"이탈리아어 키보드"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"노르웨이어 키보드"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"네덜란드어 키보드"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"폴란드어 키보드"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"포르투갈어 키보드"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"러시아어 키보드"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"세르비아어 키보드"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"스웨덴어 키보드"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"터키어 키보드"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"아프리칸스어 음성"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"체코어 음성"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"독일어 음성"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"중국어, 광둥어 음성"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"중국어, 북경어 음성"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"줄루어 음성"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"가용성 연구 모드"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"가용성 연구 모드"</string>
</resources>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index 7df124bfc..73e1aff96 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -19,20 +19,50 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
- <dimen name="keyboardHeight">1.060in</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.260in -->
+ <dimen name="keyboardHeight">1.100in</dimen>
+ <fraction name="minKeyboardHeight">45%p</fraction>
<!-- key_height + key_bottom_gap = popup_key_height -->
-<!-- <dimen name="key_height">0.250in</dimen>-->
- <dimen name="key_bottom_gap">0.020in</dimen>
- <dimen name="popup_key_height">0.270in</dimen>
- <dimen name="keyboard_top_padding">0.0in</dimen>
- <dimen name="keyboard_bottom_padding">0.0in</dimen>
- <dimen name="candidate_strip_height">38dip</dimen>
+<!-- <dimen name="key_height">0.260in</dimen>-->
+ <dimen name="popup_key_height">0.280in</dimen>
+ <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen>
+
+ <fraction name="keyboard_top_padding">1.818%p</fraction>
+ <fraction name="keyboard_bottom_padding">0.0%p</fraction>
+ <fraction name="key_bottom_gap">4.330%p</fraction>
+ <fraction name="key_horizontal_gap">0.405%p</fraction>
+
+ <dimen name="keyboardHeight_stone">0.984in</dimen>
+ <fraction name="key_bottom_gap_stone">5.010%p</fraction>
+ <fraction name="key_horizontal_gap_stone">1.159%p</fraction>
+
+ <fraction name="key_bottom_gap_gb">5.941%p</fraction>
+ <fraction name="key_horizontal_gap_gb">0.997%p</fraction>
+
+ <fraction name="keyboard_top_padding_ics">2.727%p</fraction>
+ <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
+ <fraction name="key_bottom_gap_ics">5.368%p</fraction>
+ <fraction name="key_horizontal_gap_ics">1.020%p</fraction>
+
+ <!-- left or right padding of label alignment -->
+ <dimen name="key_label_horizontal_padding">8dip</dimen>
+
+ <fraction name="key_letter_ratio">65%</fraction>
+ <fraction name="key_large_letter_ratio">74%</fraction>
+ <fraction name="key_label_ratio">40%</fraction>
+ <fraction name="key_hint_letter_ratio">30%</fraction>
+ <fraction name="key_hint_label_ratio">52%</fraction>
+ <fraction name="key_uppercase_letter_ratio">40%</fraction>
+ <fraction name="key_preview_text_ratio">90%</fraction>
+ <dimen name="key_preview_offset">0.08in</dimen>
+
+ <dimen name="key_preview_offset_ics">0.01in</dimen>
+
+ <dimen name="candidate_strip_height">36dip</dimen>
<dimen name="candidate_strip_fading_edge_length">63dip</dimen>
- <dimen name="spacebar_vertical_correction">2dip</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.324in</dimen>
+ <dimen name="mini_keyboard_slide_allowance">0.336in</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="mini_keyboard_vertical_correction">-0.270in</dimen>
+ <dimen name="mini_keyboard_vertical_correction">-0.280in</dimen>
</resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 3ff1543c6..379662323 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Klavišo paspaudimo garsas"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Iššoka paspaudus klavišą"</string>
<string name="general_category" msgid="1859088467017573195">"Bendra"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Teksto taisymas"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Teksto taisymas"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Pasiūlymai pagal ankstesnius žodžius"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Kitos parinktys"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Išplėstiniai nustatymai"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Parinktys ekspertams"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Pagr. išš. l. atsis. d."</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Be delsos"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Numatytasis"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Siūlyti kontaktų vardus"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Siūlant ir taisant naudoti vardus iš „Kontaktų“"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigūruoti žodynus"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Greiti pataisymai"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Taiso dažnai padarytas rašybos klaidas"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Rodyti taisymo pasiūlymus"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Visada rodyti"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Rodyti stačiuoju režimu"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Visada slėpti"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Naud. tarpo kl. k. jung."</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Rodyti nustatymų raktą"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatinis"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Visada rodyti"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Išjungta"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Vidutinis"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Atkaklus"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Digramų pasiūlymai"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Labai agresyviai"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramų pasiūlymai"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Naudoti ankstesnį žodį pasiūlymui patobulinti"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigramų numatymas"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Numatant naudoti ir ankstesnį žodį"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Daugiau"</string>
<string name="label_pause_key" msgid="181098308428035340">"Prist."</string>
<string name="label_wait_key" msgid="6402152600878093134">"Lauk."</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Ištrinti"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Grįžti"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Nustatymai"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Keitimas"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Tarpas"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboliai"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Skirtukas"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Balso įvestis"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simboliai įjungti"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simboliai išjungti"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Keitimas įjungtas"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Keitimas išjungtas"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Dabartinis tekstas yra %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nėra įvesto teksto"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Klavišo kodas %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Antrojo lygio klavišas"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Antrojo lygio klavišas įgalintas"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Įgalintas didžiųjų raidžių klavišas"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Ištrinti"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboliai"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Raidės"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Skaičiai"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Nustatymai"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Skirtukas"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Tarpas"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Balso įv. neleidž."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Pasirinkti įvesties metodą"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Įvesties kalbos"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Pirštu slyskite tarpo klavišu, kad pakeistumėte kalbą"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Kad išsaugotumėte, dar kartą palieskite"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Žodynas galimas"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Jei norite ištais. žodž., paliesk."</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Jei norite ištaisyti įvestus žodžius, palieskite juos tik tada, kai matomi pasiūlymai"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Klaviatūros tema"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatūros tema"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Čekiška klaviatūra"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabiška klaviatūra"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Daniška klaviatūra"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Vokiška klaviatūra"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Vokiška QWERTY klaviatūra"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Angliška (JK) klaviatūra"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Angliška (JAV) klaviatūra"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Ispaniška klaviatūra"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Suomiška klaviatūra"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Prancūziška klaviatūra"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Prancūziška (Kanada) klaviatūra"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Prancūziška (Šveicarija) klaviatūra"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Kroatiška klaviatūra"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Vengriška klaviatūra"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrajiška klaviatūra"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Itališka klaviatūra"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norvegiška klaviatūra"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Olandiška klaviatūra"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Lenkiška klaviatūra"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugališka klaviatūra"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Rusiška klaviatūra"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbiška klaviatūra"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Švediška klaviatūra"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turkiška klaviatūra"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"„Voice“ afrikanų k."</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"„Voice“ čekų k."</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"„Voice“ vokiečių k."</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"„Voice“ kinų (dziue) k."</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"„Voice“ kinų (mandarinų) k."</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"„Voice“ zulų k."</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Tinkamumo analizės režimas"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tinkamumo tyrimo režimas"</string>
</resources>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 11e768fce..c45ec23e9 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Vispārīgi"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Teksta korekcija"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Teksta korekcija"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Ieteikumi, kuru pamatā ir iepriekšējie vārdi"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Citas opcijas"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Papildu iestatījumi"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opcijas speciālistiem"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Taust. uzn. loga noraid. aizk."</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez aizkaves"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Noklusējums"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Ieteikt kontaktp. vārdus"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Izmantot kontaktpersonu vārdus kā ieteikumus un labojumus"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurēt vārdnīcas"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Ātrie labojumi"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Nodrošina izplatītu drukas kļūdu labošanu."</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Rādīt labojumu ieteikumus"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vienmēr rādīt"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Rādīt portreta režīmā"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vienmēr slēpt"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Izmantot valodu pārslēgšanai atstarpēšanas taustiņu"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Rādīt iestatījumu taustiņu"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automātiski"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vienmēr rādīt"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Izslēgta"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mērena"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresīva"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram ieteikumi"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Ļoti radikāla"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigrammu ieteikumi"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Ieteikuma uzlabošanai izmantot iepriekšējo vārdu"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigrammu prognozes"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Izmantot iepriekšējo vārdu arī prognozēm"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Vairāk"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pauze"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Gaidīt"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Dzēšanas taustiņš"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Atgriešanās taustiņš"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Iestatījumu taustiņš"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Pārslēgšanas taustiņš"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Atstarpes taustiņš"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simbolu taustiņš"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulēšanas taustiņš"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Runas ievades taustiņš"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simbolu režīms ir ieslēgts."</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simbolu režīms ir izslēgts."</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Pārslēgšanas režīms ir ieslēgts."</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Pārslēgšanas režīms ir izslēgts."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Pašreizējais teksts ir %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nav ievadīts teksts"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Taustiņu kods %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Pārslēgšanas taustiņš"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Pārslēgšanas taustiņš iespējots"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Burtslēgs iespējots"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Dzēšanas taustiņš"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboli"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Burti"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Skaitļi"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Iestatījumi"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulēšanas taustiņš"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Atstarpes taustiņš"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Balss iev. atspējota"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Atlasīt ievades metodi"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Ievades valodas"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Slidiniet pirkstu uz atstarpes taustiņa, lai mainītu valodu"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Pieskarieties vēlreiz, lai saglabātu"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Ir pieejama vārdnīca."</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Pieskarties, lai izlabotu vārdus"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Pieskarties ievadītajiem vārdiem, lai tos labotu (tikai tad, ja tiek rādīti ieteikumi)."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tastatūras motīvs"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tastatūras motīvs"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Čehu tastatūra"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arābu tastatūra"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dāņu tastatūra"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Vācu tastatūra"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Vācu QWERTY tastatūra"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Angļu (Lielbritānija) tastatūra"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Angļu (ASV) tastatūra"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spāņu tastatūra"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Somu valodas tastatūra"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Franču tastatūra"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Franču (Kanāda) tastatūra"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Franču (Šveices) tastatūra"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Horvātu valodas tastatūra"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Ungāru valodas tastatūra"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Ebreju tastatūra"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Itāļu tastatūra"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norvēģu tastatūra"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Holandiešu tastatūra"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poļu valodas tastatūra"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugāļu valodas tastatūra"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Krievu tastatūra"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbu tastatūra"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Zviedru tastatūra"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turku valodas tastatūra"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Balss afrikandu valodā"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voice čehu valodā"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voice vācu valodā"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Balss ķīniešu val. (Kantonas dial.)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Balss ķīniešu v. (mandarīnu dial.)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Balss zulu valodā"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Lietojamības izpētes režīms"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Lietojamības izpētes režīms"</string>
</resources>
diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml
new file mode 100644
index 000000000..8a2a68797
--- /dev/null
+++ b/java/res/values-ms/strings.xml
@@ -0,0 +1,237 @@
+<?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.
+*/
+ -->
+
+<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="english_ime_settings" msgid="6661589557206947774">"Tetapan papan kekunci Android"</string>
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Pilihan input"</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>
+ <string name="general_category" msgid="1859088467017573195">"Umum"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Pembetulan teks"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Cadangan berdasarkan perkataan sebelumnya"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Pilihan lain"</string>
+ <!-- no translation found for advanced_settings (362895144495591463) -->
+ <skip />
+ <!-- no translation found for advanced_settings_summary (5193513161106637254) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict (4435317977804180815) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict_summary (6599983334507879959) -->
+ <skip />
+ <string name="auto_cap" msgid="1719746674854628252">"Huruf besar auto"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurasikan kamus"</string>
+ <string name="quick_fixes" msgid="5353213327680897927">"Pembaikan pantas"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Membetulkan kesalahan menaip yang biasa"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Tunjukkan cadangan pembetulan"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Paparkan cadangan perkataan semasa menaip"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Sentiasa tunjukkan"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Tunjukkan pada mod potret"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Sentiasa sembunyikan"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Bar ruang tukar bhs"</string>
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Tunjukkan kekunci tetapan"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatik"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Sentiasa tunjukkan"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Sentiasa sembunyikan"</string>
+ <string name="auto_correction" msgid="4979925752001319458">"Auto Pembetulan"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Bar ruang dan tanda baca secara automatik membetulkan perkataan yang ditaip salah"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Matikan"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string>
+ <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Sangat agresif"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Cadangan bigram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gunakan perkataan sebelumnya untuk memperbaik cadangan"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Ramalan bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gunakan juga perkataan sebelumnya untuk ramalan"</string>
+ <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>
+ <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>
+ <string name="label_more_key" msgid="3760239494604948502">"Lagi"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Jeda"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Tnggu"</string>
+ <!-- no translation found for spoken_current_text_is (2485723011272583845) -->
+ <skip />
+ <!-- no translation found for spoken_no_text_entered (7479685225597344496) -->
+ <skip />
+ <!-- no translation found for spoken_description_unknown (3197434010402179157) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift (244197883292549308) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift_shifted (954941524766465022) -->
+ <skip />
+ <!-- no translation found for spoken_description_caps_lock (5660626444912131764) -->
+ <skip />
+ <!-- no translation found for spoken_description_delete (8740376944276199801) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_symbol (5486340107500448969) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_alpha (23129338819771807) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_numeric (591752092685161732) -->
+ <skip />
+ <!-- no translation found for spoken_description_settings (4627462689603838099) -->
+ <skip />
+ <!-- no translation found for spoken_description_tab (2667716002663482248) -->
+ <skip />
+ <!-- no translation found for spoken_description_space (2582521050049860859) -->
+ <skip />
+ <!-- no translation found for spoken_description_mic (615536748882611950) -->
+ <skip />
+ <!-- no translation found for spoken_description_smiley (2256309826200113918) -->
+ <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) -->
+ <skip />
+ <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <skip />
+ <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
+ <skip />
+ <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>
+ <string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"Untuk mematikan input suara, pergi ke tetapan kaedah input."</string>
+ <string name="voice_hint_dialog_message" msgid="1420686286820661548">"Untuk menggunakan input suara, tekan butang mikrofon."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Sebutkan sekarang"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Berfungsi"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Ralat. Sila cuba lagi."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Tidak boleh disambungkan"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Ralat, terlalu banyak pertuturan."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Masalah audio"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Ralat pelayan"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Tiada pertuturan didengari"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Tiada padanan ditemui"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Carian suara tidak dipasang"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021">"Petunjuk"<b>":"</b>" Leret merentasi papan kekunci untuk bercakap"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Petunjuk:"</b>" Lain kali, cuba ucapkan tanda baca seperti \"titik\", \"koma\" atau \"tanda soal\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Batal"</string>
+ <string name="ok" msgid="7898366843681727667">"OK"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Input suara"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Hidpkn kekunci utama"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Pd ppn kekunci simbl"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Matikan"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mik. pd kekunci utma"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mik. pd kekunci smbl"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Input suara dilmphkn"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Pilih kaedah input"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Bahasa input"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Sentuh sekali lagi untuk menyimpan"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Kamus tersedia"</string>
+ <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="prefs_enable_recorrection" msgid="4588408906649533582">"Sentuh untuk membetulkan perkataan"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Sentuh perkataan yang dimasukkan untuk membetulkannya, hanya apabila cadangan boleh dilihat"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema papan kekunci"</string>
+ <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Papan kekunci Czech"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Papan kekunci bahasa Arab"</string>
+ <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Papan kekunci Denmark"</string>
+ <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Papan kekunci Jerman"</string>
+ <!-- no translation found for subtype_mode_de_qwerty_keyboard (54890770769303956) -->
+ <skip />
+ <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Papan kekunci Inggeris (UK)"</string>
+ <string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Papan kekunci Inggeris (AS)"</string>
+ <string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Papan kekunci Sepanyol"</string>
+ <!-- no translation found for subtype_mode_fi_keyboard (3198596464082614532) -->
+ <skip />
+ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Papan kekunci Perancis"</string>
+ <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Papan kekunci Perancis (Kanada)"</string>
+ <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Ppan kekunci Perancis (Switzerland)"</string>
+ <!-- no translation found for subtype_mode_hr_keyboard (7177182405440070112) -->
+ <skip />
+ <!-- no translation found for subtype_mode_hu_keyboard (8843338355732633647) -->
+ <skip />
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Papan kekunci bahasa Ibrani"</string>
+ <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Papan kekunci Itali"</string>
+ <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Papan kekunci Norway"</string>
+ <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Papan kekunci Belanda"</string>
+ <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) -->
+ <skip />
+ <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) -->
+ <skip />
+ <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Papan kekunci Rusia"</string>
+ <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Papan kekunci Serbia"</string>
+ <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Papan kekunci Sweden"</string>
+ <!-- no translation found for subtype_mode_tr_keyboard (3155981874829226370) -->
+ <skip />
+ <string name="subtype_mode_af_voice" msgid="7542487489657902699">"Suara Bahasa Afrikaans"</string>
+ <string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Suara Orang Czech"</string>
+ <string name="subtype_mode_de_voice" msgid="8378803143958089866">"Suara Orang Jerman"</string>
+ <string name="subtype_mode_en_voice" msgid="6643420989651848728">"Suara Bahasa Inggeris"</string>
+ <string name="subtype_mode_es_voice" msgid="1323473601346507487">"Suara Orang Sepanyol"</string>
+ <string name="subtype_mode_fr_voice" msgid="4675914209337824269">"Suara Orang Perancis"</string>
+ <string name="subtype_mode_it_voice" msgid="5077373057157441323">"Suara Bahasa Itali"</string>
+ <string name="subtype_mode_ja_voice" msgid="6604859132669646367">"Suara Orang Jepun"</string>
+ <string name="subtype_mode_ko_voice" msgid="4890391190762324561">"Suara Orang Korea"</string>
+ <string name="subtype_mode_nl_voice" msgid="2603552312869575021">"Suara Bahasa Belanda"</string>
+ <string name="subtype_mode_pl_voice" msgid="2076196021014840487">"Suara Orang Poland"</string>
+ <string name="subtype_mode_pt_voice" msgid="8036522712795994397">"Suara Orang Portugis"</string>
+ <string name="subtype_mode_ru_voice" msgid="8034596947963787529">"Suara Orang Rusia"</string>
+ <string name="subtype_mode_tr_voice" msgid="3402067436761140005">"Suara Orang Turki"</string>
+ <string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Cina, Suara Bahasa Yue"</string>
+ <string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Cina, Suara Bahasa Mandarin"</string>
+ <string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Suara bahasa isiZulu"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mod kajian kebolehgunaan"</string>
+</resources>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index db163b963..e96a95b05 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Lyd ved tastetrykk"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Hurtigvindu ved tastetrykk"</string>
<string name="general_category" msgid="1859088467017573195">"Generelt"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Tekstkorrigering"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Tekstkorrigering"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Forslag basert på tidligere ord"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Andre alternativer"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Avanserte innstillinger"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Alternativer for ekspertbrukere"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Tregt tastevindu"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"U/ forsinkelse"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå kontaktnavn"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Bruk navn fra Kontakter til forslag og korrigeringer"</string>
<string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurer ordbøker"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Autokorrektur"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Retter vanlige stavefeil"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Vis rettingsforslag"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vis alltid"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Vis i stående modus"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Skjul alltid"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Skift språk med mellomromstasten"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Vis innstillingsnøkkel"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisk"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vis alltid"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Av"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Omfattende"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram-forslag"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Veldig aggressiv"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram-forslag"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Bruk forrige ord til å forbedre forslaget"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram-prediksjon"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Bruk forrige ord også for forslag"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mer"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Vent"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Innstillinger"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Mellomrom"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboler"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Taleinndata"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symboler er slått på"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symboler er slått av"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift på"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift av"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Gjeldende tekst er %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Ingen tekst er skrevet inn"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Tastaturkode %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift er aktivert"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock er aktivert"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Slett"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboler"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Bokstaver"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Tall"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Innstillinger"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulator"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Mellomrom"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Taleinndata er deaktiv."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Velg inndatametode"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Inndataspråk"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Dra fingeren på mellomromstasten for å endre språk"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"Trykk på nytt for å lagre"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Ordbok tilgjengelig"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Trykk for å endre ord"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Når forslag er synlige, kan du trykke på ord du har skrevet inn, for å endre dem"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tastaturtema"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tsjekkisk tastatur"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabisk tastatur"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Dansk tastatur"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tysk tastatur"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Tysk QWERTY-tastatur"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelsk tastatur (Storbritannia)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Engelsk tastatur (USA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spansk tastatur"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finsk tastatur"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Fransk tastatur"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Fransk tastatur (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Fransk tastatur (Sveits)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Kroatisk tastatur"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Ungarsk tastatur"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebraisk tastatur"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiensk tastatur"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norsk tastatur"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nederlandsk tastatur"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polsk tastatur"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugisisk tastatur"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russisk tastatur"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbisk tastatur"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svensk tastatur"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Tyrkisk tastatur"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikaans tale"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Tsjekkisk tale"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Tysk tale"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Kinesisk (yue) tale"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Kinesisk (mandarin) tale"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu tale"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Nyttighetsmodus"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Nyttighetsmodus"</string>
</resources>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 6dece4885..6152f93b8 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Geluid bij toetsaanslag"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up bij toetsaanslag"</string>
<string name="general_category" msgid="1859088467017573195">"Algemeen"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Tekstcorrectie"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Tekstcorrectie"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Suggesties op basis van eerdere woorden"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Andere opties"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Geavanceerde instellingen"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opties voor ervaren gebruikers"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Afwijz.vertr. toetspop-up"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Geen vertraging"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standaard"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Contactnamen suggereren"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen uit Contacten gebruiken voor suggesties en correcties"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Woordenboeken configureren"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Snelle oplossingen"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Hiermee worden veelvoorkomende typefouten gecorrigeerd"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Correctievoorstellen weergeven"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Altijd weergeven"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Weergeven in staande modus"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Altijd verbergen"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Taal schakelen via spatiebalk"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Instellingscode weergeven"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatisch"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Altijd weergeven"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Uitgeschakeld"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Normaal"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressief"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Digram-suggesties"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Zeer agressief"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Digram-suggesties"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Vorig woord gebruiken om suggestie te verbeteren"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Digram-voorspelling"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Het voorgaande woord ook voor voorspelling gebruiken"</string>
<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">"Volgende"</string>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Meer"</string>
<string name="label_pause_key" msgid="181098308428035340">"Onderbr."</string>
<string name="label_wait_key" msgid="6402152600878093134">"Wacht"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Instellingen"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Spatie"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbolen"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Spraakinvoer"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symbolen aan"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symbolen uit"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift aan"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift uit"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Huidige tekst is %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Geen tekst ingevoerd"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Toetscode %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift ingeschakeld"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock ingeschakeld"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Verwijderen"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbolen"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letters"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Cijfers"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Instellingen"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Spatie"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Spraakinvoer is uit"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Invoermethode selecteren"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Invoertalen"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Schuif uw vinger over de spatiebalk om de taal te wijzigen"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Raak nogmaals aan om op te slaan"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Woordenboek beschikbaar"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Raak aan om woorden te corrigeren"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Ingevoerde woorden aanraken om ze te verbeteren, alleen mogelijk wanneer suggesties zichtbaar zijn"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Toetsenbordthema"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Toetsenbordthema"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tsjechisch toetsenbord"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabisch toetsenbord"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Deens toetsenbord"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Duits toetsenbord"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Duits QWERTY-toetsenbord"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engels toetsenbord (VK)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Engels toetsenbord (VS)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spaans toetsenbord"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Fins toetsenbord"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Frans toetsenbord"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Frans toetsenbord (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Frans toetsenbord (Zwitserland)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Kroatisch toetsenbord"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Hongaars toetsenbord"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebreeuws toetsenbord"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italiaans toetsenbord"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Noors toetsenbord"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nederlands toetsenbord"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Pools toetsenbord"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugees toetsenbord"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russisch toetsenbord"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Servisch toetsenbord"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Zweeds toetsenbord"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turks toetsenbord"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikaanse stem"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Tsjechische stem"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Duitse stem"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Chinese stem (Yue)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Chinese stem (Mandarijn)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu stem"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modus voor gebruiksvriendelijkheidsonderzoek"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus voor gebruiksvriendelijkheidsonderzoek"</string>
</resources>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 70c4b18df..2a0a35345 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Ogólne"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Korekta tekstu"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Poprawianie tekstu"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Podpowiedzi na podstawie wcześniejszych słów"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Inne opcje"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Ustawienia zaawansowane"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opcje dla zaawansowanych użytkowników"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Opóźnienie wyłączenia wyskakującego okienka"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez opóźnienia"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Wartość domyślna"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Proponuj nazwiska z kontaktów"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"W propozycjach i poprawkach użyj nazwisk z kontaktów"</string>
<string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfiguruj słowniki"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Szybkie poprawki"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Poprawia częste błędy wpisywania"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Pokazuj propozycje poprawek"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Zawsze pokazuj"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Pokaż w trybie pionowym"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Zawsze ukrywaj"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Spacja przełącza język"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Pokaż klawisz ustawień"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatycznie"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Zawsze pokazuj"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Wyłącz"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Umiarkowana"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresywna"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestie dla bigramów"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Bardzo agresywnie"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Podpowiadanie dwuznaków"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Używaj poprzedniego wyrazu, aby polepszyć sugestię"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Przewidywanie dwuznaków"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Przewiduj również na podstawie poprzedniego słowa"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Więcej"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pauza"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Czekaj"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Ustawienia"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Spacja"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symbole"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Wprowadzanie głosowe"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symbole włączone"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symbole wyłączone"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift włączony"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift wyłączony"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Aktualny tekst: %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nie wprowadzono tekstu"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Kod klawisza: %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift włączony"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock włączony"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Usuń"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbole"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Litery"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Liczby"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Ustawienia"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Spacja"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Wprowadzanie głosowe jest wyłączone"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Wybierz sposób wprowadzania tekstu"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Języki wprowadzania"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Przesuń palcem po spacji, aby zmienić język"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Dotknij ponownie, aby zapisać"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Słownik dostępny"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Popraw dotknięte słowo"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dotykaj wprowadzonych słów, aby je poprawiać tylko wówczas, gdy widoczne są sugestie."</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Motyw klawiatury"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Motyw klawiatury"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Klawiatura czeska"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Klawiatura arabska"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Klawiatura duńska"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Klawiatura niemiecka"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Niemiecka klawiatura QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Klawiatura angielska (UK)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Klawiatura angielska (USA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Klawiatura hiszpańska"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Klawiatura fińska"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Klawiatura francuska"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Klawiatura francuska (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Klawiatura francuska (Szwajcaria)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Klawiatura chorwacka"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Klawiatura węgierska"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Klawiatura hebrajska"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Klawiatura włoska"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Klawiatura norweska"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Klawiatura holenderska"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Klawiatura polska"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Klawiatura portugalska"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Klawiatura rosyjska"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Klawiatura serbska"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Klawiatura szwedzka"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Klawiatura turecka"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Mowa afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Mowa czeska"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Mowa niemiecka"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Mowa chińska (kantoński)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Mowa chińska (mandaryński)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Mowa isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Tryb badania przydatności"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tryb badania przydatności"</string>
</resources>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 5845ebc59..13c9084fb 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Geral"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Correcção de texto"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Correção de texto"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Sugestões baseadas em palavras anteriores"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Outras opções"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Definições avançadas"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opções para utilizadores experientes"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Atraso p/ ignorar pop-up"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sem atraso"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predefinido"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de Contactos"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nomes dos Contactos para sugestões e correções"</string>
<string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configurar dicionários"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Correcções rápidas"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige os erros de escrita comuns"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Mostrar sugestões de correcção"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar sempre"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar no modo de retrato"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ocultar sempre"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Utilizar barra esp. alt. idioma"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla das definições"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar sempre"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desligar"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderada"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressiva"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestões Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muito agressivo"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Sugestões Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizar a palavra anterior para melhorar a sugestão"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Predição Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Utilizar a palavra anterior também para predição"</string>
<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">"Seguinte"</string>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mais"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Esp."</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Definições"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Espaço"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Entrada de voz"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos ativados"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desativados"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift ativado"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift desativado"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"O texto atual é %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nenhum texto digitado"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Código da tecla %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift ativado"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock ativado"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Símbolos"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letras"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Números"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Definições"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Espaço"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Entr. voz desact."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Seleccionar método de entrada"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Deslize o dedo pela barra de espaço para alterar o idioma"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Toque novamente para guardar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
<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 melhor este editor de método de introdução."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corrigir palavras"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tocar nas palavras introduzidas para as corrigir, apenas quando as sugestões estiverem visíveis"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema do teclado"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado checo"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado dinamarquês"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado alemão"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Teclado QWERTY Alemão"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado inglês (Reino Unido)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Teclado inglês (EUA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Teclado espanhol"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Teclado finlandês"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado francês"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado francês (Canadá)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado francês (Suíça)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Teclado croata"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Teclado húngaro"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebraico"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado italiano"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado norueguês"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado holandês"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado Polaco"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Teclado Português"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado russo"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado sérvio"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado sueco"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Teclado Turco"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voz em africânder"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voz checa"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voz alemã"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voz em yue, chinês"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voz em mandarim, chinês"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voz em isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modo de estudo da capacidade de utilização"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo da capacidade de utilização"</string>
</resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index f1203c671..35537606b 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Geral"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Correção de texto"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Correção de texto"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Sugestões baseadas em palavras anteriores"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Outras opções"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Configurações avançadas"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opções para usuários experientes"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Dispens. atraso chave princ."</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Sem atraso"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Padrão"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de contato"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nomes dos Contatos para sugestões e correções"</string>
<string name="auto_cap" msgid="1719746674854628252">"Capitaliz. automática"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configurar dicionários"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Reparos rápidos"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige erros comuns de digitação"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Exibir sugestões de correção"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar sempre"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Mostrar em modo retrato"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Sempre ocultar"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Alt. idiomas c/ a barra"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Mostrar tecla de config."</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automático"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Mostrar sempre"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desativado"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agressivo"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestões de bigrama"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Muito agressivo"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Sugestões de bigrama"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palavra anterior para melhorar a sugestão"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Previsão de bigrama"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Use também a palavra anterior para prever"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mais"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Esp."</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Excluir"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Voltar"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Configurações"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Espaço"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Símbolos"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Entrada de texto por voz"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Símbolos ativados"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Símbolos desativados"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift ativado"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift desativado"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"O texto atual é %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nenhum texto digitado"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Código de tecla %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift ativado"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock ativado"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Excluir"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Símbolos"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Letras"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Números"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Configurações"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Espaço"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Texto por voz desat."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Selecionar método de entrada"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Idiomas de entrada"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Deslize o dedo na barra de espaços para alterar o idioma"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Toque novamente para salvar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Tocar para corrigir"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Toque nas palavras digitadas para corrigi-las apenas quando as sugestões estiverem visíveis"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema do teclado"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Teclado em tcheco"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Teclado árabe"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Teclado para dinamarquês"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Teclado para alemão"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Teclado alemão QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Teclado para inglês (Reino Unido)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Teclado para inglês (EUA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Teclado para espanhol"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Teclado finlandês"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Teclado para francês"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Teclado para francês (Canadá)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Teclado para francês (Suíça)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Teclado croata"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Teclado húngaro"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Teclado hebraico"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Teclado para italiano"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Teclado para norueguês"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Teclado para holandês"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Teclado polonês"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Teclado em português"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Teclado para russo"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Teclado para sérvio"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Teclado para sueco"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Teclado turco"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voz em africâner"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voz em tcheco"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voz em alemão"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voz em chinês, cantonês"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voz em chinês, mandarim"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voz em zulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modo de estudo de utilização"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo de utilização"</string>
</resources>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 9c51cad72..d412c5226 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -29,8 +29,29 @@
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up cun smatgar ina tasta"</string>
<!-- no translation found for general_category (1859088467017573195) -->
<skip />
- <!-- outdated translation 7027100625580696660 --> <string name="prediction_category" msgid="6361242011806282176">"Parameters da las propostas per pleds"</string>
+ <!-- no translation found for correction_category (2236750915056607613) -->
+ <skip />
+ <!-- no translation found for ngram_category (5337109164339320257) -->
+ <skip />
+ <!-- no translation found for misc_category (6894192814868233453) -->
+ <skip />
+ <!-- no translation found for advanced_settings (362895144495591463) -->
+ <skip />
+ <!-- no translation found for advanced_settings_summary (5193513161106637254) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict (4435317977804180815) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict_summary (6599983334507879959) -->
+ <skip />
<string name="auto_cap" msgid="1719746674854628252">"Maiusclas automaticas"</string>
+ <!-- no translation found for configure_dictionaries_title (3758288002414557345) -->
+ <skip />
<string name="quick_fixes" msgid="5353213327680897927">"Correcturas sveltas"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Curregia sbagls da tippar currents"</string>
<!-- no translation found for prefs_show_suggestions (8026799663445531637) -->
@@ -43,6 +64,8 @@
<skip />
<!-- no translation found for prefs_suggestion_visibility_hide_name (6309143926422234673) -->
<skip />
+ <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) -->
+ <skip />
<!-- no translation found for prefs_settings_key (4623341240804046498) -->
<skip />
<!-- no translation found for settings_key_mode_auto_name (2993460277873684680) -->
@@ -59,8 +82,14 @@
<skip />
<!-- no translation found for auto_correction_threshold_mode_aggeressive (3524029103734923819) -->
<skip />
- <string name="bigram_suggestion" msgid="1323347224043514969">"Propostas da tip bigram"</string>
+ <!-- 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>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Meglierar la proposta cun agid dal pled precedent"</string>
+ <!-- no translation found for bigram_prediction (8914273444762259739) -->
+ <skip />
+ <!-- no translation found for bigram_prediction_summary (1747261921174300098) -->
+ <skip />
<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>
@@ -74,29 +103,77 @@
<skip />
<!-- no translation found for label_wait_key (6402152600878093134) -->
<skip />
- <!-- no translation found for description_delete_key (5586406298531883960) -->
+ <!-- no translation found for spoken_current_text_is (2485723011272583845) -->
+ <skip />
+ <!-- no translation found for spoken_no_text_entered (7479685225597344496) -->
+ <skip />
+ <!-- no translation found for spoken_description_unknown (3197434010402179157) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift (244197883292549308) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift_shifted (954941524766465022) -->
+ <skip />
+ <!-- no translation found for spoken_description_caps_lock (5660626444912131764) -->
+ <skip />
+ <!-- no translation found for spoken_description_delete (8740376944276199801) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_symbol (5486340107500448969) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_alpha (23129338819771807) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_numeric (591752092685161732) -->
<skip />
- <!-- no translation found for description_return_key (8750044000806461678) -->
+ <!-- no translation found for spoken_description_settings (4627462689603838099) -->
<skip />
- <!-- no translation found for description_settings_key (7484527796782969219) -->
+ <!-- no translation found for spoken_description_tab (2667716002663482248) -->
<skip />
- <!-- no translation found for description_shift_key (346906866277787836) -->
+ <!-- no translation found for spoken_description_space (2582521050049860859) -->
<skip />
- <!-- no translation found for description_space_key (8512130111575878517) -->
+ <!-- no translation found for spoken_description_mic (615536748882611950) -->
<skip />
- <!-- no translation found for description_switch_alpha_symbol_key (4537975384274405537) -->
+ <!-- no translation found for spoken_description_smiley (2256309826200113918) -->
<skip />
- <!-- no translation found for description_tab_key (828186583738307137) -->
+ <!-- no translation found for spoken_description_return (8178083177238315647) -->
<skip />
- <!-- no translation found for description_voice_key (3057731675774652754) -->
+ <!-- no translation found for spoken_description_comma (4970844442999724586) -->
<skip />
- <!-- no translation found for description_symbols_on (2994366855822840559) -->
+ <!-- no translation found for spoken_description_period (5286614628077903945) -->
<skip />
- <!-- no translation found for description_symbols_off (3209578267079515136) -->
+ <!-- no translation found for spoken_description_left_parenthesis (8524822120595052415) -->
<skip />
- <!-- no translation found for description_shift_on (6983188949895971587) -->
+ <!-- no translation found for spoken_description_right_parenthesis (1085757995851933164) -->
<skip />
- <!-- no translation found for description_shift_off (8553265474523069034) -->
+ <!-- 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) -->
+ <skip />
+ <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <skip />
+ <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
<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>
@@ -134,7 +211,6 @@
<!-- no translation found for selectInputMethod (315076553378705821) -->
<skip />
<string name="language_selection_title" msgid="1651299598555326750">"Linguas da cumonds vocals"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Stritgar cun il det sur la tasta da vid per midar la lingua"</string>
<!-- outdated translation 8058519710062071085 --> <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tippar danovamain per memorisar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicziunari disponibel"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Activar il feedback da l\'utilisader"</string>
@@ -143,37 +219,55 @@
<skip />
<!-- no translation found for prefs_enable_recorrection_summary (5082041365862396329) -->
<skip />
- <string name="keyboard_layout" msgid="437433231038683666">"Design da la tastatura"</string>
+ <!-- outdated translation 437433231038683666 --> <string name="keyboard_layout" msgid="8451164783510487501">"Design da la tastatura"</string>
<!-- no translation found for subtype_mode_cs_keyboard (1141718931112377586) -->
<skip />
+ <!-- no translation found for subtype_mode_ar_keyboard (2655338636329774995) -->
+ <skip />
<!-- no translation found for subtype_mode_da_keyboard (1243570804427922104) -->
<skip />
<!-- no translation found for subtype_mode_de_keyboard (1990979135959462145) -->
<skip />
+ <!-- no translation found for subtype_mode_de_qwerty_keyboard (54890770769303956) -->
+ <skip />
<!-- no translation found for subtype_mode_en_GB_keyboard (7945856548410373708) -->
<skip />
<!-- no translation found for subtype_mode_en_US_keyboard (3708655163769735410) -->
<skip />
<!-- no translation found for subtype_mode_es_keyboard (1775125478866113148) -->
<skip />
+ <!-- no translation found for subtype_mode_fi_keyboard (3198596464082614532) -->
+ <skip />
<!-- no translation found for subtype_mode_fr_keyboard (8016515336759761014) -->
<skip />
<!-- no translation found for subtype_mode_fr_CA_keyboard (2628517247158376263) -->
<skip />
<!-- no translation found for subtype_mode_fr_CH_keyboard (6742806653181621228) -->
<skip />
+ <!-- no translation found for subtype_mode_hr_keyboard (7177182405440070112) -->
+ <skip />
+ <!-- no translation found for subtype_mode_hu_keyboard (8843338355732633647) -->
+ <skip />
+ <!-- no translation found for subtype_mode_iw_keyboard (1787536828253289950) -->
+ <skip />
<!-- no translation found for subtype_mode_it_keyboard (4934199655425394484) -->
<skip />
<!-- no translation found for subtype_mode_nb_keyboard (1175783216100212360) -->
<skip />
<!-- no translation found for subtype_mode_nl_keyboard (5090278083256037936) -->
<skip />
+ <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) -->
+ <skip />
+ <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) -->
+ <skip />
<!-- no translation found for subtype_mode_ru_keyboard (1383995915064277943) -->
<skip />
<!-- no translation found for subtype_mode_sr_keyboard (5019440799612208168) -->
<skip />
<!-- no translation found for subtype_mode_sv_keyboard (4933838139861753401) -->
<skip />
+ <!-- no translation found for subtype_mode_tr_keyboard (3155981874829226370) -->
+ <skip />
<!-- no translation found for subtype_mode_af_voice (7542487489657902699) -->
<skip />
<!-- no translation found for subtype_mode_cs_voice (1136386688120958641) -->
@@ -208,6 +302,6 @@
<skip />
<!-- no translation found for subtype_mode_zu_voice (1146122571698884636) -->
<skip />
- <!-- no translation found for prefs_usability_study_mode (6937813623647419810) -->
+ <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
<skip />
</resources>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 0a80911ce..ada407a51 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"General"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Corectare text"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Corectare text"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Sugestii bazate pe cuvinte anterioare"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Alte opţiuni"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Setări avansate"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Opţiuni pt. utiliz. experţi"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Înt. înch. pop-up esenţ."</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Fără întârziere"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Prestabilit"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Sugeraţi nume din Agendă"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizaţi numele din Agendă pentru sugestii şi corecţii"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Configuraţi dicţionare"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Remedieri rapide"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corectează greşelile introduse frecvent"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Afişaţi sugestii de corectare"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Afişaţi întotdeauna"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Afişaţi în modul Portret"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ascundeţi întotdeauna"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Spacebar – selector limbă"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Afişaţi tasta setări"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automat"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Afişaţi întotdeauna"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Dezactivată"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderată"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivă"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Sugestii pentru cuvinte de două litere"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Foarte agresiv"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Sugestii de tip bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Utilizaţi cuvântul anterior pentru a îmbunătăţi sugestia"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Predicţii de tip bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Se utilizează şi cuvântul precedent pentru predicţii"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mai multe"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pauză"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Aşt."</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Ştergeţi"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Tasta Enter"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Setări"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Tasta Space"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simboluri"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tasta Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Intrare vocală"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simbolurile sunt activate"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simbolurile sunt dezactivate"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Tasta Shift este activată"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Tasta Shift este dezactivată"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Textul curent este %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nu a fost introdus text"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Tasta cu codul %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift activat"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock activat"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboluri"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Litere"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Cifre"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Setări"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Spaţiu"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Intr. vocală dezact."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Selectaţi metoda de introducere a textului"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Selectaţi limba"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Glisaţi degetul pe bara de spaţiu pentru a schimba limba"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Atingeţi din nou pentru a salva"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicţionar disponibil"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Atingeţi pentru a corecta cuvintele"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Atingeţi cuvintele introduse pentru a le corecta, numai când pot fi văzute sugestii"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Temă pentru tastatură"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Temă tastatură"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tastatură cehă"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Tastatură arabă"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Tastatură daneză"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tastatură germană"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Tastatură germană QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Tastatură engleză (Marea Britanie)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Tastatură engleză (S.U.A.)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Tastatură spaniolă"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Tastatură finlandeză"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Tastatură franceză"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Tastatură franceză (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Tastatură franceză (Elveţia)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Tastatură croată"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Tastatură maghiară"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Tastatură ebraică"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Tastatură italiană"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Tastatură norvegiană"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Tastatură olandeză"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Tastatură poloneză"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Tastatură portugheză"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Tastatură rusă"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Tastatură sârbă"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Tastatură suedeză"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Tastatură turcă"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voce afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Voce cehă"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Voce germană"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voce chineză, yue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voce chineză, mandarină"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voce isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Modul Studiu privind utilizarea"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modul Studiu privind utilizarea"</string>
</resources>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 6dab43cb9..8f9051261 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук клавиш"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Увеличение нажатых"</string>
<string name="general_category" msgid="1859088467017573195">"Общие"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Коррекция текста"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Исправление текста"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Подсказки, основанные на предыдущих словах"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Другие варианты"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Расширенные настройки"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Для опытных пользователей"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Задержка закрытия"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без задержки"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"По умолчанию"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Подсказки имен контактов"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Подсказки и исправления на основе имен из контактов"</string>
<string name="auto_cap" msgid="1719746674854628252">"Заглавные автоматически"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Настроить словари"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Быстрое исправление"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Исправлять распространенные опечатки"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Показать варианты исправлений"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"Пробел меняет язык"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Кнопка настроек"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматически"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Всегда показывать"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Откл."</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умеренное"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Активное"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Биграммные подсказки"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Жестко"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Биграммные подсказки"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Используйте предыдущее слово, чтобы исправить подсказку"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Биграммный прогноз"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Использовать предыдущее слово для прогнозирования"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Ещё"</string>
<string name="label_pause_key" msgid="181098308428035340">"Приостановить"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Подождите"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Клавиша удаления"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Клавиша \"Ввод\""</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Клавиша настроек"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Клавиша верхнего регистра"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Клавиша \"Пробел\""</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Клавиша символов"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Клавиша табуляции"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Клавиша голосового ввода"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Клавиши символов выключены"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Клавиши символов включены"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Верхний регистр включен"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Верхний регистр выключен"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Введенный текст: %s."</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Текст не введен"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Код клавиши:%d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Клавиша верхнего регистра"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Верхний регистр включен"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Включена фиксация верхнего регистра"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Клавиша удаления"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Клавиша символов"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Буквы"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Цифры"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Настройки"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Клавиша табуляции"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Пробел"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Голосовой ввод откл."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Выбрать способ ввода"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Языки ввода"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Для изменения языка проведите пальцем по пробелу"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Нажмите еще раз, чтобы сохранить"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Доступен словарь"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Включить отправку сведений"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Помогите усовершенствовать редактор способа ввода, разрешив отправку статистики и отчетов о сбоях в Google."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"Исправление нажатием"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Нажмите на слово, чтобы исправить его (при наличии подсказок)"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Вид клавиатуры"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Тема клавиатуры"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Клавиатура: чешская"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Арабская клавиатура"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Клавиатура: датская"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Клавиатура: немецкая"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Немецкая раскладка QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Клавиатура: английская (Великобритания)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Клавиатура: английская (США)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Клавиатура: испанская"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Финская раскладка"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Клавиатура: французская"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Клавиатура: французская"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Клавиатура: французская (Швейцария)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Хорватская раскладка"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Венгерская раскладка"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Клавиатура на иврите"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Клавиатура: итальянская"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Клавиатура: норвежская"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Клавиатура: голландская"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Польская клавиатура"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Португальская раскладка"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Клавиатура: русская"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Клавиатура: сербская"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Голос: шведский"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Турецкая раскладка"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Голосовой ввод на африкаанс"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Голос: чешский"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Голос: немецкий"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Голосовой ввод на китайском (диалект юэ)"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Голосовой ввод на китайском (мандаринский диалект)"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Голосовой ввод на зулу"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Режим проверки удобства использования"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим проверки удобства использования"</string>
</resources>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index e7a7cd194..e24fdbc7f 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Všeobecné"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Oprava textu"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Oprava textu"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Návrhy na základe predchádzajúcich slov"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Ďalšie možnosti"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Rozšírené nastavenia"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Možnosti pre skúsených používateľov"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Onesk. zrušenia kľúč. kon. okna"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Bez oneskorenia"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Predvolená"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Navrhnúť mená kontaktov"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Používať mená z Kontaktov na návrhy a opravy"</string>
<string name="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurovať slovníky"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Rýchle opravy"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Opravuje najčastejšie chyby pri písaní"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Zobraziť návrhy opráv"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vždy zobrazovať"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Zobraziť v režime na výšku"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vždy skrývať"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Použite medzerník na prepínanie medzi jazykmi"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Zobraziť kláves Nastavenia"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automaticky"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vždy zobrazovať"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Vypnuté"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mierne"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresívne"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Návrh Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Veľmi agresívna"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Návrhy Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Na zlepšenie návrhu použiť predchádzajúce slovo"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Odhady Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Použiť predchádzajúce slovo aj pre predpoveď"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Viac"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pozastaviť"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Čakajte"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Nastavenia"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Medzera"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboly"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Hlasový vstup"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Symboly zapnuté"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Symboly vypnuté"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift zapnutý"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift vypnutý"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Aktuálny text je %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Nie je zadaný žiadny text"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Kód klávesu %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Povolený kláves Shift"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Povolený kláves Caps Lock"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboly"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Písmená"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Čísla"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Nastavenia"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Karta"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Medzerník"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Hlasový vstup je zakázaný"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Výber metódy vstupu"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Jazyky vstupu"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Jazyk môžete zmeniť posunutím prsta po medzerníku."</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Ďalším dotykom slovo uložíte"</string>
<string name="has_dictionary" msgid="6071847973466625007">"K dispozícii je slovník"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Dotykom opravíte slová"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dotykom zadaných slov tieto slová opravíte, musia však byť viditeľné návrhy"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Motív klávesnice"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Motív klávesnice"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"klávesnica – čeština"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"klávesnica – arabčina"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"klávesnica – dánčina"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"klávesnica – nemčina"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Nemecká klávesnica QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"klávesnica – angličtina (br.)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"klávesnica – angličtina (am.)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"klávesnica – španielčina"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Fínska klávesnica"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"klávesnica – francúzština"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"klávesnica – francúzština (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"klávesnica – francúzština (Švajč.)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Chorvátska klávesnica"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Maďarská klávesnica"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"klávesnica – hebrejčina"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"klávesnica – taliančina"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"klávesnica – nórčina"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"klávesnica – holandčina"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poľská klávesnica"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugalská klávesnica"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"klávesnica – ruština"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"hlas – srbčina"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"klávesnica – švédčina"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"turecká klávesnica"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Hlas – afrikánčina"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"hlas – čeština"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"hlas – nemčina"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Hlas – čínština, kantónčina"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Hlas – čínština, mandarínska"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Hlas – Zulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Režim Štúdia vhodnosti použitia"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim štúdie použiteľnosti"</string>
</resources>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 6bb0b36c8..a7fd9b80a 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Zvok ob pritisku tipke"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pojavno okno ob pritisku tipke"</string>
<string name="general_category" msgid="1859088467017573195">"Splošno"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Popravek besedila"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Popravek besedila"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Predlogi, ki temeljijo na prejšnjih besedah"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Druge možnosti"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Dodatne nastavitve"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Možnosti za izkušene uporabnike"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Zakas. okna za zavrnitev"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Brez zamude"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Privzeto"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Predlagaj imena stikov"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Uporaba imen iz stikov za predloge in popravke"</string>
<string name="auto_cap" msgid="1719746674854628252">"Samodejne velike začetnice"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfiguracija slovarjev"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Hitri popravki"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Popravi pogoste tipkarske napake"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Pokaži predloge popravkov"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Vedno pokaži"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Pokaži v pokončnem načinu"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Vedno skrij"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Preklopite med jeziki s preslednico"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Pokaži tipko za nastavitve"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Samodejno"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Vedno pokaži"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Izklopljeno"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Zmerno"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresivno"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramni predlogi"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Zelo dosledno"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramni predlogi"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Predlog izboljšaj s prejšnjo besedo"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigramsko predvidevanje"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Uporabi prejšnjo besedo tudi za predvidevanje"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Več"</string>
<string name="label_pause_key" msgid="181098308428035340">"Premor"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Čakaj"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Izbriši"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Vračalka"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Nastavitve"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Dvigalka"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Preslednica"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Znaki"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabulatorka"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Glasovni vnos"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Znaki vklopljeni"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Znaki izklopljeni"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Dvigalka vklopljena"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Dvigalka izklopljena"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Trenutno besedilo je %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Ni vnesenega besedila"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Koda tipke %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Tipka »Shift« je omogočena"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Funkcija »Caps Lock« je omogočena"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simboli"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Pisma"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Številke"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Nastavitve"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulator"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Presledek"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Glas. vnos je onem."</string>
<string name="selectInputMethod" msgid="315076553378705821">"Izberite način vnosa"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Jeziki vnosa"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Podrsajte s prstom po preslednici, da zamenjate jezik"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Še enkrat se dotaknite, da shranite"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Slovar je na voljo"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Dotaknite se besed in jih popravite"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Dotaknite se vnesenih besed in jih popravite, samo ko so predlogi vidni"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema tipkovnice"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Češka tipkovnica"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabska tipkovnica"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danska tipkovnica"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Nemška tipkovnica"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Nemška tipkovnica QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Tipkovnica za britansko angleščino"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Tipkovnica za ameriško angleščino"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Španska tipkovnica"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finska tipkovnica"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Francoska tipkovnica"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Tipkovnica za kanadsko francoščino"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Tipkovnica za švicarsko francoščino"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Hrvaška tipkovnica"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Madžarska tipkovnica"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrejska tipkovnica"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italijanska tipkovnica"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norveška tipkovnica"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Nizozemska tipkovnica"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Poljska tipkovnica"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugalska tipkovnica"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ruska tipkovnica"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Srbska tipkovnica"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Švedska tipkovnica"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turška tipkovnica"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Govor v afrikanščini"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Govor v češčini"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Govor v nemščini"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Govor v kitajščini, jue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Govor v kitajščini, mandarinščini"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Govor v zulujščini"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Način za preučevanje uporabnosti"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način za preučevanje uporabnosti"</string>
</resources>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 02e7593ca..4e5716632 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук на притисак тастера"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Искачући прозор приликом притиска тастера"</string>
<string name="general_category" msgid="1859088467017573195">"Опште"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Исправљање текста"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Исправљање текста"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Предлози на основу претходних речи"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Друге опције"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Напредна подешавања"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Опције за искусне кориснике"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Одложи одбац. иск. прозора тастера"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без одлагања"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Подразумевано"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Предложи имена контаката"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Користи имена из Контаката за предлоге и исправке"</string>
<string name="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Конфигуриши речнике"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Брзе исправке"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Исправља честе грешке у куцању"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Прикажи предлоге за исправку"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"Користи размак за избор језика"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Прикажи тастер за подешавања"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Аутоматски"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Увек прикажи"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Искључи"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Агресивно"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram предлози"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Веома агресивно"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram предлози"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Користи претходну реч за побољшање предлога"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram предвиђање"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Користи претходну реч и за предвиђање"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Још"</string>
<string name="label_pause_key" msgid="181098308428035340">"Паузирај"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Сачекајте"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Подешавања"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Размак"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Симболи"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Гласовни унос"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Симболи су укључени"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Симболи су искључени"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift је укључен"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift је искључен"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Тренутни текст је %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Текст није унет"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Кôд тастера %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Тастер Shift је омогућен"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock је омогућен"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Симболи"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Слова"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Бројеви"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Подешавања"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Размак"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Гласовни унос је онемогућен"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Изаберите метод уноса"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Језици за унос"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Превуците прст преко тастера за размак да бисте променили језик"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Поново додирните да бисте сачували"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Речник је доступан"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Омогући повратну информацију корисника"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Помозите да се побољша овај уређивач режима уноса тако што ће се аутоматски послати статистика о коришћењу и извештаји о грешкама компанији Google."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"Додирните да бисте исправили речи"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Додирните унете речи да бисте их исправили само када су предлози видљиви"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Тема тастатуре"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Тема тастатуре"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Језик тастатуре: чешки"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Језик тастатуре: арапски"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Језик тастатуре: дански"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Језик тастатуре: немачки"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"QWERTY тастатура за немачки"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Језик тастатуре: енглески (УК)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Језик тастатуре: енглески (САД)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Језик тастатуре: шпански"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Језик тастатуре: фински"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Језик тастатуре: француски"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Језик тастатуре: француски (Канада)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Језик тастатуре: француски (Швајц.)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Језик тастатуре: хрватски"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Језик тастатуре: мађарски"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Језик тастатуре: хебрејски"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Језик тастатуре: италијански"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Језик тастатуре: норвешки"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Језик тастатуре: холандски"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Језик тастатуре: пољски"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Језик тастатуре: португалски"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Језик тастатуре: руски"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Језик тастатуре: српски"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Језик тастатуре: шведски"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Језик тастатуре: турски"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Глас на африкансу"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Глас на чешком"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Глас на немачком"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Глас на јуе кинеском"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Глас на мандаринском кинеском"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Глас на језику исизулу"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Режим за студију могућности коришћења"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за студију могућности коришћења"</string>
</resources>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index eaf350583..a2db22bd4 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Knappljud"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup vid knapptryck"</string>
<string name="general_category" msgid="1859088467017573195">"Allmänt"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Textkorrigering"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Textkorrigering"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Förslag baserade på tidigare ord"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Andra alternativ"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Avancerade inställningar"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Alternativ för expertanvändare"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Ta bort popup-fördröjning"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Fördröj inte"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Standard"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Föreslå kontaktnamn"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Använd namn från Kontakter för förslag och korrigeringar"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Konfigurera ordböcker"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Snabba lösningar"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Åtgärdar automatiskt vanliga misstag"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Visa rättningsförslag"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Visa alltid"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Visa stående"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Dölj alltid"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Byt språk m. mellanslag"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Visa inställningsknapp"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Automatiskt"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Visa alltid"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Av"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Måttlig"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Aggressiv"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigramförslag"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Mycket aggressivt"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigramförslag"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Förbättra förslaget med föregående ord"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigramförslag"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Använd även föregående ord för att ge förslag"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Mer"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Vänta"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Ta bort"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Retur"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Inställningar"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Skift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Blanksteg"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Symboler"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tabb"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Röstinmatning"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Aktivera symboler"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Inaktivera symboler"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Aktivera Skift"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Inaktivera Skift"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Nuvarande text är %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Ingen text har angetts"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Nyckelkod %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Skift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Skift aktiverat"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock är aktiverat"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symboler"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Brev"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Siffror"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Inställningar"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabb"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Blanksteg"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Röstinmatning inaktiv"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Välj inmatningsmetod"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Inmatningsspråk"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Dra med fingret på blanksteg om du vill ändra språk"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Tryck igen för att spara"</string>
<string name="has_dictionary" msgid="6071847973466625007">"En ordlista är tillgänglig"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Tryck om du vill korrigera ord"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Tryck på skrivna ord om du vill korrigera dem, endast när förslag visas"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tangentbordstema"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tangentbordstema"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Tjeckiskt tangentbord"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabiskt tangentbord"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danskt tangentbord"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Tyskt tangentbord"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Tyskt QWERTY-tangentbord"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Engelskt tangentbord (Storbrit.)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Engelskt tangentbord (USA)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spanskt tangentbord"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finskt tangentbord"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Franskt tangentbord"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Franskt tangentbord (Kanada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Franskt tangentbord (Schweiz)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Kroatiskt tangentbord"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Ungerskt tangentbord"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebreiskt tangentbord"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italienskt tangentbord"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norskt tangentbord"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Holländskt tangentbord"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polskt tangentbord"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portugisiskt tangentbord"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ryskt tangentbord"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbiskt tangentbord"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Svenskt tangentbord"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turkiskt tangentbord"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Röst, afrikaans"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Röst på tjeckiska"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Röst på tyska"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Röst, kinesiska, yue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Röst, kinesiska, mandarin"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Röst, isiZulusk"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Läge för användbarhetsstudie"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Läge för studie av användbarhet"</string>
</resources>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
new file mode 100644
index 000000000..6057acd49
--- /dev/null
+++ b/java/res/values-sw/strings.xml
@@ -0,0 +1,256 @@
+<?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.
+*/
+ -->
+
+<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="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="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>
+ <!-- no translation found for general_category (1859088467017573195) -->
+ <skip />
+ <!-- no translation found for correction_category (2236750915056607613) -->
+ <skip />
+ <!-- no translation found for ngram_category (5337109164339320257) -->
+ <skip />
+ <!-- no translation found for misc_category (6894192814868233453) -->
+ <skip />
+ <!-- no translation found for advanced_settings (362895144495591463) -->
+ <skip />
+ <!-- no translation found for advanced_settings_summary (5193513161106637254) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict (4435317977804180815) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict_summary (6599983334507879959) -->
+ <skip />
+ <string name="auto_cap" msgid="1719746674854628252">"Uwekaji wa herufi kubwa kiotomatiki"</string>
+ <!-- no translation found for configure_dictionaries_title (3758288002414557345) -->
+ <skip />
+ <string name="quick_fixes" msgid="5353213327680897927">"Utatuzi wa haraka"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Husahihisha makosa ya kawaida yaliyoandikwa"</string>
+ <!-- no translation found for prefs_show_suggestions (8026799663445531637) -->
+ <skip />
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Onyesha maneno yaliyopendekezwa wakati unachapa"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Onyesha kila wakati"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Onyesha kwenye hali wima"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Ficha kila wakati"</string>
+ <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) -->
+ <skip />
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Onyesha kitufe cha mipangilio"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Kiotomatiki"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Onyesha kila wakati"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">" Ficha kila mara"</string>
+ <string name="auto_correction" msgid="4979925752001319458">"Usahihishaji Kioto"</string>
+ <!-- outdated translation 6881047311475758267 --> <string name="auto_correction_summary" msgid="5625751551134658006">"Sahihisha neno lililotangulia kiotomatiki"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Zima"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ya wastani"</string>
+ <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Ya hima"</string>
+ <!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) -->
+ <skip />
+ <!-- outdated translation 1323347224043514969 --> <string name="bigram_suggestion" msgid="2636414079905220518">"Mapendekezo ya Bigramu"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Tumia neno la hapo awali ili kuboresha pendekezo"</string>
+ <!-- no translation found for bigram_prediction (8914273444762259739) -->
+ <skip />
+ <!-- no translation found for bigram_prediction_summary (1747261921174300098) -->
+ <skip />
+ <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>
+ <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>
+ <string name="label_more_key" msgid="3760239494604948502">"Zaidi"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Pumzisha"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Subiri"</string>
+ <!-- no translation found for spoken_current_text_is (2485723011272583845) -->
+ <skip />
+ <!-- no translation found for spoken_no_text_entered (7479685225597344496) -->
+ <skip />
+ <!-- no translation found for spoken_description_unknown (3197434010402179157) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift (244197883292549308) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift_shifted (954941524766465022) -->
+ <skip />
+ <!-- no translation found for spoken_description_caps_lock (5660626444912131764) -->
+ <skip />
+ <!-- no translation found for spoken_description_delete (8740376944276199801) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_symbol (5486340107500448969) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_alpha (23129338819771807) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_numeric (591752092685161732) -->
+ <skip />
+ <!-- no translation found for spoken_description_settings (4627462689603838099) -->
+ <skip />
+ <!-- no translation found for spoken_description_tab (2667716002663482248) -->
+ <skip />
+ <!-- no translation found for spoken_description_space (2582521050049860859) -->
+ <skip />
+ <!-- no translation found for spoken_description_mic (615536748882611950) -->
+ <skip />
+ <!-- no translation found for spoken_description_smiley (2256309826200113918) -->
+ <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) -->
+ <skip />
+ <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <skip />
+ <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
+ <skip />
+ <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>
+ <string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"Ili kuzima uingizaji sauti, nenda kwa mipangilio ya mbinu ya uingizaji."</string>
+ <string name="voice_hint_dialog_message" msgid="1420686286820661548">"Ili kutumia uingizaji wa sauti, bonyeza kitufe cha maikrofoni."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Ongea sasa"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Inafanya kazi"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Hitilafu. Tafadhali jaribu tena."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Haiwezi kuunganisha"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Hitilafu, usemi ni zaidi."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Tatizo la sauti"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Hitilafu ya Seva"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Hakuna matamshi yaliyosikizwa"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Hakuna zinazolingana zilizopatikana."</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Utafutaji wa sauti haujawekwa"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Kidokezo:"</b>" Telezesha kidole kwenye kibodi ili utamke"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Kidokezo:"</b>" Wakati mwingine, jaribu kutamka uakifishaji kama vile \"kituo\", \"koma\", au \"kiulizio cha swali\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Ghairi"</string>
+ <string name="ok" msgid="7898366843681727667">"Sawa"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Uingizaji wa sauti"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Kwenye kibodi kuu"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Kwenye kibodi ya ishara"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Zima"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Maikrofoni kwenye kibodi kuu"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Maikrofoni kwenye kibodi ya ishara"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Uingizaji sauti umelemazwa"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Chagua mtindo wa uingizaji"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Lugha za uingizaji"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Gusa tena ili kuhifadhi"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Kamusi inapatikana"</string>
+ <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="prefs_enable_recorrection" msgid="4588408906649533582">"Gusa ili kurekebisha maneno"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Gusa maneno yaliyoingizwa ili kuyasahihisha, wakati mapendekezo yanaonekana tu"</string>
+ <!-- outdated translation 437433231038683666 --> <string name="keyboard_layout" msgid="8451164783510487501">"Maandhari ya Kibodi"</string>
+ <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Kibodi ya Kicheki"</string>
+ <!-- no translation found for subtype_mode_ar_keyboard (2655338636329774995) -->
+ <skip />
+ <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Kibodi ya Kidenmaki"</string>
+ <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Kibodi ya Kijerumani"</string>
+ <!-- no translation found for subtype_mode_de_qwerty_keyboard (54890770769303956) -->
+ <skip />
+ <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Kibodi ya Kiingereza (Uingereza)"</string>
+ <string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Kibodi ya Kiingereza (Marekani)"</string>
+ <string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Kibodi ya Kihispania"</string>
+ <!-- no translation found for subtype_mode_fi_keyboard (3198596464082614532) -->
+ <skip />
+ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Kibodi ya Kifaransa"</string>
+ <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Kibodi ya Kifaransa (Kanada)"</string>
+ <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Kibodi ya Kifaransa (Uswizi)"</string>
+ <!-- no translation found for subtype_mode_hr_keyboard (7177182405440070112) -->
+ <skip />
+ <!-- no translation found for subtype_mode_hu_keyboard (8843338355732633647) -->
+ <skip />
+ <!-- no translation found for subtype_mode_iw_keyboard (1787536828253289950) -->
+ <skip />
+ <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Kibodi ya Kiitaliano"</string>
+ <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Kibodi ya Kinorwe"</string>
+ <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Kibodi ya Kiholanzi"</string>
+ <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) -->
+ <skip />
+ <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) -->
+ <skip />
+ <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Kibodi ya Kirusi"</string>
+ <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Kibodi ya Kiserbia"</string>
+ <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Kibodi ya Kiswidi"</string>
+ <!-- no translation found for subtype_mode_tr_keyboard (3155981874829226370) -->
+ <skip />
+ <!-- no translation found for subtype_mode_af_voice (7542487489657902699) -->
+ <skip />
+ <string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Sauti ya Kicheki"</string>
+ <string name="subtype_mode_de_voice" msgid="8378803143958089866">"Sauti ya Kijerumani"</string>
+ <!-- no translation found for subtype_mode_en_voice (6643420989651848728) -->
+ <skip />
+ <string name="subtype_mode_es_voice" msgid="1323473601346507487">"Sauti ya Kihispania"</string>
+ <string name="subtype_mode_fr_voice" msgid="4675914209337824269">"Sauti ya Kifaransa"</string>
+ <!-- no translation found for subtype_mode_it_voice (5077373057157441323) -->
+ <skip />
+ <string name="subtype_mode_ja_voice" msgid="6604859132669646367">"Sauti ya Kijapani"</string>
+ <string name="subtype_mode_ko_voice" msgid="4890391190762324561">"Sauti ya Kikorea"</string>
+ <!-- no translation found for subtype_mode_nl_voice (2603552312869575021) -->
+ <skip />
+ <string name="subtype_mode_pl_voice" msgid="2076196021014840487">"Sauti ya Kipolandi"</string>
+ <string name="subtype_mode_pt_voice" msgid="8036522712795994397">"Sauti ya Kireno"</string>
+ <string name="subtype_mode_ru_voice" msgid="8034596947963787529">"Sauti ya Kirusi"</string>
+ <string name="subtype_mode_tr_voice" msgid="3402067436761140005">"Sauti ya Kituruki"</string>
+ <!-- no translation found for subtype_mode_yue_voice (1576887891614624263) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zh_voice (4360533229467271152) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zu_voice (1146122571698884636) -->
+ <skip />
+ <!-- outdated translation 6937813623647419810 --> <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Hali ya Uchunguzi wa Utumizi"</string>
+</resources>
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 618b7f44c..5d4967ffe 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -21,19 +21,35 @@
<resources>
<!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
<dimen name="keyboardHeight">45.0mm</dimen>
- <!-- key_height + key_bottom_gap = popup_key_height -->
- <!-- <dimen name="key_height">14.5mm</dimen> -->
- <dimen name="key_bottom_gap">1.3mm</dimen>
- <dimen name="key_horizontal_gap">1.3mm</dimen>
+ <fraction name="minKeyboardHeight">45%p</fraction>
+
+ <dimen name="keyboard_horizontal_edges_padding">0dp</dimen>
+ <fraction name="keyboard_top_padding">2.444%p</fraction>
+ <fraction name="keyboard_bottom_padding">0.0%p</fraction>
+ <fraction name="key_bottom_gap">4.911%p</fraction>
+ <fraction name="key_horizontal_gap">1.284%p</fraction>
+
+ <dimen name="keyboardHeight_stone">45.0mm</dimen>
+ <fraction name="key_bottom_gap_stone">4.355%p</fraction>
+ <fraction name="key_horizontal_gap_stone">1.505%p</fraction>
+
+ <fraction name="key_bottom_gap_gb">5.200%p</fraction>
+ <fraction name="key_horizontal_gap_gb">1.447%p</fraction>
+
+ <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
+
<dimen name="popup_key_height">13.0mm</dimen>
- <dimen name="keyboard_top_padding">1.1mm</dimen>
- <dimen name="keyboard_bottom_padding">0.0mm</dimen>
- <!-- key_height x 1.0 -->
- <dimen name="key_preview_height">13.0mm</dimen>
- <dimen name="key_letter_size">25dip</dimen>
- <dimen name="key_label_text_size">18dip</dimen>
<!-- left or right padding of label alignment -->
- <dimen name="key_label_horizontal_alignment_padding">18dip</dimen>
+ <dimen name="key_label_horizontal_padding">18dip</dimen>
+
+ <fraction name="key_letter_ratio">45%</fraction>
+ <fraction name="key_large_letter_ratio">45%</fraction>
+ <fraction name="key_label_ratio">32%</fraction>
+ <fraction name="key_hint_letter_ratio">23%</fraction>
+ <fraction name="key_hint_label_ratio">34%</fraction>
+ <fraction name="key_uppercase_letter_ratio">29%</fraction>
+
<dimen name="candidate_strip_padding">40.0mm</dimen>
+ <integer name="candidate_count_in_strip">5</integer>
</resources>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index c3d34456e..011054df3 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -20,19 +20,17 @@
<resources>
<bool name="config_enable_show_settings_key_option">true</bool>
- <bool name="config_enable_show_subtype_settings">false</bool>
<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_show_recorrection_option">false</bool>
<bool name="config_enable_quick_fixes_option">false</bool>
<bool name="config_enable_bigram_suggestions_option">false</bool>
- <bool name="config_candidate_highlight_font_color_enabled">false</bool>
- <bool name="config_swipe_down_dismiss_keyboard_enabled">false</bool>
<bool name="config_sliding_key_input_enabled">false</bool>
<bool name="config_digit_popup_characters_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>
<bool name="config_use_spacebar_language_switcher">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>
diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml
index 27d577c7d..20876a202 100644
--- a/java/res/values-sw600dp/dimens.xml
+++ b/java/res/values-sw600dp/dimens.xml
@@ -21,29 +21,52 @@
<resources>
<!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
<dimen name="keyboardHeight">48.0mm</dimen>
- <!-- key_height + key_bottom_gap = popup_key_height -->
- <!-- <dimen name="key_height">14.5mm</dimen> -->
- <dimen name="key_bottom_gap">1.0mm</dimen>
- <dimen name="key_horizontal_gap">1.0mm</dimen>
+ <fraction name="maxKeyboardHeight">50%p</fraction>
+ <fraction name="minKeyboardHeight">-35.0%p</fraction>
+
<dimen name="popup_key_height">10.0mm</dimen>
- <dimen name="keyboard_top_padding">1.1mm</dimen>
- <dimen name="keyboard_bottom_padding">0.0mm</dimen>
- <!-- key_height x 1.0 -->
- <dimen name="key_preview_height">13.0mm</dimen>
- <dimen name="mini_keyboard_key_horizontal_padding">12dip</dimen>
+
+ <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
+ <fraction name="keyboard_top_padding">2.291%p</fraction>
+ <fraction name="keyboard_bottom_padding">0.0%p</fraction>
+ <fraction name="key_bottom_gap">3.750%p</fraction>
+ <fraction name="key_horizontal_gap">1.857%p</fraction>
+
+ <dimen name="keyboardHeight_stone">48.0mm</dimen>
+ <fraction name="key_bottom_gap_stone">3.75%p</fraction>
+ <fraction name="key_horizontal_gap_stone">1.602%p</fraction>
+
+ <fraction name="key_bottom_gap_gb">4.625%p</fraction>
+ <fraction name="key_horizontal_gap_gb">2.113%p</fraction>
+
+ <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
+
+ <dimen name="mini_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>
<!-- popup_key_height x -1.0 -->
<dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
- <dimen name="key_letter_size">24dip</dimen>
- <dimen name="key_label_text_size">14dip</dimen>
- <dimen name="key_preview_text_size_large">24dip</dimen>
<!-- left or right padding of label alignment -->
- <dimen name="key_label_horizontal_alignment_padding">6dip</dimen>
+ <dimen name="key_label_horizontal_padding">6dip</dimen>
+ <dimen name="key_hint_letter_padding">3dp</dimen>
+ <dimen name="key_uppercase_letter_padding">3dp</dimen>
+
+ <fraction name="key_letter_ratio">37%</fraction>
+ <fraction name="key_large_letter_ratio">37%</fraction>
+ <fraction name="key_label_ratio">22%</fraction>
+ <fraction name="key_hint_letter_ratio">23%</fraction>
+ <fraction name="key_hint_label_ratio">26%</fraction>
+ <fraction name="key_uppercase_letter_ratio">25%</fraction>
+ <fraction name="key_preview_text_ratio">50%</fraction>
+ <dimen name="key_preview_height">15.0mm</dimen>
+ <dimen name="key_preview_offset">0.1in</dimen>
+
+ <dimen name="key_preview_height_ics">15.0mm</dimen>
+ <dimen name="key_preview_offset_ics">0.05in</dimen>
- <dimen name="candidate_strip_height">46dip</dimen>
+ <dimen name="candidate_strip_height">44dip</dimen>
<dimen name="candidate_strip_padding">15.0mm</dimen>
<dimen name="candidate_min_width">0.3in</dimen>
<dimen name="candidate_padding">12dip</dimen>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index c40671082..18837fecc 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -19,21 +19,45 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=14.5mm -->
<dimen name="keyboardHeight">58.0mm</dimen>
- <!-- key_height + key_bottom_gap = popup_key_height -->
- <!-- <dimen name="key_height">14.5mm</dimen> -->
- <dimen name="key_bottom_gap">1.6mm</dimen>
- <dimen name="key_horizontal_gap">1.6mm</dimen>
+ <fraction name="minKeyboardHeight">45%p</fraction>
+
+ <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
+ <fraction name="keyboard_top_padding">1.896%p</fraction>
+ <fraction name="keyboard_bottom_padding">0.0%p</fraction>
+
+ <fraction name="key_bottom_gap">4.103%p</fraction>
+ <fraction name="key_horizontal_gap">1.034%p</fraction>
+
+ <dimen name="keyboardHeight_stone">58.0mm</dimen>
+ <fraction name="key_bottom_gap_stone">3.379%p</fraction>
+ <fraction name="key_horizontal_gap_stone">1.062%p</fraction>
+
+ <fraction name="key_bottom_gap_gb">3.896%p</fraction>
+ <fraction name="key_horizontal_gap_gb">1.195%p</fraction>
+
+ <fraction name="keyboard_top_padding_ics">1.896%p</fraction>
+ <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
+ <fraction name="key_bottom_gap_ics">3.690%p</fraction>
+ <fraction name="key_horizontal_gap_ics">1.030%p</fraction>
+
<dimen name="popup_key_height">13.0mm</dimen>
- <dimen name="keyboard_top_padding">1.1mm</dimen>
- <dimen name="keyboard_bottom_padding">0.0mm</dimen>
- <!-- key_height x 1.0 -->
- <dimen name="key_preview_height">13.0mm</dimen>
- <dimen name="key_letter_size">28dip</dimen>
- <dimen name="key_label_text_size">20dip</dimen>
<!-- left or right padding of label alignment -->
- <dimen name="key_label_horizontal_alignment_padding">18dip</dimen>
+ <dimen name="key_label_horizontal_padding">18dip</dimen>
+
+ <fraction name="key_letter_ratio">43%</fraction>
+ <fraction name="key_large_letter_ratio">42%</fraction>
+ <fraction name="key_label_ratio">28%</fraction>
+ <fraction name="key_hint_letter_ratio">23%</fraction>
+ <fraction name="key_hint_label_ratio">28%</fraction>
+ <fraction name="key_uppercase_letter_ratio">24%</fraction>
+ <dimen name="key_preview_height">17.0mm</dimen>
+
+ <dimen name="key_preview_height_ics">26.5mm</dimen>
+ <dimen name="key_preview_offset_ics">0.05in</dimen>
+
<dimen name="candidate_strip_padding">40.0mm</dimen>
+ <integer name="candidate_count_in_strip">5</integer>
</resources>
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index f075b1b50..2828f9d1b 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -20,26 +20,25 @@
<resources>
<bool name="config_enable_show_settings_key_option">false</bool>
- <bool name="config_enable_show_subtype_settings">false</bool>
<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_show_recorrection_option">false</bool>
<bool name="config_enable_quick_fixes_option">false</bool>
<bool name="config_enable_bigram_suggestions_option">false</bool>
- <bool name="config_candidate_highlight_font_color_enabled">false</bool>
- <bool name="config_swipe_down_dismiss_keyboard_enabled">false</bool>
<bool name="config_sliding_key_input_enabled">false</bool>
<bool name="config_digit_popup_characters_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>
<bool name="config_use_spacebar_language_switcher">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>
+ <integer name="config_delay_update_suggestions">180</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_popup_keyboard_column">5</integer>
+ <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" -->
+ <integer name="log_screen_metrics">2</integer>
</resources>
diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml
index 9ea5258df..f0340bc70 100644
--- a/java/res/values-sw768dp/dimens.xml
+++ b/java/res/values-sw768dp/dimens.xml
@@ -19,17 +19,31 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=12mm -->
<dimen name="keyboardHeight">48.0mm</dimen>
- <!-- key_height + key_bottom_gap = popup_key_height -->
- <!-- <dimen name="key_height">14.5mm</dimen> -->
- <dimen name="key_bottom_gap">1.1mm</dimen>
- <dimen name="key_horizontal_gap">1.1mm</dimen>
+ <fraction name="maxKeyboardHeight">50%p</fraction>
+ <fraction name="minKeyboardHeight">-35.0%p</fraction>
+
+ <dimen name="keyboard_horizontal_edges_padding">0.0mm</dimen>
+ <fraction name="keyboard_top_padding">2.291%p</fraction>
+ <fraction name="keyboard_bottom_padding">0.0%p</fraction>
+
+ <fraction name="key_bottom_gap">4.270%p</fraction>
+ <fraction name="key_horizontal_gap">1.551%p</fraction>
+
+ <dimen name="keyboardHeight_stone">48.0mm</dimen>
+ <fraction name="key_bottom_gap_stone">3.75%p</fraction>
+ <fraction name="key_horizontal_gap_stone">1.059%p</fraction>
+
+ <fraction name="key_bottom_gap_gb">4.687%p</fraction>
+ <fraction name="key_horizontal_gap_gb">1.272%p</fraction>
+
+ <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
+ <fraction name="key_bottom_gap_ics">3.312%p</fraction>
+ <fraction name="key_horizontal_gap_ics">1.066%p</fraction>
+
<dimen name="popup_key_height">10.0mm</dimen>
- <dimen name="keyboard_top_padding">1.1mm</dimen>
- <dimen name="keyboard_bottom_padding">0.0mm</dimen>
- <!-- key_height x 1.0 -->
- <dimen name="key_preview_height">13.0mm</dimen>
+
<dimen name="mini_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 -->
@@ -37,15 +51,30 @@
<!-- popup_key_height x -1.0 -->
<dimen name="mini_keyboard_vertical_correction">-13.0mm</dimen>
- <dimen name="key_letter_size">26dip</dimen>
- <dimen name="key_label_text_size">16dip</dimen>
- <dimen name="key_preview_text_size_large">24dip</dimen>
<!-- left or right padding of label alignment -->
- <dimen name="key_label_horizontal_alignment_padding">6dip</dimen>
+ <dimen name="key_label_horizontal_padding">6dip</dimen>
+ <dimen name="key_hint_letter_padding">3dp</dimen>
+ <dimen name="key_uppercase_letter_padding">3dp</dimen>
+
+ <fraction name="key_letter_ratio">40%</fraction>
+ <fraction name="key_large_letter_ratio">42%</fraction>
+ <fraction name="key_label_ratio">28%</fraction>
+ <fraction name="key_hint_letter_ratio">23%</fraction>
+ <fraction name="key_hint_label_ratio">28%</fraction>
+ <fraction name="key_uppercase_letter_ratio">26%</fraction>
+ <fraction name="key_preview_text_ratio">50%</fraction>
+ <dimen name="key_preview_height">15.0mm</dimen>
+ <dimen name="key_preview_offset">0.1in</dimen>
+
+ <dimen name="key_preview_height_ics">15.0mm</dimen>
+ <dimen name="key_preview_offset_ics">0.05in</dimen>
- <dimen name="candidate_strip_height">46dip</dimen>
+ <dimen name="candidate_strip_height">44dip</dimen>
+ <!-- candidate_strip_minimum_height =
+ key_preview_height_holo - key_preview_offset_holo + alpha -->
+ <dimen name="candidate_strip_minimum_height">18mm</dimen>
<dimen name="candidate_strip_padding">15.0mm</dimen>
- <dimen name="candidate_min_width">0.3in</dimen>
- <dimen name="candidate_padding">12dip</dimen>
+ <dimen name="candidate_min_width">46dip</dimen>
+ <dimen name="candidate_padding">8dip</dimen>
<dimen name="candidate_text_size">22dip</dimen>
</resources>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index 6dc813b74..ce8f9f1c9 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"ส่งเสียงเมื่อกดปุ่ม"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"ป๊อปอัปเมื่อกดแป้น"</string>
<string name="general_category" msgid="1859088467017573195">"ทั่วไป"</string>
- <string name="prediction_category" msgid="6361242011806282176">"การแก้ไขข้อความ"</string>
+ <string name="correction_category" msgid="2236750915056607613">"การแก้ไขข้อความ"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"ข้อเสนอแนะตามคำก่อนหน้านี้"</string>
+ <string name="misc_category" msgid="6894192814868233453">"ตัวเลือกอื่นๆ"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"การตั้งค่าขั้นสูง"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"ตัวเลือกสำหรับผู้ใช้ที่มีความเชี่ยวชาญ"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"การหน่วงเวลาก่อนปิดป๊อปอัพหลัก"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ไม่มีการหน่วงเวลา"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ค่าเริ่มต้น"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"แนะนำชื่อผู้ติดต่อ"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"ใช้ชื่อจากรายชื่อติดต่อสำหรับคำแนะนำและการแก้ไข"</string>
<string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"กำหนดค่าพจนานุกรม"</string>
<string name="quick_fixes" msgid="5353213327680897927">"แก้ไขด่วน"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"แก้ไขข้อผิดพลาดในการพิมพ์ที่พบบ่อย"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"แสดงคำแนะนำการแก้ไข"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"ใช้แป้น Spacebar เพื่อสลับภาษา"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"แสดงแป้นการตั้งค่า"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"อัตโนมัติ"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"แสดงตลอดเวลา"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ปิด"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ปานกลาง"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"เข้มงวด"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"คำแนะนำ Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"สูง"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"คำแนะนำ Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"ใช้คำก่อนหน้านี้เพื่อปรับปรุงคำแนะนำ"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"การคาดคะเน Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"ใช้คำก่อนหน้านี้สำหรับการคาดคะเน"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"เพิ่มเติม"</string>
<string name="label_pause_key" msgid="181098308428035340">"หยุดชั่วคราว"</string>
<string name="label_wait_key" msgid="6402152600878093134">"รอ"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"ลบ"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"การตั้งค่า"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Space"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"สัญลักษณ์"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"ป้อนข้อมูลด้วยเสียง"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"สัญลักษณ์เปิดอยู่"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"สัญลักษณ์ปิดอยู่"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift เปิดอยู่"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift ปิดอยู่"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"ข้อความปัจจุบันคือ %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"ไม่มีข้อความ"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"รหัสคีย์ %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"เปิดใช้งาน Shift แล้ว"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"เปิดใช้งาน Caps Lock แล้ว"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"ลบ"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"สัญลักษณ์"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"ตัวอักษร"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"หมายเลข"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"การตั้งค่า"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"แท็บ"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Space"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"ปิดใช้งานป้อนข้อมูลด้วยเสียง"</string>
<string name="selectInputMethod" msgid="315076553378705821">"เลือกวิธีการป้อนข้อมูล"</string>
<string name="language_selection_title" msgid="1651299598555326750">"ภาษาในการป้อนข้อมูล"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"เลื่อนนิ้วไปบนแป้นเคาะวรรคเพื่อเปลี่ยนภาษา"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← แตะอีกครั้งเพื่อบันทึก"</string>
<string name="has_dictionary" msgid="6071847973466625007">"มีพจนานุกรมให้ใช้งาน"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"เปิดใช้งานการแสดงความคิดเห็นจากผู้ใช้"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"ช่วยปรับปรุงตัวแก้ไขวิธีการป้อนข้อมูลนี้โดยการส่งสถิติการใช้งานและรายงานการขัดข้องถึง Google โดยอัตโนมัติ"</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"แตะเพื่อแก้ไขคำ"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"แตะคำที่ป้อนไว้เพื่อแก้ไข เฉพาะเมื่อเห็นข้อเสนอแนะเท่านั้น"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"ชุดรูปแบบแป้นพิมพ์"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"ชุดรูปแบบแป้นพิมพ์"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"แป้นพิมพ์ภาษาเช็ก"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"แป้นพิมพ์ภาษาอาหรับ"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"แป้นพิมพ์ภาษาเดนมาร์ก"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"แป้นพิมพ์ภาษาเยอรมัน"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"แป้นพิมพ์ภาษาเยอรมันแบบ QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"แป้นพิมพ์ภาษาอังกฤษ (สหราชอาณาจักร)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"แป้นพิมพ์ภาษาอังกฤษ (สหรัฐอเมริกา)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"แปันพิมพ์ภาษาสเปน"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"แป้นพิมพ์ภาษาฟินแลนด์"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"แป้นพิมพ์ภาษาฝรั่งเศส"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"แป้นพิมพ์ภาษาฝรั่งเศส (แคนาดา)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"แป้นพิมพ์ภาษาฝรั่งเศส (สวิตเซอร์แลนด์)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"แป้นพิมพ์ภาษาโครเอเชีย"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"แป้นพิมพ์ภาษาฮังกาเรียน"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"แป้นพิมพ์ภาษาฮิบรู"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"แป้นพิมพ์ภาษาอิตาลี"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"แป้นพิมพ์ภาษานอร์เวย์"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"แป้นพิมพ์ภาษาดัตช์"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"แป้นพิมพ์ภาษาโปแลนด์"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"แป้นพิมพ์ภาษาโปรตุเกส"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"แป้นพิมพ์ภาษารัสเซีย"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"แป้นพิมพ์ภาษาเซอร์เบีย"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"แป้นพิมพ์ภาษาสวีเดน"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"แป้นพิมพ์ภาษาตุรกี"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"เสียงภาษาแอฟริกัน"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"เสียงภาษาเช็ก"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"เสียงภาษาเยอรมัน"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"เสียงภาษาจีนกวางตุ้ง"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"เสียงภาษาจีนกลาง"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"เสียงภาษาซูลู"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"โหมดศึกษาประโยชน์ในการใช้งาน"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"โหมดศึกษาประโยชน์ในการใช้งาน"</string>
</resources>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index bdd700b67..0d260aff8 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Tunog sa keypress"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Popup sa keypress"</string>
<string name="general_category" msgid="1859088467017573195">"Pangkalahatan"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Pagwawasto ng teksto"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Pagwawasto ng teksto"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Mga suhestiyon batay sa mga nakaraang salita"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Iba pang mga pagpipilian"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Mga advanced na setting"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Mga pagpipilian para sa mga ekspertong user"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Balewala antala key popup"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Walang antala"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Mungkahi pangalan Contact"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gamitin pangalan mula Mga Contact sa mga mungkahi\'t pagwawasto"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"I-configure ang mga diksyunaryo"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Mga mabilisang pagsasaayos"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Itinatama ang mga karaniwang na-type na mali"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Magpakita ng mga suhestiyon ng pagwawasto"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Palaging ipakita"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Ipakita sa portrait mode"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Palaging itago"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Gamitin ang panglipat ng wika sa spacebar"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Ipakita ang key ng mga setting"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Awtomatiko"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Palaging ipakita"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Naka-off"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresibo"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Mga Suhestiyon na Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Napaka-agresibo"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Mga bigram na suhestiyon"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Gamitin ang nakaraang salita upang pahusayin ang suhestiyon"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram na hula"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Gamitin ang nakaraang salita para din sa hula"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Higit pa"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Intay"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Tanggalin"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Bumalik"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Mga Setting"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Puwang"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Mga Simbolo"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Input ng Boses"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Naka-on ang mga simbolo"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Naka-off ang mga simbolo"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Naka-on ang shift"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Naka-off ang shift"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Ang kasalukuyang teksto ay %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Walang tekstong inilagay"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Code ng key %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Pinagana ang shift"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Pinagana ang caps lock"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Tanggalin"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Mga Simbolo"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Mga Titik"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Mga Numero"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Mga Setting"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Puwang"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Hindi pinagana ang voice input"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Pumili ng paraan ng pag-input"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Mag-input ng mga wika"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"I-slide ang daliri sa spacebar upang palitan ang wika"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Pinduting muli upang i-save"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Available ang diksyunaryo"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Pindutin upang itama ang mga salita"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Pindutin ang mga inilagay na salita upang iwasto ang mga ito, kapag nakikita lang ang mga suhestiyon"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Tema ng Keyboard"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema ng keyboard"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Czech na Keyboard"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arabic na Keyboard"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danish na Keyboard"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"German na Keyboard"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"German na QWERTY Keyboard"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Ingles (UK) na Keyboard"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Ingles (US) na Keyboard"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Spanish na Keyboard"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Finnish na Keyboard"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"French na Keyboard"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"French (Canada) na Keyboard"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"French (Switzerland) na Keyboard"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Croatian na Keyboard"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Hungarian na Keyboard"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Hebrew na Keyboard"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Italian na Keyboard"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norwegian na Keyboard"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Dutch na Keyboard"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Polish na Keyboard"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portuguese na Keyboard"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Russian na Keyboard"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Serbian na Keyboard"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Swedish na Keyboard"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Turkish na Keyboard"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikaans na Boses"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Czech na Boses"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"German na Boses"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Chinese, Yue na Boses"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Chinese, Mandarin na Boses"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"isiZulu na Boses"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Usability Study Mode"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Study mode ng pagiging kapaki-pakinabang"</string>
</resources>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index a88b50960..cfaeaee39 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Genel"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Metin düzeltme"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Metin düzeltme"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Önceki kelimelere dayalı öneriler"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Diğer seçenekler"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Gelişmiş ayarlar"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Uzman kullanıcılar için seçenekler"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Tuş popup içn kaptm ertlm"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Gecikme yok"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Varsayılan"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Kişi Adları öner"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Öneri ve düzeltmeler için Kişiler\'deki adları kullan"</string>
<string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Sözlükleri yapılandır"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Hızlı onarımlar"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Yaygın olarak yapılan yazım hatalarını düzeltir"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Düzeltme önerilerini göster"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Her zaman göster"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Dikey modda göster"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Her zaman gizle"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Dil geçişi &gt; boşluk çubuğuyla"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Ayarları göster tuşu"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Otomatik"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Her zaman göster"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Kapalı"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ölçülü"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Agresif"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Bigram Önerileri"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Çok geniş ölçekte"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Bigram önerileri"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Öneriyi geliştirmek için önceki kelimeyi kullanın"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Bigram tahmini"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Önceki kelimeyi de tahmin için kullan"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Diğer"</string>
<string name="label_pause_key" msgid="181098308428035340">"Durkl"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Bekle"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Sil"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Ayarlar"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Üst Karakter"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Boşluk"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Simgeler"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Sekme"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Ses Girişi"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Simgeler açık"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Simgeler kapalı"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Üst Karakter açık"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Üst Karakter kapalı"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Mevcut metin: %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Hiç metin girilmedi"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Tuş kodu: %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Üst Karakter"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Üst Karakter Etkin"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Büyük harf etkin"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simgeler"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Harfler"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Rakamlar"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Ayarlar"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Sekme"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Boşluk"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Sesle grş devre dışı"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Giriş yöntemini seç"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Giriş dilleri"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Dili değiştirmek için parmağınızı boşluk çubuğu üzerinde kaydırın"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Kaydetmek için tekrar dokunun"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Sözlük kullanılabilir"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Kelimeleri düzeltmek için dokunun"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Yalnızca öneriler görünür olduğunda, düzeltmek için girilen kelimelere dokunun"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Klavye Teması"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Klavye teması"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Çekçe Klavye"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Arapça Klavye"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Danca Klavye"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Almanca Klavye"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Almanca QWERTY Klavye"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"İngilizce (İngiltere) Klavye"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"İngilizce (ABD) Klavye"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"İspanyolca Klavye"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Fince klavye"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Fransızca Klavye"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Fransızca (Kanada) Klavye"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Fransızca (İsviçre) Klavye"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Hırvatça Klavye"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Macarca Klavye"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"İbranice Klavye"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"İtalyanca Klavye"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Norveççe Klavye"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Felemenkçe Klavye"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Lehçe Klavye"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Portekizce Klavye"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Rusça Klavye"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Sırpça Klavye"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"İsveççe Klavye"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Türkçe Klavye"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Afrikanca Ses"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Çekçe Ses"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Almanca Ses"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Çince, Yue Ses"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Çince, Mandarin Ses"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Zuluca Ses"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Kullanılabilirlik Çalışması Modu"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kullanılabilirlik çalışması modu"</string>
</resources>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 5010ee9b5..11b174f16 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"Звук при натиску клав."</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Сплив. при нат.клав."</string>
<string name="general_category" msgid="1859088467017573195">"Загальні"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Виправлення тексту"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Виправлення тексту"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Пропозиції на основі попередніх слів"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Інші опції"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Розширені налаштування"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Налаштування для досвідчених користувачів"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Затримка клавіши закриття"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Без затримки"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"За умовчанням"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Пропон. імена контактів"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Використ. імена зі списку контактів для пропозицій і виправлень"</string>
<string name="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Налаштувати словники"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Шв. виправлення"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Виправляє поширені помилки"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Показувати пропозиції виправлень"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"Використ. зміну мови пробілом"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Показ. клав. налашт."</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Автоматично"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Завжди показ."</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Вимк."</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Середнє"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Повне"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Двобуквені пропозиції"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Повне виправлення"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Пропозиції з двох слів"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Викор. попер. слово для покращ. пропозиції"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Передбачений запит із двох слів"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Використовувати попереднє слово також як передбачений запит"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Більше"</string>
<string name="label_pause_key" msgid="181098308428035340">"Пауза"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Чек."</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Клавіша Delete"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Клавіша Return"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Клавіша Settings"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Клавіша Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Клавіша Space"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Клавіша Symbols"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Клавіша Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Клавіша Voice Input"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Символи ввімкнено"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Символи вимкнено"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift увімкнено"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift вимкнено"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Поточний текст – %s."</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Текст не введено"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Код клавіші – %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Клавіша Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift увімкнено"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps Lock увімкнено"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Клавіша Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Символи"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Літери"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Цифри"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Налаштування"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Вкладка"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Пробіл"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Голос. ввід вимкнено"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Вибрати метод введення"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Мови вводу"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Переміст. палець на пробіл, щоб змін. мову"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Торкн. ще, щоб збер."</string>
<string name="has_dictionary" msgid="6071847973466625007">"Словник доступний"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Увімк. відгуки корист."</string>
<string name="prefs_description_log" msgid="5827825607258246003">"Допоможіть покращ. редактор методу введ., автомат. надсилаючи в Google статистику використ. та звіти про збої."</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"Торкн., щоб виправ. слова"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Торкніться введених слів, щоб виправити їх, лише коли ввімкнено пропозиції"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Тема клавіатури"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Тема клавіатури"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Чеська розкладка"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Розкладка для арабської мови"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Данська розкладка"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Німецька розкладка"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Німецька клавіатура QWERTY"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Англ. розкладка (Великобританія)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Англійська розкладка (США)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Іспанська розкладка"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Фінська розкладка"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Французька розкладка"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Французька розкладка (Канада)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Французька розкладка (Швейцарія)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Хорватська розкладка"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Угорська розкладка"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Розкладка для івриту"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Італійська розкладка"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Норвезька розкладка"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Голланд. розклад."</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Польська розкладка"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Португальська розкладка"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Російська розкладка"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Сербська розкладка"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Шведська розкладка"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Турецька розкладка"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Voice мовою африкаанс"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Голос чеською"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Голос німецькою"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Voice китайською, юеською мовою"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Voice китайською, мандарин. мовою"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Voice мовою ісізулу"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Режим вивчення зручності у використанні"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим вивчення зручності у використанні"</string>
</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 8dac2f922..a468f62f3 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -27,8 +27,18 @@
<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>
<string name="general_category" msgid="1859088467017573195">"Chung"</string>
- <string name="prediction_category" msgid="6361242011806282176">"Sửa văn bản"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Sửa văn bản"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"Đề xuất dựa trên các từ trước đó"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Tùy chọn khác"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Cài đặt nâng cao"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"Tùy chọn cho người dùng chuyên gia"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Hlại việc l.bỏ csổ b.lên chính"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Không có tgian trễ"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Mặc định"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Đề xuất tên liên hệ"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Sử dụng tên từ Danh bạ cho các đề xuất và chỉnh sửa"</string>
<string name="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"Cấu hình từ điển"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Sửa nhanh"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Sửa lỗi nhập thông thường"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Hiển thị gợi ý sửa"</string>
@@ -36,6 +46,7 @@
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Luôn hiển thị"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Hiển thị trên chế độ khổ đứng"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Luôn ẩn"</string>
+ <string name="prefs_use_spacebar_language_switch" msgid="8828538114550634449">"Sử dụng trình chuyển đổi ngôn ngữ thanh cách"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"Hiển thị phím cài đặt"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Tự động"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Luôn hiển thị"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Tắt"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Đơn giản"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Linh hoạt"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"Đề xuất Bigram"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"Rất linh hoạt"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"Đề xuất Bigram"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Sử dụng từ trước đó để cải tiến đề xuất"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"Dự đoán Bigram"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"Cũng sử dụng từ trước đó để dự đoán"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Đã lưu"</string>
<string name="label_go_key" msgid="1635148082137219148">"Đến"</string>
<string name="label_next_key" msgid="362972844525672568">"Tiếp theo"</string>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"Khác"</string>
<string name="label_pause_key" msgid="181098308428035340">"Tạm dừng"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Đợi"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"Xóa"</string>
- <string name="description_return_key" msgid="8750044000806461678">"Quay lại"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"Cài đặt"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"Dấu cách"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"Biểu tượng"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"Nhập liệu bằng giọng nói"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"Bật biểu tượng"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"Tắt biểu tượng"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Bật Shift"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Tắt Shift"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Ký tự hiện tại là %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Không có ký tự nào được nhập"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Mã phím %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Đã bật Shift"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Đã bật viết hoa"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Xóa"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Biểu tượng"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Chữ cái"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Số"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Cài đặt"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Dấu cách"</string>
+ <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>
@@ -86,7 +124,7 @@
<string name="voice_not_installed" msgid="5552450909753842415">"Tìm kiếm bằng giọng nói chưa được cài đặt"</string>
<string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Gợi ý:"</b>" Trượt qua bàn phím để nói"</string>
<string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Gợi ý:"</b>" Lần tới, thử nói dấu câu như \"dấu chấm\", \"dấu phẩy\" hoặc \"dấu hỏi\"."</string>
- <string name="cancel" msgid="6830980399865683324">"Huỷ"</string>
+ <string name="cancel" msgid="6830980399865683324">"Hủy"</string>
<string name="ok" msgid="7898366843681727667">"OK"</string>
<string name="voice_input" msgid="2466640768843347841">"Nhập liệu bằng giọng nói"</string>
<string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Trên bàn phím chính"</string>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"Nhập liệu bằng giọng nói đã bị vô hiệu hóa"</string>
<string name="selectInputMethod" msgid="315076553378705821">"Chọn phương thức nhập"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Ngôn ngữ nhập"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"Trượt ngón tay trên phím cách để thay đổi ngôn ngữ"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Chạm lại để lưu"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Có sẵn từ điển"</string>
<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="prefs_enable_recorrection" msgid="4588408906649533582">"Chạm để sửa từ"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Chạm các từ đã nhập để sửa, chỉ khi các đề xuất hiển thị"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"Chủ đề bàn phím"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Chủ đề bàn phím"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Bàn phím tiếng Séc"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"Bàn phím tiếng Ả Rập"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Bàn phím tiếng Đan Mạch"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Bàn phím tiếng Đức"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"Bàn phím QWERTY Tiếng Đức"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Bàn phím tiếng Anh (Anh)"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Bàn phím tiếng Anh (Mỹ)"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Bàn phím tiếng Tây Ban Nha"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"Bàn phím tiếng Phần Lan"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Bàn phím tiếng Pháp"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Bàn phím tiếng Pháp (Canada)"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Bàn phím tiếng Pháp (Thụy Sĩ)"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"Bàn phím tiếng Croatia"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"Bàn phím tiếng Hungari"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"Bàn phím tiếng Do Thái"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Bàn phím tiếng Ý"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Bàn phím tiếng Na Uy"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Bàn phím tiếng Hà Lan"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"Bàn phím tiếng Ba Lan"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"Bàn phím tiếng Bồ Đào Nha"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Bàn phím tiếng Nga"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Bàn phím tiếng Serbia"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Bàn phím tiếng Thụy Điển"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"Bàn phím tiếng Thổ Nhĩ Kỳ"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"Giọng tiếng Hà Lan ở Nam Phi"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Giọng nói tiếng Séc"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"Giọng nói tiếng Đức"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"Giọng tiếng Trung, Yue"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"Giọng tiếng Trung, tiếng Quan thoại"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"Giọng isiZulu"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"Chế độ nghiên cứu tính khả dụng"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Chế độ nghiên cứu tính khả dụng"</string>
</resources>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 9d7689153..fb9cc5a18 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"按键时播放音效"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"按键时显示弹出窗口"</string>
<string name="general_category" msgid="1859088467017573195">"常规"</string>
- <string name="prediction_category" msgid="6361242011806282176">"文本更正"</string>
+ <string name="correction_category" msgid="2236750915056607613">"文本更正"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"根据前面的字词提供建议"</string>
+ <string name="misc_category" msgid="6894192814868233453">"其他选项"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"高级设置"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"适合专家级用户的选项"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"关闭弹出式键盘的延迟"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"无延迟"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"默认"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"推荐联系人姓名"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用联系人中的姓名提供建议和更正"</string>
<string name="auto_cap" msgid="1719746674854628252">"自动大写"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"配置字典"</string>
<string name="quick_fixes" msgid="5353213327680897927">"快速纠正"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"纠正常见的输入错误"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"显示更正建议"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"使用空格键切换语言"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"显示设置键"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自动"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"始终显示"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"关闭"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"部分"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"全部"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"双连词建议"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"改动极大"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"双连词建议"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"使用以前的字词改进建议"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"双连词预测"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"结合前一个字词进行预测"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"更多"</string>
<string name="label_pause_key" msgid="181098308428035340">"暂停"</string>
<string name="label_wait_key" msgid="6402152600878093134">"等待"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"删除"</string>
- <string name="description_return_key" msgid="8750044000806461678">"回车"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"设置"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift"</string>
- <string name="description_space_key" msgid="8512130111575878517">"空格"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"符号"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"语音输入"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"符号模式已打开"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"符号模式已关闭"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"Shift 模式已打开"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"Shift 模式已关闭"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"当前文本为%s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"未输入文字"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"键码为 %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift 已启用"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"Caps lock 已启用"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"删除"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"符号"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"字母"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"数字"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"设置"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"空格"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"语音输入功能已停用"</string>
<string name="selectInputMethod" msgid="315076553378705821">"选择输入法"</string>
<string name="language_selection_title" msgid="1651299598555326750">"输入语言"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"在空格键上滑动手指可更改语言"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← 再次触摸即可保存"</string>
<string name="has_dictionary" msgid="6071847973466625007">"提供字典"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"启用用户反馈"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"自动向 Google 发送使用情况统计信息和崩溃报告,帮助改进该输入法编辑器。"</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"触摸以更正字词"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"仅在系统显示建议后,才触摸输入的字词进行更正"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"键盘主题"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"键盘主题"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"捷克语键盘"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"阿拉伯语键盘"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"丹麦语键盘"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"德语键盘"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"德语 QWERTY 键盘"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"英语(英国)键盘"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"英语(美国)键盘"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"西班牙语键盘"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"芬兰语键盘"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"法语键盘"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"法语(加拿大)键盘"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"法语(瑞士)键盘"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"克罗地亚语键盘"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"匈牙利语键盘"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"希伯来语键盘"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"意大利语键盘"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"挪威语键盘"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"荷兰语键盘"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"波兰语键盘"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"葡萄牙语键盘"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"俄语键盘"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"塞尔维亚语键盘"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"瑞典语键盘"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"土耳其语键盘"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"南非荷兰语语音"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"捷克语语音"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"德语语音"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"中文,粤语语音"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"中文,普通话语音"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"祖鲁语语音"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"可用性研究模式"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"可用性研究模式"</string>
</resources>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 9ba728461..95e8f8ac8 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -27,8 +27,18 @@
<string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"按鍵時顯示彈出式視窗"</string>
<string name="general_category" msgid="1859088467017573195">"一般設定"</string>
- <string name="prediction_category" msgid="6361242011806282176">"文字修正"</string>
+ <string name="correction_category" msgid="2236750915056607613">"文字修正"</string>
+ <string name="ngram_category" msgid="5337109164339320257">"根據先前字詞產生的建議"</string>
+ <string name="misc_category" msgid="6894192814868233453">"其他選項"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"進階設定"</string>
+ <string name="advanced_settings_summary" msgid="5193513161106637254">"提供給專業使用者的選項"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"關閉彈出式鍵盤的延遲時間"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"不延遲"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"預設"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人名稱"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用「聯絡人」的名稱提供建議與修正"</string>
<string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
+ <string name="configure_dictionaries_title" msgid="3758288002414557345">"設定字典"</string>
<string name="quick_fixes" msgid="5353213327680897927">"快速修正"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"修正一般打字錯誤"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"顯示修正建議"</string>
@@ -36,6 +46,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_use_spacebar_language_switch" msgid="8828538114550634449">"使用空白鍵切換語言"</string>
<string name="prefs_settings_key" msgid="4623341240804046498">"顯示設定金鑰"</string>
<string name="settings_key_mode_auto_name" msgid="2993460277873684680">"自動"</string>
<string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"一律顯示"</string>
@@ -45,8 +56,11 @@
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"關閉"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"部分"</string>
<string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"全部"</string>
- <string name="bigram_suggestion" msgid="1323347224043514969">"雙連詞建議"</string>
+ <string name="auto_correction_threshold_mode_very_aggeressive" msgid="3386782235540547678">"更正範圍極大"</string>
+ <string name="bigram_suggestion" msgid="2636414079905220518">"雙連詞建議"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"根據前一個字詞自動找出更適合的建議"</string>
+ <string name="bigram_prediction" msgid="8914273444762259739">"雙連詞預測"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"同樣使用先前的字詞進行預測"</string>
<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>
@@ -56,18 +70,42 @@
<string name="label_more_key" msgid="3760239494604948502">"更多"</string>
<string name="label_pause_key" msgid="181098308428035340">"暫停"</string>
<string name="label_wait_key" msgid="6402152600878093134">"等候"</string>
- <string name="description_delete_key" msgid="5586406298531883960">"刪除"</string>
- <string name="description_return_key" msgid="8750044000806461678">"返回"</string>
- <string name="description_settings_key" msgid="7484527796782969219">"設定"</string>
- <string name="description_shift_key" msgid="346906866277787836">"Shift 鍵"</string>
- <string name="description_space_key" msgid="8512130111575878517">"空白鍵"</string>
- <string name="description_switch_alpha_symbol_key" msgid="4537975384274405537">"符號"</string>
- <string name="description_tab_key" msgid="828186583738307137">"Tab 鍵"</string>
- <string name="description_voice_key" msgid="3057731675774652754">"語音輸入"</string>
- <string name="description_symbols_on" msgid="2994366855822840559">"開啟符號"</string>
- <string name="description_symbols_off" msgid="3209578267079515136">"關閉符號"</string>
- <string name="description_shift_on" msgid="6983188949895971587">"開啟位移"</string>
- <string name="description_shift_off" msgid="8553265474523069034">"關閉位移"</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"目前文字為 %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"未輸入文字"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"按鍵代碼 %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift 鍵"</string>
+ <string name="spoken_description_shift_shifted" msgid="954941524766465022">"Shift 鍵已啟用"</string>
+ <string name="spoken_description_caps_lock" msgid="5660626444912131764">"大寫鎖定已啟用"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"刪除"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"符號"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"字母"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"數字"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"設定"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab 鍵"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"空白鍵"</string>
+ <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>
@@ -97,29 +135,37 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"語音輸入已停用"</string>
<string name="selectInputMethod" msgid="315076553378705821">"選取輸入法"</string>
<string name="language_selection_title" msgid="1651299598555326750">"輸入語言"</string>
- <string name="language_selection_summary" msgid="187110938289512256">"以手指在空白鍵上滑動可變更語言"</string>
<string name="hint_add_to_dictionary" msgid="9006292060636342317">"← 再次輕觸即可儲存"</string>
<string name="has_dictionary" msgid="6071847973466625007">"可使用字典"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"啟用使用者意見回饋"</string>
<string name="prefs_description_log" msgid="5827825607258246003">"自動將使用統計資料和當機報告傳送給 Google,協助改善這個輸入法編輯器。"</string>
<string name="prefs_enable_recorrection" msgid="4588408906649533582">"輕觸此處可修正字詞"</string>
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"輕觸輸入的字詞即可加以修正 (出現建議時才適用)"</string>
- <string name="keyboard_layout" msgid="437433231038683666">"鍵盤主題"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string>
<string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"捷克文鍵盤"</string>
+ <string name="subtype_mode_ar_keyboard" msgid="2655338636329774995">"阿拉伯文鍵盤"</string>
<string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"丹麥文鍵盤"</string>
<string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"德文鍵盤"</string>
+ <string name="subtype_mode_de_qwerty_keyboard" msgid="54890770769303956">"德文 QWERTY 鍵盤"</string>
<string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"英文 (英國) 鍵盤"</string>
<string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"英文 (美國) 鍵盤"</string>
<string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"西班牙文鍵盤"</string>
+ <string name="subtype_mode_fi_keyboard" msgid="3198596464082614532">"芬蘭文鍵盤"</string>
<string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"法文鍵盤"</string>
<string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"法文 (加拿大) 鍵盤"</string>
<string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"法文 (瑞士) 鍵盤"</string>
+ <string name="subtype_mode_hr_keyboard" msgid="7177182405440070112">"克羅埃西亞文鍵盤"</string>
+ <string name="subtype_mode_hu_keyboard" msgid="8843338355732633647">"匈牙利文鍵盤"</string>
+ <string name="subtype_mode_iw_keyboard" msgid="1787536828253289950">"希伯來文鍵盤"</string>
<string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"義大利文鍵盤"</string>
<string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"挪威文鍵盤"</string>
<string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"荷蘭文鍵盤"</string>
+ <string name="subtype_mode_pl_keyboard" msgid="2225816414814396047">"波蘭文鍵盤"</string>
+ <string name="subtype_mode_pt_keyboard" msgid="7503997804861754840">"葡萄牙文鍵盤"</string>
<string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"俄文鍵盤"</string>
<string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"塞爾維亞文鍵盤"</string>
<string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"瑞典文語音"</string>
+ <string name="subtype_mode_tr_keyboard" msgid="3155981874829226370">"土耳其文鍵盤"</string>
<string name="subtype_mode_af_voice" msgid="7542487489657902699">"南非荷蘭文語音"</string>
<string name="subtype_mode_cs_voice" msgid="1136386688120958641">"捷克文語音"</string>
<string name="subtype_mode_de_voice" msgid="8378803143958089866">"德文語音"</string>
@@ -137,5 +183,5 @@
<string name="subtype_mode_yue_voice" msgid="1576887891614624263">"中文 (粵語) 語音"</string>
<string name="subtype_mode_zh_voice" msgid="4360533229467271152">"中文 (華語) 語音"</string>
<string name="subtype_mode_zu_voice" msgid="1146122571698884636">"祖魯文語音"</string>
- <string name="prefs_usability_study_mode" msgid="6937813623647419810">"使用習慣學習模式"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"使用性研究模式"</string>
</resources>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
new file mode 100644
index 000000000..f20a14eb1
--- /dev/null
+++ b/java/res/values-zu/strings.xml
@@ -0,0 +1,256 @@
+<?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.
+*/
+ -->
+
+<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="english_ime_settings" msgid="6661589557206947774">"Izilungiselelo zekhibhodi ye-Android"</string>
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Okukhethwa kukho kokungenayo"</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>
+ <!-- no translation found for general_category (1859088467017573195) -->
+ <skip />
+ <!-- no translation found for correction_category (2236750915056607613) -->
+ <skip />
+ <!-- no translation found for ngram_category (5337109164339320257) -->
+ <skip />
+ <!-- no translation found for misc_category (6894192814868233453) -->
+ <skip />
+ <!-- no translation found for advanced_settings (362895144495591463) -->
+ <skip />
+ <!-- no translation found for advanced_settings_summary (5193513161106637254) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_delay (6213164897443068248) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_no_delay (2096123151571458064) -->
+ <skip />
+ <!-- no translation found for key_preview_popup_dismiss_default_delay (2166964333903906734) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict (4435317977804180815) -->
+ <skip />
+ <!-- no translation found for use_contacts_dict_summary (6599983334507879959) -->
+ <skip />
+ <string name="auto_cap" msgid="1719746674854628252">"Ukwenza ofeleba okuzenzakalelayo"</string>
+ <!-- no translation found for configure_dictionaries_title (3758288002414557345) -->
+ <skip />
+ <string name="quick_fixes" msgid="5353213327680897927">"Ukulungisa okusheshayo"</string>
+ <string name="quick_fixes_summary" msgid="3405028402510332373">"Ilungisa amaphutha athayiphwa ngokuvamile"</string>
+ <!-- no translation found for prefs_show_suggestions (8026799663445531637) -->
+ <skip />
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Bonisa amagama aphakamisiwe ngenkathi uthayipha"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Bonisa njalo"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3551821800439659812">"Bonisa kwimodi emile"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Fihla njalo"</string>
+ <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) -->
+ <skip />
+ <string name="prefs_settings_key" msgid="4623341240804046498">"Bonisa ukhiye wezilungiselelo"</string>
+ <string name="settings_key_mode_auto_name" msgid="2993460277873684680">"Okuzenzakalelayo"</string>
+ <string name="settings_key_mode_always_show_name" msgid="3047567041784760575">"Bonisa njalo"</string>
+ <string name="settings_key_mode_always_hide_name" msgid="7833948046716923994">"Fihla njalo"</string>
+ <string name="auto_correction" msgid="4979925752001319458">"Ukulungisa okuzenzakalelayo"</string>
+ <!-- outdated translation 6881047311475758267 --> <string name="auto_correction_summary" msgid="5625751551134658006">"Ngokuzenzakalelayo ilungisa igama elandulele"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Valiwe"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Thobekile"</string>
+ <string name="auto_correction_threshold_mode_aggeressive" msgid="3524029103734923819">"Bukhali"</string>
+ <!-- no translation found for auto_correction_threshold_mode_very_aggeressive (3386782235540547678) -->
+ <skip />
+ <!-- outdated translation 1323347224043514969 --> <string name="bigram_suggestion" msgid="2636414079905220518">"Iziphakamiso ze-Biagram"</string>
+ <string name="bigram_suggestion_summary" msgid="4383845146070101531">"Sebenzisa igama elandulele ukuthuthukisa okusikiselwayo"</string>
+ <!-- no translation found for bigram_prediction (8914273444762259739) -->
+ <skip />
+ <!-- no translation found for bigram_prediction_summary (1747261921174300098) -->
+ <skip />
+ <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>
+ <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>
+ <string name="label_more_key" msgid="3760239494604948502">"Okungaphezulu"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Misa okwesikhashana"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Linda"</string>
+ <!-- no translation found for spoken_current_text_is (2485723011272583845) -->
+ <skip />
+ <!-- no translation found for spoken_no_text_entered (7479685225597344496) -->
+ <skip />
+ <!-- no translation found for spoken_description_unknown (3197434010402179157) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift (244197883292549308) -->
+ <skip />
+ <!-- no translation found for spoken_description_shift_shifted (954941524766465022) -->
+ <skip />
+ <!-- no translation found for spoken_description_caps_lock (5660626444912131764) -->
+ <skip />
+ <!-- no translation found for spoken_description_delete (8740376944276199801) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_symbol (5486340107500448969) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_alpha (23129338819771807) -->
+ <skip />
+ <!-- no translation found for spoken_description_to_numeric (591752092685161732) -->
+ <skip />
+ <!-- no translation found for spoken_description_settings (4627462689603838099) -->
+ <skip />
+ <!-- no translation found for spoken_description_tab (2667716002663482248) -->
+ <skip />
+ <!-- no translation found for spoken_description_space (2582521050049860859) -->
+ <skip />
+ <!-- no translation found for spoken_description_mic (615536748882611950) -->
+ <skip />
+ <!-- no translation found for spoken_description_smiley (2256309826200113918) -->
+ <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) -->
+ <skip />
+ <!-- no translation found for spoken_description_ellipsis (1687670869947652062) -->
+ <skip />
+ <!-- no translation found for spoken_description_low_double_quote (3551394572784840975) -->
+ <skip />
+ <string name="voice_warning_title" msgid="4419354150908395008">"Okungenayo kwezwi"</string>
+ <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Okungenayo kwezwi akusekelwa kolimi lwakho, kodwa kuyasebenza Ngesingisi."</string>
+ <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Okufakwayo kwezwi kusebenzisa ukuqaphela izwi le-Google. "<a href="http://m.google.com/privacy">"Inqubomgomo Yobumfihlo Yefoni"</a>" iyasebenza."</string>
+ <string name="voice_warning_how_to_turn_off" msgid="3190378129944934856">"Ukuvala okufakwayo kwezwi, iya kuzilungiselelo zendlela yokufakwayo"</string>
+ <string name="voice_hint_dialog_message" msgid="1420686286820661548">"Ukusebenzisa okufakwayo kwezwi, cindezela inkinobho yemakrofoni."</string>
+ <string name="voice_listening" msgid="467518160751321844">"Khuluma manje"</string>
+ <string name="voice_working" msgid="6666937792815731889">"Kuyasebenza"</string>
+ <string name="voice_initializing" msgid="661962047129906646"></string>
+ <string name="voice_error" msgid="5140896300312186162">"Iphutha. Sicela uzame futhi."</string>
+ <string name="voice_network_error" msgid="6649556447401862563">"Ayikwazanga ukuxhuma"</string>
+ <string name="voice_too_much_speech" msgid="5746973620134227376">"Iphutha, kunamagama amaningi."</string>
+ <string name="voice_audio_error" msgid="5072707727016414454">"Inkinga yomsindo"</string>
+ <string name="voice_server_error" msgid="7807129913977261644">"Iphutha leseva"</string>
+ <string name="voice_speech_timeout" msgid="8461817525075498795">"Awekho amagama azwakele"</string>
+ <string name="voice_no_match" msgid="4285117547030179174">"Akukho okufanayo okutholiwe"</string>
+ <string name="voice_not_installed" msgid="5552450909753842415">"Ukusesha ngezwi akufakiwe"</string>
+ <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Isexwayiso:"</b>"Shintshela kwikhibhodi ukuze ukhulume"</string>
+ <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Isixwayiso: "</b>"Esikhathini esilandelayo, zama ukukhuluma izimpimiselo ezinjengo \"isikhathi, \"ikhefu\" noma \"uphawu lombuzo\"."</string>
+ <string name="cancel" msgid="6830980399865683324">"Khansela"</string>
+ <string name="ok" msgid="7898366843681727667">"KULUNGILE"</string>
+ <string name="voice_input" msgid="2466640768843347841">"Okungenayo kwezwi"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Kwikhibhodi eyisisekelo"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Ikhibhodi yezimpawu"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"VALIWE"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"I-mic kwikhibhodi eyisisekelo"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Ikhibhodi yezimpawu ze-mic"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Okufakwayo kwezwi kuvimbelwe"</string>
+ <string name="selectInputMethod" msgid="315076553378705821">"Khetha indlela yokungenayo"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Izilimi zokufakwayo"</string>
+ <string name="hint_add_to_dictionary" msgid="9006292060636342317">"← Thinta futhi ukulondoloza"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Isichazamazwi siyatholakala"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Vumela impendulo yomsebenzisi"</string>
+ <string name="prefs_description_log" msgid="5827825607258246003">"Siza ukuthuthukisa umhleli wendlela yokungenayo ngokuthumela izibalo zokubala nokuphahlaza imibiko e-Google."</string>
+ <string name="prefs_enable_recorrection" msgid="4588408906649533582">"Thinta ukulungisa amagama"</string>
+ <string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Thinta amagama afakiwe ukuwalungisa, kuphela lapho okusikiselwayo kubonakala"</string>
+ <!-- outdated translation 437433231038683666 --> <string name="keyboard_layout" msgid="8451164783510487501">"Indikimba Yekhibhodi"</string>
+ <string name="subtype_mode_cs_keyboard" msgid="1141718931112377586">"Ikhibhodi yesi-Czech"</string>
+ <!-- no translation found for subtype_mode_ar_keyboard (2655338636329774995) -->
+ <skip />
+ <string name="subtype_mode_da_keyboard" msgid="1243570804427922104">"Ikhibhodi yesi-Danish"</string>
+ <string name="subtype_mode_de_keyboard" msgid="1990979135959462145">"Ikhobhodi yei-German"</string>
+ <!-- no translation found for subtype_mode_de_qwerty_keyboard (54890770769303956) -->
+ <skip />
+ <string name="subtype_mode_en_GB_keyboard" msgid="7945856548410373708">"Ikhibhodi ye-English (UK)"</string>
+ <string name="subtype_mode_en_US_keyboard" msgid="3708655163769735410">"Ikhobhodi ye-English (US)"</string>
+ <string name="subtype_mode_es_keyboard" msgid="1775125478866113148">"Ikhobhodi yesi-Spanish"</string>
+ <!-- no translation found for subtype_mode_fi_keyboard (3198596464082614532) -->
+ <skip />
+ <string name="subtype_mode_fr_keyboard" msgid="8016515336759761014">"Ikhibhodi yesi-French"</string>
+ <string name="subtype_mode_fr_CA_keyboard" msgid="2628517247158376263">"Ikhobhodi yesi-French (i-Canada)"</string>
+ <string name="subtype_mode_fr_CH_keyboard" msgid="6742806653181621228">"Ikhibhodi yesi-French (i-Switzerland"</string>
+ <!-- no translation found for subtype_mode_hr_keyboard (7177182405440070112) -->
+ <skip />
+ <!-- no translation found for subtype_mode_hu_keyboard (8843338355732633647) -->
+ <skip />
+ <!-- no translation found for subtype_mode_iw_keyboard (1787536828253289950) -->
+ <skip />
+ <string name="subtype_mode_it_keyboard" msgid="4934199655425394484">"Ikhibhodi yesi-Italian"</string>
+ <string name="subtype_mode_nb_keyboard" msgid="1175783216100212360">"Ikhibhodi yesi-Norwegian"</string>
+ <string name="subtype_mode_nl_keyboard" msgid="5090278083256037936">"Ikhibhodi yesi-Dutch"</string>
+ <!-- no translation found for subtype_mode_pl_keyboard (2225816414814396047) -->
+ <skip />
+ <!-- no translation found for subtype_mode_pt_keyboard (7503997804861754840) -->
+ <skip />
+ <string name="subtype_mode_ru_keyboard" msgid="1383995915064277943">"Ikhobhodi yesi-Russian"</string>
+ <string name="subtype_mode_sr_keyboard" msgid="5019440799612208168">"Ikhibhodi yesi-Serbian"</string>
+ <string name="subtype_mode_sv_keyboard" msgid="4933838139861753401">"Ikhobhodi yesi-Swedish"</string>
+ <!-- no translation found for subtype_mode_tr_keyboard (3155981874829226370) -->
+ <skip />
+ <!-- no translation found for subtype_mode_af_voice (7542487489657902699) -->
+ <skip />
+ <string name="subtype_mode_cs_voice" msgid="1136386688120958641">"Izwi le-Czech"</string>
+ <string name="subtype_mode_de_voice" msgid="8378803143958089866">"Izwi lesi-German"</string>
+ <!-- no translation found for subtype_mode_en_voice (6643420989651848728) -->
+ <skip />
+ <string name="subtype_mode_es_voice" msgid="1323473601346507487">"Izwi lesi-Spanish"</string>
+ <string name="subtype_mode_fr_voice" msgid="4675914209337824269">"Izwi lesi-French"</string>
+ <!-- no translation found for subtype_mode_it_voice (5077373057157441323) -->
+ <skip />
+ <string name="subtype_mode_ja_voice" msgid="6604859132669646367">"Izwi lesi-Japanese"</string>
+ <string name="subtype_mode_ko_voice" msgid="4890391190762324561">"Izwi lesi-Korean"</string>
+ <!-- no translation found for subtype_mode_nl_voice (2603552312869575021) -->
+ <skip />
+ <string name="subtype_mode_pl_voice" msgid="2076196021014840487">"Izwi lesi-Polish"</string>
+ <string name="subtype_mode_pt_voice" msgid="8036522712795994397">"Izwi lesi-Portuguese"</string>
+ <string name="subtype_mode_ru_voice" msgid="8034596947963787529">"Izwi lesi-Russian"</string>
+ <string name="subtype_mode_tr_voice" msgid="3402067436761140005">"Izwi lesi-Turkish"</string>
+ <!-- no translation found for subtype_mode_yue_voice (1576887891614624263) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zh_voice (4360533229467271152) -->
+ <skip />
+ <!-- no translation found for subtype_mode_zu_voice (1146122571698884636) -->
+ <skip />
+ <!-- outdated translation 6937813623647419810 --> <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Imodi Yesitadi Yokusebenziseka"</string>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index a015d6b71..fa5c08ba7 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -15,39 +15,79 @@
-->
<resources>
-
- <declare-styleable name="KeyboardView">
- <!-- Default KeyboardView style. -->
+ <declare-styleable name="KeyboardTheme">
+ <!-- Keyboard style -->
+ <attr name="keyboardStyle" format="reference" />
+ <!-- LatinKeyboard style -->
+ <attr name="latinKeyboardStyle" format="reference" />
+ <!-- KeyboardView style -->
<attr name="keyboardViewStyle" format="reference" />
+ <!-- PopupMiniKeyboardView style -->
+ <attr name="popupMiniKeyboardViewStyle" format="reference" />
+ <attr name="popupMiniKeyboardPanelStyle" format="reference" />
+ <!-- Suggestions strip style -->
+ <attr name="suggestionsStripBackgroundStyle" format="reference" />
+ <attr name="suggestionBackgroundStyle" format="reference" />
+ <attr name="suggestionPreviewBackgroundStyle" format="reference" />
+ <attr name="candidateViewStyle" format="reference" />
+ </declare-styleable>
+ <declare-styleable name="KeyboardView">
<!-- Image for the key. This image needs to be a StateListDrawable, with the following
possible states: normal, pressed, checkable, checkable+pressed, checkable+checked,
checkable+checked+pressed. -->
<attr name="keyBackground" format="reference" />
- <!-- Size of the text for one letter character keys. -->
- <attr name="keyLetterSize" format="dimension" />
-
- <!-- Size of the text for custom keys with some text and no icon. -->
- <attr name="labelTextSize" format="dimension" />
+ <!-- Size of the text for one letter keys, in the proportion of key height. -->
+ <attr name="keyLetterRatio" format="float" />
+ <!-- Large size of the text for one letter keys, in the proportion of key height. -->
+ <attr name="keyLargeLetterRatio" format="float" />
+ <!-- Size of the text for keys with some text, in the proportion of key height. -->
+ <attr name="keyLabelRatio" format="float" />
+ <!-- Size of the text for hint letter (= one character hint label), in the proportion of
+ key height. -->
+ <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" />
+ <!-- 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" />
+ <!-- Top and right padding of upper case letter to the edge of the key.-->
+ <attr name="keyUppercaseLetterPadding" format="dimension" />
<!-- Color to use for the label in a key. -->
<attr name="keyTextColor" format="color" />
-
- <!-- Color to use for the label in a key when in disabled state. -->
- <attr name="keyTextColorDisabled" format="color" />
+ <!-- Color to use for the label in a key when in inactivated state. -->
+ <attr name="keyTextInactivatedColor" format="color" />
+ <!-- Key hint letter (= one character hint label) color -->
+ <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" />
<!-- Layout resource for key press feedback.-->
<attr name="keyPreviewLayout" format="reference" />
-
+ <!-- The background for key press feedback. -->
+ <attr name="keyPreviewBackground" format="reference" />
+ <!-- The background for the left edge key press feedback. -->
+ <attr name="keyPreviewLeftBackground" format="reference" />
+ <!-- The background for the right edge key press feedback. -->
+ <attr name="keyPreviewRightBackground" format="reference" />
+ <!-- The background for spacebar press feedback. -->
+ <attr name="keyPreviewSpacebarBackground" format="reference" />
+ <!-- The text color for key press feedback. -->
+ <attr name="keyPreviewTextColor" format="color" />
<!-- Vertical offset of the key press feedback from the key. -->
<attr name="keyPreviewOffset" format="dimension" />
-
<!-- Height of the key press feedback popup. -->
<attr name="keyPreviewHeight" format="dimension" />
-
- <!-- Hysteresis distance for key debouncing -->
- <attr name="keyHysteresisDistance" format="dimension" />
+ <!-- Size of the text for key press feedback popup, int the proportion of key height -->
+ <attr name="keyPreviewTextRatio" format="float" />
<!-- Amount to offset the touch Y coordinate by, for bias correction. -->
<attr name="verticalCorrection" format="dimension" />
@@ -59,20 +99,25 @@
<attr name="shadowRadius" format="float" />
<attr name="backgroundDimAmount" format="float" />
- <attr name="keyLetterStyle">
+ <attr name="keyTextStyle" format="enum">
<!-- This should be aligned with Typeface.NORMAL etc. -->
<enum name="normal" value="0" />
<enum name="bold" value="1" />
<enum name="italic" value="2" />
<enum name="boldItalic" value="3" />
</attr>
+ </declare-styleable>
- <attr name="colorScheme">
- <!-- This should be aligned with KeyboardView.COLOR_SCHEME_* -->
- <enum name="white" value="0" />
- <enum name="black" value="1" />
+ <declare-styleable name="CandidateView">
+ <attr name="autoCorrectHighlight" format="integer">
+ <flag name="autoCorrectBold" value="0x01" />
+ <flag name="autoCorrectUnderline" value="0x02" />
+ <flag name="autoCorrectInvert" value="0x04" />
</attr>
-
+ <attr name="colorTypedWord" format="color" />
+ <attr name="colorAutoCorrect" format="color" />
+ <attr name="colorSuggested" format="color" />
+ <attr name="candidateCountInStrip" format="integer" />
</declare-styleable>
<declare-styleable name="Keyboard">
@@ -80,15 +125,24 @@
<attr name="keyboardHeight" format="dimension" />
<!-- Maximum keyboard height, in pixels or percentage of display height -->
<attr name="maxKeyboardHeight" format="dimension|fraction" />
- <!-- Default width of a key, in pixels or percentage of display width. -->
- <attr name="keyWidth" format="dimension|fraction" />
- <!-- Default height of a row (key height + vertical gap), in pixels or percentage of
- keyboard height.
+ <!-- Minimum keyboard height represented in pixels, percentage of display height if fraction
+ is positive, or percentage of display width if fraction is negative. -->
+ <attr name="minKeyboardHeight" format="dimension|fraction" />
+ <!-- Keyboard top and bottom paddings. -->
+ <attr name="keyboardTopPadding" format="dimension" />
+ <attr name="keyboardBottomPadding" format="dimension" />
+ <!-- Default width of a key, in pixels or percentage of display width.
If the value is zero, the actual key width will be determined to fill out the area up
to the right edge of the keyboard.
If the value is negative, 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.
-->
+ <attr name="keyWidth" format="dimension|fraction|enum">
+ <enum name="fillRight" value="0" />
+ <enum name="fillBoth" value="-1" />
+ </attr>
+ <!-- Default height of a row (key height + vertical gap), in pixels or percentage of
+ keyboard height. -->
<attr name="rowHeight" format="dimension|fraction" />
<!-- Default horizontal gap between keys. -->
<attr name="horizontalGap" format="dimension|fraction" />
@@ -96,6 +150,25 @@
<attr name="verticalGap" format="dimension|fraction" />
<!-- Popup keyboard layout template -->
<attr name="popupKeyboardTemplate" format="reference" />
+ <!-- Locale of the keyboard layout -->
+ <attr name="keyboardLocale" format="string" />
+ <!-- Icon set for key top and key preview. -->
+ <attr name="iconShiftKey" format="reference" />
+ <attr name="iconToSymbolKey" format="reference" />
+ <attr name="iconToSymbolKeyWithShortcut" format="reference" />
+ <attr name="iconDeleteKey" format="reference" />
+ <attr name="iconDeleteRtlKey" format="reference" />
+ <attr name="iconSettingsKey" format="reference" />
+ <attr name="iconShortcutKey" format="reference" />
+ <attr name="iconSpaceKey" format="reference" />
+ <attr name="iconReturnKey" format="reference" />
+ <attr name="iconSearchKey" format="reference" />
+ <attr name="iconTabKey" format="reference" />
+ <attr name="iconShiftedShiftKey" format="reference" />
+ <attr name="iconPreviewSpaceKey" format="reference" />
+ <attr name="iconPreviewTabKey" format="reference" />
+ <attr name="iconPreviewSettingsKey" format="reference" />
+ <attr name="iconPreviewShortcutKey" format="reference" />
</declare-styleable>
<declare-styleable name="Keyboard_Key">
@@ -106,47 +179,74 @@
<!-- Maximum column of popup keyboard -->
<attr name="maxPopupKeyboardColumn" format="integer" />
<!-- Key edge flags. -->
- <attr name="keyEdgeFlags">
+ <attr name="keyEdgeFlags" format="integer">
<!-- Key is anchored to the left of the keyboard. -->
<flag name="left" value="1" />
<!-- Key is anchored to the right of the keyboard. -->
<flag name="right" value="2" />
</attr>
- <!-- Whether this is a modifier key such as Alt or Shift. -->
- <attr name="isModifier" format="boolean" />
+ <!-- Whether this is a functional key which has different key top than normal key. -->
+ <attr name="isFunctional" format="boolean" />
<!-- Whether this is a toggle key. -->
<attr name="isSticky" format="boolean" />
<!-- Whether long-pressing on this key will make it repeat. -->
<attr name="isRepeatable" format="boolean" />
- <!-- The icon to show in the popup preview. -->
- <attr name="iconPreview" format="reference" />
<!-- 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 key label option -->
- <attr name="keyLabelOption">
- <!-- This should be aligned with KeyboardView.KEY_LABEL_OPTION_* -->
- <flag name="alignLeft" value="1" />
- <flag name="alignRight" value="2" />
- <flag name="alignBottom" value="8" />
- <flag name="fontNormal" value="16" />
+ <!-- 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_* -->
+ <flag name="alignLeft" value="0x01" />
+ <flag name="alignRight" value="0x02" />
+ <flag name="alignLeftOfCenter" value="0x08" />
+ <flag name="largeLetter" value="0x10" />
+ <flag name="fontNormal" value="0x20" />
+ <flag name="fontMonoSpace" value="0x40" />
+ <flag name="followKeyLetterRatio" value="0x80" />
+ <flag name="followKeyHintLabelRatio" value="0x100" />
+ <flag name="hasPopupHint" value="0x200" />
+ <flag name="hasUppercaseLetter" value="0x400" />
+ <flag name="hasHintLabel" value="0x800" />
</attr>
- <!-- The unicode that this key generates in manual temporary upper case mode. -->
- <attr name="manualTemporaryUpperCaseCode" format="integer" />
<!-- The icon to display on the key instead of the label. -->
- <attr name="keyIcon" format="reference" />
- <!-- The hint icon to display on the key in conjunction with the label -->
- <attr name="keyHintIcon" format="reference" />
- <!-- The hint icon to display on the key when keyboard is in manual temporary upper case
- mode. -->
- <attr name="manualTemporaryUpperCaseHintIcon" format="reference" />
+ <attr name="keyIcon" format="enum">
+ <!-- This should be aligned with KeyboardIcons.ICON_* -->
+ <enum name="iconShiftKey" value="1" />
+ <enum name="iconToSymbolKey" value="2" />
+ <enum name="iconToSymbolKeyWithShortcut" value="3" />
+ <enum name="iconDeleteKey" value="4" />
+ <enum name="iconDeleteRtlKey" value="5" />
+ <enum name="iconSettingsKey" value="6" />
+ <enum name="iconShortcutKey" value="7" />
+ <enum name="iconSpaceKey" value="8" />
+ <enum name="iconReturnKey" value="9" />
+ <enum name="iconSearchKey" value="10" />
+ <enum name="iconTabKey" 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="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="iconPreviewSpaceKey" value="13" />
+ <enum name="iconPreviewTabKey" value="14" />
+ <enum name="iconPreviewSettingsKey" value="15" />
+ <enum name="iconPreviewShortcutKey" value="16" />
+ </attr>
<!-- The key style to specify a set of key attributes defined by <key_style/> -->
<attr name="keyStyle" format="string" />
- <!-- Shift key icon for shifted state -->
- <attr name="shiftedIcon" format="reference" />
<!-- 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" />
<!-- The X-coordinate of upper right corner of this key including horizontal gap.
If the value is negative, the origin is the right edge of the keyboard. -->
<attr name="keyXPos" format="dimension|fraction" />
@@ -154,7 +254,7 @@
<declare-styleable name="Keyboard_Row">
<!-- Row edge flags. -->
- <attr name="rowEdgeFlags">
+ <attr name="rowEdgeFlags" format="integer">
<!-- Row is anchored to the top of the keyboard. -->
<flag name="top" value="4" />
<!-- Row is anchored to the bottom of the keyboard. -->
@@ -168,7 +268,7 @@
<declare-styleable name="Keyboard_Case">
<!-- This should be aligned with KeyboardId.MODE_* -->
- <attr name="mode">
+ <attr name="mode" format="enum|string">
<enum name="text" value="0" />
<enum name="url" value="1" />
<enum name="email" value="2" />
@@ -176,7 +276,7 @@
<enum name="phone" value="4" />
<enum name="number" value="5" />
</attr>
- <attr name="webInput" format="boolean" />
+ <attr name="navigateAction" format="boolean" />
<attr name="passwordInput" format="boolean" />
<attr name="hasSettingsKey" format="boolean" />
<!-- This should be aligned with KeyboardID.F2KEY_MODE_* -->
@@ -189,17 +289,18 @@
<attr name="clobberSettingsKey" format="boolean" />
<attr name="voiceKeyEnabled" format="boolean" />
<attr name="hasVoiceKey" format="boolean" />
- <attr name="imeAction">
+ <attr name="imeAction" format="enum">
<!-- This should be aligned with EditorInfo.IME_ACTION_* -->
- <flag name="actionUnspecified" value="0" />
- <flag name="actionNone" value="1" />
- <flag name="actionGo" value="2" />
- <flag name="actionSearch" value="3" />
- <flag name="actionSend" value="4" />
- <flag name="actionNext" value="5" />
- <flag name="actionDone" value="6" />
- <flag name="actionPrevious" value="7" />
+ <enum name="actionUnspecified" value="0" />
+ <enum name="actionNone" value="1" />
+ <enum name="actionGo" value="2" />
+ <enum name="actionSearch" value="3" />
+ <enum name="actionSend" value="4" />
+ <enum name="actionNext" value="5" />
+ <enum name="actionDone" value="6" />
+ <enum name="actionPrevious" value="7" />
</attr>
+ <attr name="localeCode" format="string" />
<attr name="languageCode" format="string" />
<attr name="countryCode" format="string" />
</declare-styleable>
@@ -208,4 +309,12 @@
<attr name="styleName" format="string" />
<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>
</resources>
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
deleted file mode 100644
index 741171f88..000000000
--- a/java/res/values/colors.xml
+++ /dev/null
@@ -1,31 +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.
-*/
--->
-<resources>
- <color name="candidate_normal">#FFFFFFFF</color>
- <color name="candidate_recommended">#FFFCAE00</color>
- <color name="candidate_other">#FFFCAE00</color>
- <color name="latinkeyboard_transparent">#00000000</color>
- <color name="latinkeyboard_bar_language_shadow_white">#80000000</color>
- <color name="latinkeyboard_bar_language_shadow_black">#80FFFFFF</color>
- <color name="latinkeyboard_bar_language_text">#FFC0C0C0</color>
- <color name="latinkeyboard_feedback_language_text">#FFFFFFFF</color>
- <color name="latinkeyboard_key_color_white">#FFFFFFFF</color>
- <color name="latinkeyboard_key_color_black">#FF000000</color>
-</resources>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 7c100c367..86eeae74a 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -19,37 +19,42 @@
-->
<resources>
- <bool name="config_swipeDisambiguation">true</bool>
<bool name="config_enable_show_settings_key_option">true</bool>
- <bool name="config_enable_show_subtype_settings">true</bool>
<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_show_recorrection_option">true</bool>
<bool name="config_enable_quick_fixes_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_candidate_highlight_font_color_enabled">true</bool>
- <bool name="config_swipe_down_dismiss_keyboard_enabled">true</bool>
<bool name="config_sliding_key_input_enabled">true</bool>
<bool name="config_digit_popup_characters_enabled">true</bool>
<!-- Whether or not Popup on key press is enabled by default -->
<bool name="config_default_popup_preview">true</bool>
<!-- Default values for whether quick fixes and bigram suggestions are activated -->
<bool name="config_default_quick_fixes">true</bool>
+ <!-- Default value for bigram suggestion: while showing candidates for a word should we weigh
+ in the previous word? -->
<bool name="config_default_bigram_suggestions">true</bool>
+ <!-- Default value for bigram prediction: after entering a word and a space only, should we look
+ at input history to suggest a hopefully helpful candidate for the next word? -->
+ <bool name="config_default_bigram_prediction">false</bool>
<bool name="config_default_recorrection_enabled">true</bool>
<bool name="config_default_sound_enabled">false</bool>
+ <bool name="config_auto_correction_spacebar_led_enabled">true</bool>
<bool name="config_use_spacebar_language_switcher">true</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">-1</integer>
+ <integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer>
+ <integer name="config_delay_update_suggestions">100</integer>
+ <integer name="config_delay_update_old_suggestions">300</integer>
+ <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">15</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">10</integer>
- <integer name="config_preview_fadein_anim_time">0</integer>
- <integer name="config_preview_fadeout_anim_time">70</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_keyboard_grid_width">32</integer>
@@ -60,7 +65,7 @@
<integer name="config_double_spaces_turn_into_period_timeout">1100</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">4</string>
+ <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_popup_keyboard_column">5</integer>
<string-array name="auto_correction_threshold_values" translatable="false">
@@ -69,8 +74,13 @@
<!-- Modest : Suggestion whose normalized score is greater than this value
will be subject to auto-correction. -->
<item>0.22</item>
- <!-- Aggressive : Suggestion whose normalized score is greater than this value
+ <!-- Aggressive -->
+ <item>0.08</item>
+ <!-- Very Aggressive : Suggestion whose normalized score is greater than this value
will be subject to auto-correction. -->
<item>0</item>
</string-array>
+ <!-- Screen metrics for logging. 0 = "mdpi", 1 = "hdpi", 2 = "xlarge" -->
+ <integer name="log_screen_metrics">0</integer>
+ <bool name="config_require_umlaut_processing">false</bool>
</resources>
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index d28b9232b..ff0458cfe 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -19,41 +19,74 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
- <dimen name="keyboardHeight">1.265in</dimen>
- <!-- key_height + key_bottom_gap = popup_key_height -->
- <!-- <dimen name="key_height">0.290in</dimen> -->
- <dimen name="key_bottom_gap">0.035in</dimen>
- <dimen name="key_horizontal_gap">0.000in</dimen>
- <dimen name="popup_key_height">0.325in</dimen>
- <dimen name="keyboard_top_padding">0.00in</dimen>
- <dimen name="keyboard_bottom_padding">0.06in</dimen>
- <!-- key_preview_text_size_large x 2 -->
- <dimen name="key_preview_height">80sp</dimen>
+ <!-- keyboardHeight = row_height*4 + key_bottom_gap*3 -->
+ <dimen name="keyboardHeight">1.285in</dimen>
+ <fraction name="maxKeyboardHeight">50%p</fraction>
+ <fraction name="minKeyboardHeight">-61.8%p</fraction>
+
+ <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="keyboard_horizontal_edges_padding">0dp</dimen>
+ <fraction name="keyboard_top_padding">1.556%p</fraction>
+ <fraction name="keyboard_bottom_padding">4.669%p</fraction>
+ <fraction name="key_bottom_gap">6.250%p</fraction>
+ <fraction name="key_horizontal_gap">1.352%p</fraction>
+
+ <dimen name="keyboardHeight_stone">1.317in</dimen>
+ <fraction name="keyboard_top_padding_stone">1.556%p</fraction>
+ <fraction name="keyboard_bottom_padding_stone">0.778%p</fraction>
+ <fraction name="key_bottom_gap_stone">7.506%p</fraction>
+ <fraction name="key_horizontal_gap_stone">1.739%p</fraction>
+
+ <fraction name="key_bottom_gap_gb">6.495%p</fraction>
+ <fraction name="key_horizontal_gap_gb">1.971%p</fraction>
+
+ <fraction name="keyboard_top_padding_ics">2.335%p</fraction>
+ <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">6dp</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.390in</dimen>
+ <dimen name="mini_keyboard_slide_allowance">0.396in</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="mini_keyboard_vertical_correction">-0.325in</dimen>
-
- <dimen name="key_letter_size">0.13in</dimen>
- <dimen name="key_label_text_size">0.083in</dimen>
- <dimen name="key_preview_text_size_large">40sp</dimen>
- <!-- left or right padding of label alignment -->
- <dimen name="key_label_horizontal_alignment_padding">0.13in</dimen>
- <dimen name="key_preview_offset">0.000in</dimen>
+ <dimen name="mini_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.05in</dimen>
- <dimen name="candidate_strip_height">42dip</dimen>
+ <fraction name="key_letter_ratio">55%</fraction>
+ <fraction name="key_large_letter_ratio">65%</fraction>
+ <fraction name="key_label_ratio">34%</fraction>
+ <fraction name="key_hint_letter_ratio">25%</fraction>
+ <fraction name="key_hint_label_ratio">44%</fraction>
+ <fraction name="key_uppercase_letter_ratio">35%</fraction>
+ <fraction name="key_preview_text_ratio">82%</fraction>
+ <dimen name="key_preview_height">80sp</dimen>
+ <dimen name="key_preview_offset">0.1in</dimen>
+
+ <dimen name="key_label_horizontal_padding">4dip</dimen>
+ <dimen name="key_hint_letter_padding">2dp</dimen>
+ <dimen name="key_uppercase_letter_padding">2dp</dimen>
+
+ <dimen name="key_preview_height_ics">80sp</dimen>
+ <dimen name="key_preview_offset_ics">0.05in</dimen>
+
+ <dimen name="candidate_strip_height">40dip</dimen>
+ <!-- candidate_strip_minimum_height =
+ key_preview_height_holo - key_preview_offset_holo + alpha -->
+ <dimen name="candidate_strip_minimum_height">100sp</dimen>
<dimen name="candidate_strip_fading_edge_length">63dip</dimen>
<dimen name="candidate_strip_padding">0dip</dimen>
- <dimen name="candidate_min_width">0.3in</dimen>
+ <dimen name="candidate_min_width">44dip</dimen>
<dimen name="candidate_padding">6dip</dimen>
<dimen name="candidate_text_size">18dip</dimen>
- <dimen name="spacebar_vertical_correction">4dip</dimen>
+ <integer name="candidate_count_in_strip">3</integer>
+
<!-- If the screen height in landscape is larger than the below value, then the keyboard
will not go into extract (fullscreen) mode. -->
<dimen name="max_height_for_fullscreen">2.5in</dimen>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 6a1069e99..f88d2df1c 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -18,12 +18,19 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Symbols that are commonly considered word separators in this language -->
- <string name="word_separators">.\u0009\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
- <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
- <string name="sentence_separators">.,!?)</string>
<!-- Symbols that are suggested between words -->
<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 -->
+ <string name="magic_space_stripping_symbols">\u0009\u0020\n/_\u0027-</string>
+ <!-- Symbols that should convert magic spaces into real space -->
+ <string name="magic_space_promoting_symbols">([*&amp;@{&lt;&gt;+=|</string>
+ <!-- Symbols that do NOT separate words -->
+ <string name="non_word_separator_symbols">\u0027-</string>
+ <!-- Word separator list is the union of all symbols except those that are not separators:
+ magic_space_swapping_symbols | magic_space_stripping_symbols |
+ magic_space_neutral_symbols \ non_word_separator_symbols -->
<!-- Label for ALT modifier key. Must be short to fit on key! -->
<string name="label_alt_key">ALT</string>
@@ -31,8 +38,17 @@
<string name="label_tab_key">Tab</string>
<!-- Label for "switch to symbols" key. Must be short to fit on key! -->
<string name="label_to_symbol_key">\?123</string>
- <!-- Label for "switch to numeric" key. Must be short to fit on key! -->
- <string name="label_to_numeric_key">123</string>
+ <!-- Label for "switch to phone numeric" key. Must be short to fit on key! -->
+ <string name="label_to_phone_numeric_key">123</string>
+ <!-- Label for "switch to phone symbols" key. Must be short to fit on key! -->
+ <string name="label_to_phone_symbols_key">\uff0a\uff03\uff08</string>
+
+ <!-- Character for candidate divider (BOX DRAWINGS LIGHT VERTICAL) -->
+ <string name="label_candidate_divider">\u2502</string>
+ <!-- Character for expand candidates pane (BLACK DOWN-POINTING TRIANGLE) -->
+ <string name="label_expand_candidates_pane">\u25bc</string>
+ <!-- Character for close candidates pane (BLACK UP-POINTING TRIANGLE) -->
+ <string name="label_close_candidates_pane">\u25b2</string>
<!-- Option values to show/hide the settings key in onscreen keyboard -->
<!-- Automatically decide to show or hide the settings key -->
@@ -77,15 +93,18 @@
<string name="auto_correction_threshold_mode_index_off">0</string>
<string name="auto_correction_threshold_mode_index_modest">1</string>
<string name="auto_correction_threshold_mode_index_aggeressive">2</string>
+ <string name="auto_correction_threshold_mode_index_very_aggeressive">3</string>
<string-array name="auto_correction_threshold_mode_indexes">
<item>@string/auto_correction_threshold_mode_index_off</item>
<item>@string/auto_correction_threshold_mode_index_modest</item>
<item>@string/auto_correction_threshold_mode_index_aggeressive</item>
+ <item>@string/auto_correction_threshold_mode_index_very_aggeressive</item>
</string-array>
<string-array name="auto_correction_threshold_modes">
<item>@string/auto_correction_threshold_mode_off</item>
<item>@string/auto_correction_threshold_mode_modest</item>
<item>@string/auto_correction_threshold_mode_aggeressive</item>
+ <item>@string/auto_correction_threshold_mode_very_aggeressive</item>
</string-array>
<string name="voice_mode_main">0</string>
@@ -119,7 +138,7 @@
<string name="layout_stone_bold">Stone (bold)</string>
<string name="layout_stone_normal">Stone (normal)</string>
<string name="layout_gingerbread">Gingerbread</string>
- <string name="layout_honeycomb">Honeycomb</string>
+ <string name="layout_ics">IceCreamSandwich</string>
<!-- For keyboard theme switcher dialog -->
<string-array name="keyboard_layout_modes">
@@ -128,7 +147,7 @@
<item>@string/layout_stone_normal</item>
<item>@string/layout_stone_bold</item>
<item>@string/layout_gingerbread</item>
- <item>@string/layout_honeycomb</item>
+ <item>@string/layout_ics</item>
</string-array>
<string-array name="keyboard_layout_modes_values">
<item>0</item>
@@ -143,9 +162,11 @@
<string-array name="subtype_locale_exception_keys">
<item>en_US</item>
<item>en_GB</item>
+ <item>de_ZZ</item>
</string-array>
<string-array name="subtype_locale_exception_values">
<item>English (US)</item>
<item>English (UK)</item>
+ <item>Deutsch (QWERTY)</item>
</string-array>
</resources>
diff --git a/java/res/values/keyboard-icons-black.xml b/java/res/values/keyboard-icons-black.xml
new file mode 100644
index 000000000..313bf02e1
--- /dev/null
+++ b/java/res/values/keyboard-icons-black.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <style name="KeyboardIcons.Black">
+ <!-- Keyboard icons -->
+ <!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are too
+ ambiguous.
+ sym_bkeyboard_voice_off
+ -->
+ <item name="iconShiftKey">@drawable/sym_bkeyboard_shift</item>
+ <item name="iconToSymbolKeyWithShortcut">@drawable/sym_bkeyboard_123_mic</item>
+ <item name="iconDeleteKey">@drawable/sym_bkeyboard_delete</item>
+ <!-- TODO: update this icon drawable -->
+ <item name="iconDeleteRtlKey">@drawable/sym_bkeyboard_delete_rtl</item>
+ <item name="iconSettingsKey">@drawable/sym_bkeyboard_settings</item>
+ <item name="iconShortcutKey">@drawable/sym_bkeyboard_mic</item>
+ <item name="iconSpaceKey">@drawable/sym_bkeyboard_space</item>
+ <item name="iconReturnKey">@drawable/sym_bkeyboard_return</item>
+ <item name="iconSearchKey">@drawable/sym_bkeyboard_search</item>
+ <item name="iconTabKey">@drawable/sym_bkeyboard_tab</item>
+ <item name="iconShiftedShiftKey">@drawable/sym_bkeyboard_shift_locked</item>
+ <item name="iconPreviewSpaceKey">@drawable/sym_keyboard_feedback_space</item>
+ <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
+ <item name="iconPreviewSettingsKey">@drawable/sym_keyboard_feedback_settings</item>
+ <item name="iconPreviewShortcutKey">@drawable/sym_keyboard_feedback_mic</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
new file mode 100644
index 000000000..a2bfd7a2f
--- /dev/null
+++ b/java/res/values/keyboard-icons-ics.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <style name="KeyboardIcons.IceCreamSandwich">
+ <!-- Keyboard icons -->
+ <!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are missing.
+ sym_keyboard_123_mic_holo
+ -->
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo</item>
+ <item name="iconToSymbolKeyWithShortcut">@drawable/sym_keyboard_123_mic_holo</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo</item>
+ <!-- TODO: update this icon drawable -->
+ <item name="iconDeleteRtlKey">@drawable/sym_keyboard_delete_rtl_holo</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo</item>
+ <item name="iconSpaceKey">@drawable/sym_keyboard_space_holo</item>
+ <item name="iconReturnKey">@drawable/sym_keyboard_return_holo</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab_holo</item>
+ <item name="iconShiftedShiftKey">@drawable/sym_keyboard_shift_locked_holo</item>
+ <item name="iconPreviewSpaceKey">@drawable/transparent</item>
+ <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
+ <item name="iconPreviewSettingsKey">@drawable/sym_keyboard_settings_holo</item>
+ <item name="iconPreviewShortcutKey">@drawable/sym_keyboard_feedback_mic</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
new file mode 100644
index 000000000..b6fa89026
--- /dev/null
+++ b/java/res/values/keyboard-icons-white.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <style name="KeyboardIcons">
+ <!-- Keyboard icons -->
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift</item>
+ <item name="iconToSymbolKeyWithShortcut">@drawable/sym_keyboard_123_mic</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete</item>
+ <!-- TODO: update this icon drawable -->
+ <item name="iconDeleteRtlKey">@drawable/sym_keyboard_delete_rtl</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_mic</item>
+ <item name="iconSpaceKey">@drawable/sym_keyboard_space</item>
+ <item name="iconReturnKey">@drawable/sym_keyboard_return</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab</item>
+ <item name="iconShiftedShiftKey">@drawable/sym_keyboard_shift_locked</item>
+ <item name="iconPreviewSpaceKey">@drawable/sym_keyboard_feedback_space</item>
+ <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
+ <item name="iconPreviewSettingsKey">@drawable/sym_keyboard_feedback_settings</item>
+ <item name="iconPreviewShortcutKey">@drawable/sym_keyboard_feedback_mic</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 d6f9bfc28..ee345291a 100644
--- a/java/res/values/keycodes.xml
+++ b/java/res/values/keycodes.xml
@@ -26,26 +26,6 @@
<integer name="key_shift">-1</integer>
<integer name="key_switch_alpha_symbol">-2</integer>
<integer name="key_delete">-5</integer>
- <integer name="key_settings">-100</integer>
- <integer name="key_voice">-102</integer>
-
- <!-- Array used for mapping key codes to description strings. -->
- <array name="key_descriptions">
- <item>@integer/key_tab</item>
- <item>@string/description_tab_key</item>
- <item>@integer/key_return</item>
- <item>@string/description_return_key</item>
- <item>@integer/key_space</item>
- <item>@string/description_space_key</item>
- <item>@integer/key_shift</item>
- <item>@string/description_shift_key</item>
- <item>@integer/key_switch_alpha_symbol</item>
- <item>@string/description_switch_alpha_symbol_key</item>
- <item>@integer/key_delete</item>
- <item>@string/description_delete_key</item>
- <item>@integer/key_settings</item>
- <item>@string/description_settings_key</item>
- <item>@integer/key_voice</item>
- <item>@string/description_voice_key</item>
- </array>
+ <integer name="key_settings">-6</integer>
+ <integer name="key_shortcut">-8</integer>
</resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index ac14a2082..739f72f36 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -38,11 +38,37 @@
<string name="general_category">General</string>
<!-- Category title for text prediction -->
- <string name="prediction_category">Text correction</string>
+ <string name="correction_category">Text correction</string>
+
+ <!-- Category title for ngrams -->
+ <string name="ngram_category">Suggestions based on previous words</string>
+
+ <!-- Category title for misc options -->
+ <string name="misc_category">Other options</string>
+
+ <!-- Option name for advanced settings screen [CHAR LIMIT=25] -->
+ <string name="advanced_settings">Advanced settings</string>
+ <!-- Option summary for advanced settings screen [CHAR LIMIT=65 (two lines) or 30 (fits on one line, preferable)] -->
+ <string name="advanced_settings_summary">Options for expert users</string>
+
+ <!-- Option for the dismiss delay of the key popup [CHAR LIMIT=25] -->
+ <string name="key_preview_popup_dismiss_delay">Key popup dismiss delay</string>
+ <!-- Description for delay for dismissing a popup on keypress: no delay [CHAR LIMIT=15] -->
+ <string name="key_preview_popup_dismiss_no_delay">No delay</string>
+ <!-- Description for delay for dismissing a popup on screen: default value of the delay [CHAR LIMIT=15] -->
+ <string name="key_preview_popup_dismiss_default_delay">Default</string>
+
+ <!-- Option name for enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=25] -->
+ <string name="use_contacts_dict">Suggest Contact names</string>
+ <!-- Description for option enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=65] -->
+ <string name="use_contacts_dict_summary">Use names from Contacts for suggestions and corrections</string>
<!-- Option to enable auto capitalization of sentences -->
<string name="auto_cap">Auto-capitalization</string>
+ <!-- Option to configure dictionaries -->
+ <string name="configure_dictionaries_title">Configure dictionaries</string>
+
<!-- Option to enable quick fixes -->
<string name="quick_fixes">Quick fixes</string>
<!-- Description for quick fixes -->
@@ -55,6 +81,8 @@
<string name="prefs_suggestion_visibility_show_name">Always show</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name">Show on portrait mode</string>
<string name="prefs_suggestion_visibility_hide_name">Always hide</string>
+ <!-- Option to enable spacebar language switcher [CHAR LIMIT=20]-->
+ <string name="prefs_use_spacebar_language_switch">Use the spacebar language switcher</string>
<!-- Option to show/hide the settings key -->
<string name="prefs_settings_key">Show settings key</string>
@@ -76,11 +104,17 @@
<string name="auto_correction_threshold_mode_modest">Modest</string>
<!-- Option to suggest auto correction candidates aggressively. Auto-corrects to a word which has even large edit distance from typed word. [CHAR LIMIT=20] -->
<string name="auto_correction_threshold_mode_aggeressive">Aggressive</string>
+ <!-- Option to suggest auto correction candidates very aggressively. Auto-corrects to a word which has even large edit distance from typed word. [CHAR LIMIT=20] -->
+ <string name="auto_correction_threshold_mode_very_aggeressive">Very aggressive</string>
<!-- Option to enable bigram correction -->
- <string name="bigram_suggestion">Bigram Suggestions</string>
+ <string name="bigram_suggestion">Bigram suggestions</string>
<!-- Description for auto correction -->
<string name="bigram_suggestion_summary">Use previous word to improve suggestion</string>
+ <!-- Option to enable using user-history bigram when no input -->
+ <string name="bigram_prediction">Bigram prediction</string>
+ <!-- Description for auto correction -->
+ <string name="bigram_prediction_summary">Use previous word also for prediction</string>
<!-- Indicates that a word has been added to the dictionary -->
<string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string>
@@ -102,30 +136,80 @@
<!-- Label for "Wait" key of phone number keyboard. Must be short to fit on key! [CHAR LIMIT=5]-->
<string name="label_wait_key">Wait</string>
- <!-- Spoken text description for delete key. -->
- <string name="description_delete_key">Delete</string>
- <!-- Spoken text description for return key. -->
- <string name="description_return_key">Return</string>
- <!-- Spoken text description for settings key. -->
- <string name="description_settings_key">Settings</string>
- <!-- Spoken text description for shift key. -->
- <string name="description_shift_key">Shift</string>
- <!-- Spoken text description for space key. -->
- <string name="description_space_key">Space</string>
- <!-- Spoken text description for symbols key. -->
- <string name="description_switch_alpha_symbol_key">Symbols</string>
- <!-- Spoken text description for tab key. -->
- <string name="description_tab_key">Tab</string>
- <!-- Spoken text description for voice input key. -->
- <string name="description_voice_key">Voice Input</string>
- <!-- Spoken text description for symbols mode on. -->
- <string name="description_symbols_on">Symbols on</string>
- <!-- Spoken text description for symbols mode off. -->
- <string name="description_symbols_off">Symbols off</string>
- <!-- Spoken text description for shift mode on. -->
- <string name="description_shift_on">Shift on</string>
- <!-- Spoken text description for shift mode off. -->
- <string name="description_shift_off">Shift off</string>
+ <!-- Spoken description for the currently entered text -->
+ <string name="spoken_current_text_is">Current text is "%s"</string>
+ <!-- Spoken description when there is no text entered -->
+ <string name="spoken_no_text_entered">No text entered</string>
+
+ <!-- Spoken description for unknown keyboard keys. -->
+ <string name="spoken_description_unknown">Key code %d</string>
+ <!-- Spoken description for the "Shift" keyboard key. -->
+ <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 "Delete" keyboard key. -->
+ <string name="spoken_description_delete">Delete</string>
+ <!-- Spoken description for the "To Symbol" keyboard key. -->
+ <string name="spoken_description_to_symbol">Symbols</string>
+ <!-- Spoken description for the "To Alpha" keyboard key. -->
+ <string name="spoken_description_to_alpha">Letters</string>
+ <!-- Spoken description for the "To Numbers" keyboard key. -->
+ <string name="spoken_description_to_numeric">Numbers</string>
+ <!-- Spoken description for the "Settings" keyboard key. -->
+ <string name="spoken_description_settings">Settings</string>
+ <!-- Spoken description for the "Tab" keyboard key. -->
+ <string name="spoken_description_tab">Tab</string>
+ <!-- Spoken description for the "Space" keyboard key. -->
+ <string name="spoken_description_space">Space</string>
+ <!-- Spoken description for the "Mic" keyboard key. -->
+ <string name="spoken_description_mic">Voice input</string>
+ <!-- Spoken description for the "Smiley" keyboard key. -->
+ <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>
<!-- Voice related labels -->
@@ -219,8 +303,9 @@
<!-- Title for input language selection screen -->
<string name="language_selection_title">Input languages</string>
- <!-- Title summary for input language selection screen -->
- <string name="language_selection_summary">Slide finger on spacebar to change language</string>
+
+ <!-- Preference for input language selection -->
+ <string name="select_language">Select input languages</string>
<!-- Add to dictionary hint -->
<string name="hint_add_to_dictionary">\u2190 Touch again to save</string>
@@ -238,38 +323,57 @@
<string name="prefs_enable_recorrection_summary">Touch entered words to correct them, only when suggestions are visible</string>
<!-- Title of the item to change the keyboard theme [CHAR LIMIT=20]-->
- <string name="keyboard_layout">Keyboard Theme</string>
+ <string name="keyboard_layout">Keyboard theme</string>
<!-- Description for Czech keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_cs_keyboard">Czech Keyboard</string>
+ <!-- Description for Arabic keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_ar_keyboard">Arabic Keyboard</string>
<!-- Description for Danish keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_da_keyboard">Danish Keyboard</string>
<!-- Description for German keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_de_keyboard">German Keyboard</string>
+ <!-- Description for German QWERTY keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_de_qwerty_keyboard">German QWERTY Keyboard</string>
<!-- Description for English (United Kingdom) keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_en_GB_keyboard">English (UK) Keyboard</string>
<!-- Description for English (United States) keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_en_US_keyboard">English (US) Keyboard</string>
<!-- Description for Spanish keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_es_keyboard">Spanish Keyboard</string>
+ <!-- Description for Finnish keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_fi_keyboard">Finnish Keyboard</string>
<!-- Description for French keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_fr_keyboard">French Keyboard</string>
<!-- Description for French (Canada) keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_fr_CA_keyboard">French (Canada) Keyboard</string>
<!-- Description for French (Switzerland) keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_fr_CH_keyboard">French (Switzerland) Keyboard</string>
+ <!-- Description for Croatian keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_hr_keyboard">Croatian Keyboard</string>
+ <!-- Description for Hungarian keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_hu_keyboard">Hungarian Keyboard</string>
+ <!-- Description for Hebrew keyboard subtype [CHAR LIMIT=35] -->
+ <!-- Java uses the deprecated "iw" code instead of the standard "he" code -->
+ <string name="subtype_mode_iw_keyboard">Hebrew Keyboard</string>
<!-- Description for Italian keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_it_keyboard">Italian Keyboard</string>
<!-- Description for Norwegian keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_nb_keyboard">Norwegian Keyboard</string>
<!-- Description for Dutch keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_nl_keyboard">Dutch Keyboard</string>
+ <!-- Description for Polish keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_pl_keyboard">Polish Keyboard</string>
+ <!-- Description for Portuguese keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_pt_keyboard">Portuguese Keyboard</string>
<!-- Description for Russian keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_ru_keyboard">Russian Keyboard</string>
<!-- Description for Serbian keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_sr_keyboard">Serbian Keyboard</string>
<!-- Description for Swedish keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_sv_keyboard">Swedish Keyboard</string>
+ <!-- Description for Turkish keyboard subtype [CHAR LIMIT=35] -->
+ <string name="subtype_mode_tr_keyboard">Turkish Keyboard</string>
<!-- Description for Afrikaans voice input subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_af_voice">Afrikaans Voice</string>
<!-- Description for Czech voice input subtype [CHAR LIMIT=35] -->
@@ -306,5 +410,5 @@
<string name="subtype_mode_zu_voice">isiZulu Voice</string>
<!-- Title of an option for usability study mode -->
- <string name="prefs_usability_study_mode">Usability Study Mode</string>
+ <string name="prefs_usability_study_mode">Usability study mode</string>
</resources>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 130714fd3..8ed334376 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -15,31 +15,187 @@
-->
<resources>
+ <!-- Theme "Basic" -->
+ <style name="Keyboard">
+ <item name="rowHeight">25%p</item>
+ <item name="keyboardHeight">@dimen/keyboardHeight</item>
+ <item name="maxKeyboardHeight">@fraction/maxKeyboardHeight</item>
+ <item name="minKeyboardHeight">@fraction/minKeyboardHeight</item>
+ <item name="popupKeyboardTemplate">@xml/kbd_popup_template</item>
+ <item name="keyboardTopPadding">@fraction/keyboard_top_padding</item>
+ <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding</item>
+ <item name="horizontalGap">@fraction/key_horizontal_gap</item>
+ <item name="verticalGap">@fraction/key_bottom_gap</item>
+ <item name="maxPopupKeyboardColumn">@integer/config_max_popup_keyboard_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>
- <item name="keyLetterSize">@dimen/key_letter_size</item>
- <item name="keyLetterStyle">normal</item>
+ <item name="keyLetterRatio">@fraction/key_letter_ratio</item>
+ <item name="keyLargeLetterRatio">@fraction/key_large_letter_ratio</item>
+ <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="keyTextStyle">normal</item>
<item name="keyTextColor">#FFFFFFFF</item>
- <item name="keyTextColorDisabled">#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="keyLabelHorizontalPadding">@dimen/key_label_horizontal_padding</item>
+ <item name="keyHintLetterPadding">@dimen/key_hint_letter_padding</item>
+ <item name="keyUppercaseLetterPadding">@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>
+ <item name="keyPreviewRightBackground">@null</item>
+ <item name="keyPreviewSpacebarBackground">@drawable/keyboard_key_feedback</item>
+ <item name="keyPreviewTextColor">#FFFFFFFF</item>
<item name="keyPreviewOffset">@dimen/key_preview_offset</item>
<item name="keyPreviewHeight">@dimen/key_preview_height</item>
- <item name="labelTextSize">@dimen/key_label_text_size</item>
+ <item name="keyPreviewTextRatio">@fraction/key_preview_text_ratio</item>
<item name="popupLayout">@layout/keyboard_popup</item>
- <item name="keyHysteresisDistance">@dimen/key_hysteresis_distance</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>
- <item name="colorScheme">white</item>
</style>
- <style name="KeyPreviewAnimation">
- <item name="android:windowEnterAnimation">@anim/key_preview_fadein</item>
- <item name="android:windowExitAnimation">@anim/key_preview_fadeout</item>
+ <style name="PopupMiniKeyboardView" parent="KeyboardView">
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup</item>
+ <item name="verticalCorrection">@dimen/mini_keyboard_vertical_correction</item>
+ </style>
+ <style name="PopupMiniKeyboardPanelStyle">
+ <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>
+ </style>
+ <style name="SuggestionsStripBackgroundStyle">
+ <item name="android:background">@drawable/keyboard_suggest_strip</item>
+ </style>
+ <style name="SuggestionBackgroundStyle">
+ <item name="android:background">@drawable/btn_candidate</item>
+ </style>
+ <style name="SuggestionPreviewBackgroundStyle">
+ <item name="android:background">@drawable/candidate_feedback_background</item>
+ </style>
+ <style name="CandidateViewStyle" parent="SuggestionsStripBackgroundStyle">
+ <item name="autoCorrectHighlight">autoCorrectBold</item>
+ <item name="colorTypedWord">#FFFFFFFF</item>
+ <item name="colorAutoCorrect">#FFFCAE00</item>
+ <item name="colorSuggested">#FFFCAE00</item>
+ <item name="candidateCountInStrip">@integer/candidate_count_in_strip</item>
+ </style>
+ <!-- Theme "Basic high contrast" -->
+ <style name="KeyboardView.HighContrast" parent="KeyboardView">
+ <item name="android:background">@android:color/black</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key3</item>
+ </style>
+ <!-- Theme "Stone" -->
+ <style name="Keyboard.Stone" parent="Keyboard">
+ <item name="keyboardHeight">@dimen/keyboardHeight_stone</item>
+ <item name="keyboardTopPadding">@fraction/keyboard_top_padding_stone</item>
+ <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_stone</item>
+ <item name="horizontalGap">@fraction/key_horizontal_gap_stone</item>
+ <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">
+ <item name="keyBackground">@drawable/btn_keyboard_key_stone</item>
+ <item name="keyTextColor">#FF000000</item>
+ <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="shadowColor">#FFFFFFFF</item>
+ </style>
+ <style name="PopupMiniKeyboardView.Stone" parent="PopupMiniKeyboardView">
+ <item name="keyBackground">@drawable/btn_keyboard_key_stone</item>
+ <item name="keyTextColor">#FF000000</item>
+ <item name="shadowColor">#FFFFFFFF</item>
+ </style>
+ <!-- Theme "Stone bold" -->
+ <style name="KeyboardView.Stone.Bold" parent="KeyboardView.Stone">
+ <item name="keyTextStyle">bold</item>
+ </style>
+ <!-- Theme "Gingerbread" -->
+ <style name="Keyboard.Gingerbread" parent="Keyboard">
+ <item name="horizontalGap">@fraction/key_horizontal_gap_gb</item>
+ <item name="verticalGap">@fraction/key_bottom_gap_gb</item>
+ </style>
+ <style name="KeyboardView.Gingerbread" parent="KeyboardView">
+ <item name="android:background">@drawable/keyboard_dark_background</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_gingerbread</item>
+ <item name="keyTextStyle">bold</item>
+ </style>
+ <style name="PopupMiniKeyboardView.Gingerbread" parent="PopupMiniKeyboardView">
+ <item name="android:background">@null</item>
+ </style>
+ <!-- Theme "IceCreamSandwich" -->
+ <style name="Keyboard.IceCreamSandwich" parent="Keyboard" >
+ <item name="keyboardTopPadding">@fraction/keyboard_top_padding_ics</item>
+ <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_ics</item>
+ <item name="horizontalGap">@fraction/key_horizontal_gap_ics</item>
+ <item name="verticalGap">@fraction/key_bottom_gap_ics</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">
+ <item name="android:background">@drawable/keyboard_background_holo</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
+ <item name="keyTextStyle">bold</item>
+ <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="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>
+ <item name="keyPreviewSpacebarBackground">@drawable/transparent</item>
+ <item name="keyPreviewTextColor">#FFFFFFFF</item>
+ <item name="keyPreviewHeight">@dimen/key_preview_height_ics</item>
+ <item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
+ <item name="shadowColor">#00000000</item>
+ <item name="shadowRadius">0.0</item>
+ </style>
+ <style name="PopupMiniKeyboardView.IceCreamSandwich" parent="PopupMiniKeyboardView">
+ <item name="android:background">@null</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
+ </style>
+ <style name="PopupMiniKeyboardPanelStyle.IceCreamSandwich">
+ <item name="android:background">@drawable/btn_keyboard_key_popup_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>
+ </style>
+ <style name="SuggestionsStripBackgroundStyle.IceCreamSandwich">
+ <item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
+ </style>
+ <style name="SuggestionBackgroundStyle.IceCreamSandwich">
+ <item name="android:background">@drawable/btn_candidate_ics</item>
+ </style>
+ <style name="SuggestionPreviewBackgroundStyle.IceCreamSandwich">
+ <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
+ </style>
+ <style name="CandidateViewStyle.IceCreamSandwich" parent="SuggestionsStripBackgroundStyle.IceCreamSandwich">
+ <item name="autoCorrectHighlight">autoCorrectBold|autoCorrectInvert</item>
+ <item name="colorTypedWord">#FFFFFFFF</item>
+ <item name="colorAutoCorrect">#FF3DC8FF</item>
+ <item name="colorSuggested">#FFFFFFFF</item>
+ <item name="candidateCountInStrip">@integer/candidate_count_in_strip</item>
</style>
- <style name="MiniKeyboardAnimation">
+ <style name="PopupMiniKeyboardAnimation">
<item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
<item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item>
</style>
diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml
new file mode 100644
index 000000000..820f96216
--- /dev/null
+++ b/java/res/values/themes-basic-highcontrast.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <style name="KeyboardTheme.HighContrast" parent="KeyboardIcons">
+ <item name="keyboardStyle">@style/Keyboard</item>
+ <item name="latinKeyboardStyle">@style/LatinKeyboard</item>
+ <item name="keyboardViewStyle">@style/KeyboardView.HighContrast</item>
+ <item name="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView</item>
+ <item name="popupMiniKeyboardPanelStyle">@style/PopupMiniKeyboardPanelStyle</item>
+ <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
+ <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
+ <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+ <item name="candidateViewStyle">@style/CandidateViewStyle</item>
+ </style>
+</resources>
diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml
new file mode 100644
index 000000000..18cae4e24
--- /dev/null
+++ b/java/res/values/themes-basic.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<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="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView</item>
+ <item name="popupMiniKeyboardPanelStyle">@style/PopupMiniKeyboardPanelStyle</item>
+ <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
+ <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
+ <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+ <item name="candidateViewStyle">@style/CandidateViewStyle</item>
+ </style>
+</resources>
diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml
new file mode 100644
index 000000000..60f226153
--- /dev/null
+++ b/java/res/values/themes-gingerbread.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<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="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView.Gingerbread</item>
+ <item name="popupMiniKeyboardPanelStyle">@style/PopupMiniKeyboardPanelStyle</item>
+ <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
+ <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
+ <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+ <item name="candidateViewStyle">@style/CandidateViewStyle</item>
+ </style>
+</resources>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
new file mode 100644
index 000000000..97c594408
--- /dev/null
+++ b/java/res/values/themes-ics.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<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="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView.IceCreamSandwich</item>
+ <item name="popupMiniKeyboardPanelStyle">@style/PopupMiniKeyboardPanelStyle.IceCreamSandwich</item>
+ <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle.IceCreamSandwich</item>
+ <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item>
+ <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle.IceCreamSandwich</item>
+ <item name="candidateViewStyle">@style/CandidateViewStyle.IceCreamSandwich</item>
+ </style>
+</resources>
diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml
new file mode 100644
index 000000000..d33e6bf35
--- /dev/null
+++ b/java/res/values/themes-stone-bold.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <style name="KeyboardTheme.Stone.Bold" parent="KeyboardIcons.Black">
+ <item name="keyboardStyle">@style/Keyboard.Stone</item>
+ <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item>
+ <item name="keyboardViewStyle">@style/KeyboardView.Stone.Bold</item>
+ <item name="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView.Stone</item>
+ <item name="popupMiniKeyboardPanelStyle">@style/PopupMiniKeyboardPanelStyle</item>
+ <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
+ <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
+ <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+ <item name="candidateViewStyle">@style/CandidateViewStyle</item>
+ </style>
+</resources>
diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml
new file mode 100644
index 000000000..230b2ca4d
--- /dev/null
+++ b/java/res/values/themes-stone.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<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="popupMiniKeyboardViewStyle">@style/PopupMiniKeyboardView.Stone</item>
+ <item name="popupMiniKeyboardPanelStyle">@style/PopupMiniKeyboardPanelStyle</item>
+ <item name="suggestionsStripBackgroundStyle">@style/SuggestionsStripBackgroundStyle</item>
+ <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
+ <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+ <item name="candidateViewStyle">@style/CandidateViewStyle</item>
+ </style>
+</resources>
diff --git a/java/res/values/whitelist.xml b/java/res/values/whitelist.xml
index ced52e70e..d4ecbfaa4 100644
--- a/java/res/values/whitelist.xml
+++ b/java/res/values/whitelist.xml
@@ -25,14 +25,5 @@
3. (String)after
-->
<string-array name="wordlist_whitelist">
-
- <item>255</item>
- <item>ill</item>
- <item>I\'ll</item>
-
- <item>255</item>
- <item>thisd</item>
- <item>this\'d</item>
-
</string-array>
</resources>
diff --git a/java/res/xml-sw600dp/kbd_qwerty.xml b/java/res/xml-ar/kbd_qwerty.xml
index 9541e13fd..57a6d2caf 100644
--- a/java/res/xml-sw600dp/kbd_qwerty.xml
+++ b/java/res/xml-ar/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="ar"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_arabic" />
</Keyboard>
diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml-cs/kbd_qwerty.xml
index 010bdb3f7..9991ea2d2 100644
--- a/java/res/xml-cs/kbd_qwerty.xml
+++ b/java/res/xml-cs/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="cs"
>
<include
- latin:keyboardLayout="@xml/kbd_qwertz_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_qwertz" />
</Keyboard>
diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-da/kbd_qwerty.xml
index 441b7cb17..37a50fdfd 100644
--- a/java/res/xml-da/kbd_qwerty.xml
+++ b/java/res/xml-da/kbd_qwerty.xml
@@ -20,14 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="da"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
+ latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
</Keyboard>
diff --git a/java/res/xml-de-rZZ/kbd_qwerty.xml b/java/res/xml-de-rZZ/kbd_qwerty.xml
new file mode 100644
index 000000000..d5fd8ef7a
--- /dev/null
+++ b/java/res/xml-de-rZZ/kbd_qwerty.xml
@@ -0,0 +1,27 @@
+<?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="de"
+>
+ <include
+ latin:keyboardLayout="@xml/kbd_rows_qwerty" />
+</Keyboard>
diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml
index a23e4fbf0..89e10b26d 100644
--- a/java/res/xml-de/kbd_qwerty.xml
+++ b/java/res/xml-de/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="de"
>
<include
- latin:keyboardLayout="@xml/kbd_qwertz_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_qwertz" />
</Keyboard>
diff --git a/java/res/xml-es/kbd_qwerty.xml b/java/res/xml-es/kbd_qwerty.xml
new file mode 100644
index 000000000..568f4d652
--- /dev/null
+++ b/java/res/xml-es/kbd_qwerty.xml
@@ -0,0 +1,27 @@
+<?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-fi/kbd_qwerty.xml b/java/res/xml-fi/kbd_qwerty.xml
index b0a7b3eb0..75721e057 100644
--- a/java/res/xml-fi/kbd_qwerty.xml
+++ b/java/res/xml-fi/kbd_qwerty.xml
@@ -20,14 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="fi"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
+ latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
</Keyboard>
diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml
index 92d92f0e6..7bdfbadf1 100644
--- a/java/res/xml-fr-rCA/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCA/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="fr_CA"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_qwerty" />
</Keyboard>
diff --git a/java/res/xml-fr-rCH/kbd_qwerty.xml b/java/res/xml-fr-rCH/kbd_qwerty.xml
index a23e4fbf0..41b701d83 100644
--- a/java/res/xml-fr-rCH/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCH/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="fr_CH"
>
<include
- latin:keyboardLayout="@xml/kbd_qwertz_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_qwertz" />
</Keyboard>
diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml-fr/kbd_qwerty.xml
index 2d0b42baf..8c730a24f 100644
--- a/java/res/xml-fr/kbd_qwerty.xml
+++ b/java/res/xml-fr/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="fr"
>
<include
- latin:keyboardLayout="@xml/kbd_azerty_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_azerty" />
</Keyboard>
diff --git a/java/res/xml-hr/kbd_qwerty.xml b/java/res/xml-hr/kbd_qwerty.xml
new file mode 100644
index 000000000..ca92e86a7
--- /dev/null
+++ b/java/res/xml-hr/kbd_qwerty.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:keyboardLocale="hr"
+>
+ <!-- TODO: Dedicated Croatian layout especially for tablet. -->
+ <include
+ latin:keyboardLayout="@xml/kbd_rows_qwertz" />
+</Keyboard>
diff --git a/java/res/xml-hu/kbd_qwerty.xml b/java/res/xml-hu/kbd_qwerty.xml
index 010bdb3f7..3195d5b1f 100644
--- a/java/res/xml-hu/kbd_qwerty.xml
+++ b/java/res/xml-hu/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="hu"
>
<include
- latin:keyboardLayout="@xml/kbd_qwertz_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_qwertz" />
</Keyboard>
diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml
index 6c2504e65..dc2c5d35a 100644
--- a/java/res/xml-iw/kbd_qwerty.xml
+++ b/java/res/xml-iw/kbd_qwerty.xml
@@ -1,112 +1,27 @@
<?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
+** 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
+** 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
+** 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:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="iw"
>
<include
- latin:keyboardLayout="@xml/kbd_key_styles" />
- <Row
- latin:rowEdgeFlags="top"
- >
- <Spacer
- latin:keyWidth="5%p" />
- <Key
- latin:keyLabel="ק"
- latin:keyEdgeFlags="left" />
- <Key
- latin:keyLabel="ר" />
- <Key
- latin:keyLabel="א" />
- <Key
- latin:keyLabel="ט" />
- <Key
- latin:keyLabel="ו" />
- <Key
- latin:keyLabel="ן" />
- <Key
- latin:keyLabel="ם" />
- <Key
- latin:keyLabel="פ" />
- <Spacer
- latin:keyWidth="1.25%p" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="13.75%p"
- latin:keyEdgeFlags="right" />
- </Row>
- <Row>
- <Key
- latin:keyLabel="ש"
- latin:keyEdgeFlags="left" />
- <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:keyEdgeFlags="right" />
- </Row>
- <Row>
- <Spacer
- latin:keyWidth="5%p" />
- <Key
- latin:keyLabel="ז"
- latin:keyEdgeFlags="left" />
- <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:keyEdgeFlags="right" />
- </Row>
- <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+ latin:keyboardLayout="@xml/kbd_rows_hebrew" />
</Keyboard>
diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml
index 441b7cb17..1f4e86e89 100644
--- a/java/res/xml-nb/kbd_qwerty.xml
+++ b/java/res/xml-nb/kbd_qwerty.xml
@@ -20,14 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="nb"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
+ latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
</Keyboard>
diff --git a/java/res/xml-pl/kbd_qwerty.xml b/java/res/xml-pl/kbd_qwerty.xml
new file mode 100644
index 000000000..44312c52c
--- /dev/null
+++ b/java/res/xml-pl/kbd_qwerty.xml
@@ -0,0 +1,27 @@
+<?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="pl"
+>
+ <include
+ latin:keyboardLayout="@xml/kbd_rows_qwerty" />
+</Keyboard>
diff --git a/java/res/xml-pt/kbd_qwerty.xml b/java/res/xml-pt/kbd_qwerty.xml
new file mode 100644
index 000000000..f5dcbc61b
--- /dev/null
+++ b/java/res/xml-pt/kbd_qwerty.xml
@@ -0,0 +1,27 @@
+<?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-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml
index 0eb311501..aee1b1bfc 100644
--- a/java/res/xml-ru/kbd_qwerty.xml
+++ b/java/res/xml-ru/kbd_qwerty.xml
@@ -20,14 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="ru"
>
<include
- latin:keyboardLayout="@xml/kbd_ru_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_russian" />
</Keyboard>
diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml
index 3995e4e27..58fc187c2 100644
--- a/java/res/xml-sr/kbd_qwerty.xml
+++ b/java/res/xml-sr/kbd_qwerty.xml
@@ -20,14 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="sr"
>
<include
- latin:keyboardLayout="@xml/kbd_sr_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_serbian" />
</Keyboard>
diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml
index 72bdc339e..e29d9abce 100644
--- a/java/res/xml-sv/kbd_qwerty.xml
+++ b/java/res/xml-sv/kbd_qwerty.xml
@@ -20,14 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="sv"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows_scandinavia" />
+ latin:keyboardLayout="@xml/kbd_rows_scandinavian" />
</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/kbd_key_styles.xml
index 082c374e8..dbea4dcfd 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/kbd_key_styles.xml
@@ -22,21 +22,9 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- Base key style for the functional key -->
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="functionalKeyStyle"
- latin:isModifier="true" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="functionalKeyStyle" />
- </case>
- </switch>
+ <key-style
+ latin:styleName="functionalKeyStyle"
+ latin:isFunctional="true" />
<!-- Base key style for the key which may have settings key as popup key -->
<switch>
<case
@@ -49,123 +37,62 @@
<default>
<key-style
latin:styleName="settingsPopupStyle"
- latin:keyHintIcon="@drawable/hint_popup_holo"
- latin:popupCharacters="\@drawable/sym_keyboard_settings_holo|\@integer/key_settings"
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="\@icon/5|\@integer/key_settings"
latin:parentStyle="functionalKeyStyle" />
</default>
</switch>
<!-- Functional key styles -->
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="@drawable/sym_keyboard_shift_holo"
- latin:shiftedIcon="@drawable/sym_keyboard_shift_locked_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_shift"
- latin:parentStyle="functionalKeyStyle"
- latin:isSticky="true" />
- <key-style
- latin:styleName="deleteKeyStyle"
- latin:code="@integer/key_delete"
- latin:keyIcon="@drawable/sym_keyboard_delete_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_delete"
- latin:parentStyle="functionalKeyStyle"
- latin:isRepeatable="true" />
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_keyboard_return_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_return"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyHintIcon="@drawable/hint_popup_holo"
- latin:popupCharacters="@string/alternates_for_smiley"
- latin:maxPopupKeyboardColumn="5" />
- <key-style
- latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
- latin:keyIcon="@drawable/sym_keyboard_voice_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:parentStyle="settingsPopupStyle" />
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="@drawable/sym_keyboard_settings_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="@drawable/sym_bkeyboard_shift"
- latin:shiftedIcon="@drawable/sym_bkeyboard_shift_locked"
- latin:iconPreview="@drawable/sym_keyboard_feedback_shift"
- latin:parentStyle="functionalKeyStyle"
- latin:isSticky="true" />
- <key-style
- latin:styleName="deleteKeyStyle"
- latin:code="@integer/key_delete"
- latin:keyIcon="@drawable/sym_bkeyboard_delete"
- latin:iconPreview="@drawable/sym_keyboard_feedback_delete"
- latin:parentStyle="functionalKeyStyle"
- latin:isRepeatable="true" />
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_bkeyboard_return"
- latin:iconPreview="@drawable/sym_keyboard_feedback_return"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyHintIcon="@drawable/hint_popup_holo"
- latin:popupCharacters="@string/alternates_for_smiley"
- latin:maxPopupKeyboardColumn="5" />
- <key-style
- latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
- latin:keyIcon="@drawable/sym_bkeyboard_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:parentStyle="settingsPopupStyle" />
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="@drawable/sym_bkeyboard_settings"
- latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- </switch>
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKey"
+ latin:keyIconShifted="iconShiftedShiftKey"
+ latin:parentStyle="functionalKeyStyle"
+ latin:isSticky="true" />
+ <key-style
+ latin:styleName="deleteKeyStyle"
+ latin:code="@integer/key_delete"
+ latin:keyIcon="iconDeleteKey"
+ latin:parentStyle="functionalKeyStyle"
+ latin:isRepeatable="true" />
+ <key-style
+ latin:styleName="returnKeyStyle"
+ latin:code="@integer/key_return"
+ latin:keyIcon="iconReturnKey"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="spaceKeyStyle"
+ latin:code="@integer/key_space"
+ latin:keyIconPreview="iconPreviewSpaceKey" />
+ <key-style
+ latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
+ latin:code="@integer/key_space"
+ latin:keyIconPreview="iconPreviewSpaceKey" />
+ <key-style
+ latin:styleName="smileyKeyStyle"
+ latin:keyLabel=":-)"
+ latin:keyOutputText=":-) "
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_smiley"
+ latin:maxPopupKeyboardColumn="5" />
+ <key-style
+ latin:styleName="shortcutKeyStyle"
+ latin:code="@integer/key_shortcut"
+ latin:keyIcon="iconShortcutKey"
+ latin:keyIconPreview="iconPreviewShortcutKey"
+ latin:parentStyle="settingsPopupStyle" />
+ <key-style
+ latin:styleName="settingsKeyStyle"
+ latin:code="@integer/key_settings"
+ latin:keyIcon="iconSettingsKey"
+ latin:keyIconPreview="iconPreviewSettingsKey"
+ latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="tabKeyStyle"
latin:code="@integer/key_tab"
- latin:keyIcon="@drawable/sym_keyboard_tab_holo"
- latin:iconPreview="@drawable/sym_keyboard_tab_holo"
+ latin:keyIcon="iconTabKey"
+ latin:keyIconPreview="iconPreviewTabKey"
latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="toSymbolKeyStyle"
@@ -189,9 +116,8 @@
<key-style
latin:styleName="comKeyStyle"
latin:keyLabel="@string/keylabel_for_popular_domain"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelOption="fontNormal|hasPopupHint"
latin:keyOutputText="@string/keylabel_for_popular_domain"
- latin:keyHintIcon="@drawable/hint_popup_holo"
latin:popupCharacters="@string/alternates_for_popular_domain" />
<switch>
<case
diff --git a/java/res/xml-sw600dp/kbd_number.xml b/java/res/xml-sw600dp/kbd_number.xml
index f0972b39c..b3a1010d7 100644
--- a/java/res/xml-sw600dp/kbd_number.xml
+++ b/java/res/xml-sw600dp/kbd_number.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="16.75%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -48,8 +41,8 @@
latin:keyStyle="num3KeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.0%p"
- latin:keyWidth="0%p"
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -62,8 +55,8 @@
latin:keyStyle="num6KeyStyle" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-11.0%p"
- latin:keyWidth="0%p"
+ latin:keyXPos="-11.00%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -79,7 +72,7 @@
<Row>
<Key
latin:keyStyle="tabKeyStyle"
- latin:keyWidth="11.0%p"
+ latin:keyWidth="11.00%p"
latin:keyEdgeFlags="left" />
<Spacer
latin:keyXPos="24.875%p" />
@@ -87,7 +80,7 @@
latin:keyStyle="num0KeyStyle" />
<Spacer
latin:keyXPos="-11.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
@@ -98,49 +91,60 @@
<Row>
<Key
latin:keyLabel="-"
- latin:keyXPos="11.0%p"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="11.00%p"
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:keyLabel="2"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="3" />
+ latin:keyLabel="3"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="-11.00%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
- latin:keyLabel="*"
- latin:keyXPos="11.0%p"
+ latin:keyStyle="numStarKeyStyle"
+ latin:keyXPos="11.00%p"
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:keyLabel="5"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="6" />
+ latin:keyLabel="6"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="-11.00%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -149,21 +153,27 @@
edge key. -->
<Key
latin:keyLabel="("
- latin:keyXPos="11.0%p"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="11.00%p"
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:keyLabel="8"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="9" />
+ latin:keyLabel="9"
+ latin:keyStyle="numKeyStyle" />
</Row>
<!-- This row is intentionally not marked as a bottom row -->
<Row>
@@ -175,15 +185,17 @@
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
latin:keyWidth="27.75%p" />
<Key
- latin:keyLabel="*"
+ latin:keyStyle="numStarKeyStyle"
latin:keyXPos="38.75%p" />
<Key
- latin:keyLabel="0" />
+ latin:keyLabel="0"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="#" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<Spacer
latin:keyXPos="-11.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/kbd_numkey_styles.xml b/java/res/xml-sw600dp/kbd_numkey_styles.xml
deleted file mode 100644
index b10dc9333..000000000
--- a/java/res/xml-sw600dp/kbd_numkey_styles.xml
+++ /dev/null
@@ -1,150 +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:colorScheme="white"
- >
- <key-style
- latin:styleName="num0KeyStyle"
- latin:code="48"
- latin:keyIcon="@drawable/sym_keyboard_num0_holo" />
- <key-style
- latin:styleName="num1KeyStyle"
- latin:code="49"
- latin:keyIcon="@drawable/sym_keyboard_num1_holo" />
- <key-style
- latin:styleName="num2KeyStyle"
- latin:code="50"
- latin:keyIcon="@drawable/sym_keyboard_num2_holo" />
- <key-style
- latin:styleName="num3KeyStyle"
- latin:code="51"
- latin:keyIcon="@drawable/sym_keyboard_num3_holo" />
- <key-style
- latin:styleName="num4KeyStyle"
- latin:code="52"
- latin:keyIcon="@drawable/sym_keyboard_num4_holo" />
- <key-style
- latin:styleName="num5KeyStyle"
- latin:code="53"
- latin:keyIcon="@drawable/sym_keyboard_num5_holo" />
- <key-style
- latin:styleName="num6KeyStyle"
- latin:code="54"
- latin:keyIcon="@drawable/sym_keyboard_num6_holo" />
- <key-style
- latin:styleName="num7KeyStyle"
- latin:code="55"
- latin:keyIcon="@drawable/sym_keyboard_num7_holo" />
- <key-style
- latin:styleName="num8KeyStyle"
- latin:code="56"
- latin:keyIcon="@drawable/sym_keyboard_num8_holo" />
- <key-style
- latin:styleName="num9KeyStyle"
- latin:code="57"
- latin:keyIcon="@drawable/sym_keyboard_num9_holo" />
- <key-style
- latin:styleName="numStarKeyStyle"
- latin:code="42"
- latin:keyIcon="@drawable/sym_keyboard_numbstar_holo" />
- <key-style
- latin:styleName="numPoundKeyStyle"
- latin:code="35"
- latin:keyIcon="@drawable/sym_keyboard_numbpound_holo" />
- <key-style
- latin:styleName="numAltKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_keyboard_numalt"
- latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" />
- <key-style
- latin:styleName="numSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:keyIcon="@drawable/sym_keyboard_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="num0KeyStyle"
- latin:code="48"
- latin:keyIcon="@drawable/sym_bkeyboard_num0" />
- <key-style
- latin:styleName="num1KeyStyle"
- latin:code="49"
- latin:keyIcon="@drawable/sym_bkeyboard_num1" />
- <key-style
- latin:styleName="num2KeyStyle"
- latin:code="50"
- latin:keyIcon="@drawable/sym_bkeyboard_num2" />
- <key-style
- latin:styleName="num3KeyStyle"
- latin:code="51"
- latin:keyIcon="@drawable/sym_bkeyboard_num3" />
- <key-style
- latin:styleName="num4KeyStyle"
- latin:code="52"
- latin:keyIcon="@drawable/sym_bkeyboard_num4" />
- <key-style
- latin:styleName="num5KeyStyle"
- latin:code="53"
- latin:keyIcon="@drawable/sym_bkeyboard_num5" />
- <key-style
- latin:styleName="num6KeyStyle"
- latin:code="54"
- latin:keyIcon="@drawable/sym_bkeyboard_num6" />
- <key-style
- latin:styleName="num7KeyStyle"
- latin:code="55"
- latin:keyIcon="@drawable/sym_bkeyboard_num7" />
- <key-style
- latin:styleName="num8KeyStyle"
- latin:code="56"
- latin:keyIcon="@drawable/sym_bkeyboard_num8" />
- <key-style
- latin:styleName="num9KeyStyle"
- latin:code="57"
- latin:keyIcon="@drawable/sym_bkeyboard_num9" />
- <key-style
- latin:styleName="numStarKeyStyle"
- latin:code="42"
- latin:keyIcon="@drawable/sym_bkeyboard_numstar" />
- <key-style
- latin:styleName="numPoundKeyStyle"
- latin:code="35"
- latin:keyIcon="@drawable/sym_bkeyboard_numpound" />
- <key-style
- latin:styleName="numAltKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_bkeyboard_numalt"
- latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" />
- <key-style
- latin:styleName="numSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:keyIcon="@drawable/sym_bkeyboard_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- </case>
- </switch>
-</merge>
diff --git a/java/res/xml-sw600dp/kbd_phone.xml b/java/res/xml-sw600dp/kbd_phone.xml
index 220c4b882..dd53a206a 100644
--- a/java/res/xml-sw600dp/kbd_phone.xml
+++ b/java/res/xml-sw600dp/kbd_phone.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="16.75%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -36,13 +29,13 @@
<!-- This row is intentionally not marked as a top row -->
<Row>
<Key
- latin:code="45"
- latin:keyLabel=" - "
+ latin:keyLabel="-"
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="15.625%p"
latin:keyWidth="9.25%p" />
<Key
- latin:code="43"
- latin:keyLabel=" + "
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num1KeyStyle"
@@ -54,18 +47,18 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="-11.00%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
- latin:code="44"
- latin:keyLabel=" , "
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="15.625%p"
latin:keyWidth="9.25%p" />
<Key
- latin:code="46"
- latin:keyLabel=" . "
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num4KeyStyle"
@@ -77,24 +70,24 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="-11.00%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
latin:keyStyle="moreKeyStyle"
- latin:keyWidth="11.00%p"
+ latin:keyWidth="11.0%p"
latin:keyEdgeFlags="left" />
<!-- There is an empty area below the "More" key and left of the "(" key. To ignore
the touch event on the area, "(" is intentionally not marked as a left edge key. -->
<Key
- latin:code="40"
- latin:keyLabel=" ( "
+ latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="15.625%p"
latin:keyWidth="9.25%p" />
<Key
- latin:code="41"
- latin:keyLabel=" ) "
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num7KeyStyle"
@@ -120,10 +113,11 @@
<Key
latin:keyStyle="num0KeyStyle" />
<Key
- latin:keyStyle="numPoundKeyStyle" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<Spacer
latin:keyXPos="-11.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/kbd_phone_symbols.xml b/java/res/xml-sw600dp/kbd_phone_symbols.xml
index 43c4f6d7f..d083ecb60 100644
--- a/java/res/xml-sw600dp/kbd_phone_symbols.xml
+++ b/java/res/xml-sw600dp/kbd_phone_symbols.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="16.75%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -36,13 +29,13 @@
<!-- This row is intentionally not marked as a top row -->
<Row>
<Key
- latin:code="45"
- latin:keyLabel=" - "
- latin:keyXPos="11.0%p"
+ latin:keyLabel="-"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="11.00%p"
latin:keyWidth="9.25%p" />
<Key
- latin:code="43"
- latin:keyLabel=" + "
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:code="44"
@@ -58,18 +51,18 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="-11.00%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
- latin:code="44"
- latin:keyLabel=" , "
- latin:keyXPos="11.0%p"
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="11.00%p"
latin:keyWidth="9.25%p" />
<Key
- latin:code="46"
- latin:keyLabel=" . "
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:code="59"
@@ -85,7 +78,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.00%p"
- latin:keyWidth="-11.00%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -96,16 +89,16 @@
<!-- There is an empty area below the "More" key and left of the "(" key. To ignore
the touch event on the area, "(" is intentionally not marked as a left edge key. -->
<Key
- latin:code="40"
- latin:keyLabel=" ( "
+ latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
- latin:code="41"
- latin:keyLabel=" ) "
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
- latin:code="78"
- latin:keyLabel=" N "
+ latin:keyLabel="N"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="9.25%p" />
<Key
latin:keyStyle="num7KeyStyle"
@@ -130,10 +123,11 @@
<Key
latin:keyStyle="num0KeyStyle" />
<Key
- latin:keyStyle="numPoundKeyStyle" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<Spacer
latin:keyXPos="-11.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/kbd_popup_template.xml b/java/res/xml-sw600dp/kbd_popup_template.xml
index fff2659be..d97649965 100644
--- a/java/res/xml-sw600dp/kbd_popup_template.xml
+++ b/java/res/xml-sw600dp/kbd_popup_template.xml
@@ -20,7 +20,7 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="8%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
+ latin:horizontalGap="@fraction/key_horizontal_gap"
latin:verticalGap="0px"
latin:rowHeight="@dimen/popup_key_height"
>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_f2.xml b/java/res/xml-sw600dp/kbd_qwerty_f2.xml
index e6c57f8f7..7638ee4b4 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_f2.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_f2.xml
@@ -27,7 +27,7 @@
>
<Key
latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</case>
<case
@@ -38,8 +38,8 @@
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</case>
<!-- voiceKeyEnabled="false" -->
@@ -56,15 +56,15 @@
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</case>
<!-- voiceKeyEnabled="false" -->
<default>
<Key
latin:keyStyle="settingsKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</default>
</switch>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row1.xml b/java/res/xml-sw600dp/kbd_qwerty_row1.xml
index 1a6ed9728..b781d681e 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row1.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row1.xml
@@ -59,7 +59,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row2.xml b/java/res/xml-sw600dp/kbd_qwerty_row2.xml
index 1e6011cde..05b005af1 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row2.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row2.xml
@@ -53,7 +53,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row3.xml b/java/res/xml-sw600dp/kbd_qwerty_row3.xml
index 4118ee197..278db13fc 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row3.xml
@@ -58,15 +58,13 @@
<default>
<Key
latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="!"
latin:popupCharacters="!" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
latin:popupCharacters="\?" />
</default>
</switch>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row4.xml b/java/res/xml-sw600dp/kbd_qwerty_row4.xml
index 6378ea414..4f41c17b4 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row4.xml
@@ -48,9 +48,8 @@
<default>
<Key
latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="64"
- latin:keyHintIcon="@drawable/key_hint_at_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_at_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\@"
latin:popupCharacters="\@" />
</default>
</switch>
@@ -75,18 +74,16 @@
>
<Key
latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="58"
- latin:keyHintIcon="@drawable/key_hint_colon_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_colon_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel=":"
latin:popupCharacters=":"
latin:keyWidth="9.750%p" />
</case>
<default>
<Key
latin:keyLabel="\?"
- latin:manualTemporaryUpperCaseCode="95"
- latin:keyHintIcon="@drawable/key_hint_underline_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_underline_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="_"
latin:popupCharacters="_"
latin:keyWidth="9.750%p" />
</default>
@@ -102,9 +99,8 @@
<default>
<Key
latin:keyLabel="!"
- latin:manualTemporaryUpperCaseCode="39"
- latin:keyHintIcon="@drawable/key_hint_quote_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_quote_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\'"
latin:popupCharacters="\'"
latin:keyWidth="9.750%p" />
</default>
@@ -125,18 +121,16 @@
>
<Key
latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="58"
- latin:keyHintIcon="@drawable/key_hint_colon_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_colon_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel=":"
latin:popupCharacters=":"
latin:keyWidth="9.750%p" />
</case>
<default>
<Key
latin:keyLabel="\'"
- latin:manualTemporaryUpperCaseCode="34"
- latin:keyHintIcon="@drawable/key_hint_quote_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_quote_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="&quot;"
latin:popupCharacters="&quot;"
latin:keyWidth="9.750%p" />
</default>
@@ -152,9 +146,8 @@
<default>
<Key
latin:keyLabel="-"
- latin:manualTemporaryUpperCaseCode="95"
- latin:keyHintIcon="@drawable/key_hint_underline_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_underline_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="_"
latin:popupCharacters="_"
latin:keyWidth="9.750%p" />
</default>
@@ -163,7 +156,7 @@
</switch>
<Spacer
latin:keyXPos="-10.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/kbd_row3_right.xml b/java/res/xml-sw600dp/kbd_row3_right.xml
index 7867e175a..5e9584f2d 100644
--- a/java/res/xml-sw600dp/kbd_row3_right.xml
+++ b/java/res/xml-sw600dp/kbd_row3_right.xml
@@ -28,7 +28,7 @@
<Key
latin:keyLabel="\@"
latin:keyXPos="-8.9%p"
- latin:keyWidth="-8.9%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</case>
<case
@@ -36,12 +36,11 @@
>
<Key
latin:keyLabel="-"
- latin:manualTemporaryUpperCaseCode="95"
- latin:keyHintIcon="@drawable/key_hint_underline_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_underline_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="_"
latin:popupCharacters="_"
latin:keyXPos="-8.9%p"
- latin:keyWidth="-8.9%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</case>
<case
@@ -49,19 +48,18 @@
>
<Key
latin:keyLabel=":"
- latin:manualTemporaryUpperCaseCode="43"
- latin:keyHintIcon="@drawable/key_hint_plus_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_plus_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="+"
latin:popupCharacters="+"
latin:keyXPos="-8.9%p"
- latin:keyWidth="-8.9%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</case>
<default>
<Key
latin:keyStyle="smileyKeyStyle"
latin:keyXPos="-8.9%p"
- latin:keyWidth="-8.9%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</default>
</switch>
diff --git a/java/res/xml-sw600dp/kbd_rows_arabic.xml b/java/res/xml-sw600dp/kbd_rows_arabic.xml
new file mode 100644
index 000000000..bc37d5a9f
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_rows_arabic.xml
@@ -0,0 +1,134 @@
+<?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.
+*/
+-->
+
+<!-- This file for Arabic layout is an alpha version. It allows to enter -->
+<!-- some right-to-left text, but it has gone through no study whatsoever, -->
+<!-- and needs to be run through UX. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/kbd_key_styles" />
+ <Row
+ latin:keyWidth="8.0%p"
+ >
+ <Key
+ latin:keyLabel="ض"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ص" />
+ <Key
+ latin:keyLabel="ث" />
+ <Key
+ latin:keyLabel="ق" />
+ <Key
+ latin:keyLabel="ف"
+ latin:popupCharacters="ف,ڤ" />
+ <Key
+ latin:keyLabel="غ" />
+ <Key
+ latin:keyLabel="ع" />
+ <Key
+ latin:keyLabel="ه"
+ latin:popupCharacters="ه,هـ" />
+ <Key
+ latin:keyLabel="خ" />
+ <Key
+ latin:keyLabel="ح" />
+ <Key
+ latin:keyLabel="ج"
+ latin:popupCharacters="ج,چ" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-10.0%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.0%p"
+ >
+ <Key
+ latin:keyLabel="ش"
+ latin:keyXPos="3.0%p" />
+ <Key
+ latin:keyLabel="س" />
+ <Key
+ latin:keyLabel="ي" />
+ <Key
+ latin:keyLabel="ب"
+ latin:popupCharacters="ب,پ" />
+ <Key
+ latin:keyLabel="ل"
+ latin:popupCharacters="ل,لا" />
+ <Key
+ latin:keyLabel="ا"
+ latin:popupCharacters="ا,أ,إ,آ" />
+ <Key
+ latin:keyLabel="ت" />
+ <Key
+ latin:keyLabel="ن" />
+ <Key
+ latin:keyLabel="م" />
+ <Key
+ latin:keyLabel="ك"
+ latin:popupCharacters="ك,گ" />
+ <Key
+ latin:keyLabel="ط" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyXPos="-14.6%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="7.65%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="8.0%p"
+ latin:keyEdgeFlags="left" />
+ <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:popupCharacters="ز,ژ" />
+ <Key
+ latin:keyLabel="ظ" />
+ <Key
+ latin:keyLabel="د" />
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_azerty_rows.xml b/java/res/xml-sw600dp/kbd_rows_azerty.xml
index e3a835387..7ba716bc5 100644
--- a/java/res/xml-sw600dp/kbd_azerty_rows.xml
+++ b/java/res/xml-sw600dp/kbd_rows_azerty.xml
@@ -24,7 +24,7 @@
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
<Row
- latin:keyWidth="9.0%p"
+ latin:keyWidth="8.5%p"
latin:rowEdgeFlags="top"
>
<Key
@@ -61,15 +61,16 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="9.0%p"
+ latin:keyWidth="8.5%p"
>
<Key
latin:keyLabel="q"
latin:popupCharacters="@string/alternates_for_q"
+ latin:keyXPos="5.0%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="s"
@@ -97,11 +98,11 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="8.9%p"
+ latin:keyWidth="8.5%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
@@ -137,21 +138,19 @@
<default>
<Key
latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="!"
latin:popupCharacters="!" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
latin:popupCharacters="\?" />
</default>
</switch>
<include
latin:keyboardLayout="@xml/kbd_row3_right" />
- </Row>
+ </Row>
<include
latin:keyboardLayout="@xml/kbd_qwerty_row4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_rows_hebrew.xml b/java/res/xml-sw600dp/kbd_rows_hebrew.xml
new file mode 100644
index 000000000..a1475376b
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_rows_hebrew.xml
@@ -0,0 +1,122 @@
+<?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" />
+ <Row
+ latin:keyWidth="8.600%p"
+ latin:rowEdgeFlags="top"
+ >
+ <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="deleteKeyStyle"
+ latin:keyXPos="-12.000%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.600%p"
+ >
+ <Key
+ latin:keyLabel="ש"
+ latin:keyXPos="4.000%p" />
+ <Key
+ latin:keyLabel="ד" />
+ <Key
+ latin:keyLabel="ג"
+ latin:popupCharacters="ג,ג׳" />
+ <Key
+ latin:keyLabel="כ" />
+ <Key
+ latin:keyLabel="ע" />
+ <Key
+ latin:keyLabel="י"
+ latin:popupCharacters="י,ײַ" />
+ <Key
+ latin:keyLabel="ח"
+ latin:popupCharacters="ח,ח׳" />
+ <Key
+ latin:keyLabel="ל" />
+ <Key
+ latin:keyLabel="ך" />
+ <Key
+ latin:keyLabel="ף" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyXPos="-10.400%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.600%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.000%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ז"
+ latin:popupCharacters="ז,ז׳" />
+ <Key
+ latin:keyLabel="ס" />
+ <Key
+ latin:keyLabel="ב" />
+ <Key
+ latin:keyLabel="ה" />
+ <Key
+ latin:keyLabel="נ" />
+ <Key
+ latin:keyLabel="מ" />
+ <Key
+ latin:keyLabel="צ"
+ latin:popupCharacters="צ,צ׳" />
+ <Key
+ latin:keyLabel="ת"
+ latin:popupCharacters="ת,ת׳" />
+ <Key
+ latin:keyLabel="ץ"
+ latin:popupCharacters="ץ,ץ׳" />
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_rows.xml b/java/res/xml-sw600dp/kbd_rows_qwerty.xml
index a2d26b3de..a2d26b3de 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_rows.xml
+++ b/java/res/xml-sw600dp/kbd_rows_qwerty.xml
diff --git a/java/res/xml-sw600dp/kbd_qwertz_rows.xml b/java/res/xml-sw600dp/kbd_rows_qwertz.xml
index 5c2fbf2b9..7f85fe778 100644
--- a/java/res/xml-sw600dp/kbd_qwertz_rows.xml
+++ b/java/res/xml-sw600dp/kbd_rows_qwertz.xml
@@ -61,7 +61,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<include
@@ -103,15 +103,13 @@
<default>
<Key
latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="!"
latin:popupCharacters="!" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
latin:popupCharacters="\?" />
</default>
</switch>
diff --git a/java/res/xml-sw600dp/kbd_ru_rows.xml b/java/res/xml-sw600dp/kbd_rows_russian.xml
index fb820ccc1..b72324745 100644
--- a/java/res/xml-sw600dp/kbd_ru_rows.xml
+++ b/java/res/xml-sw600dp/kbd_rows_russian.xml
@@ -55,7 +55,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -87,7 +87,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -118,9 +118,8 @@
latin:keyLabel="ю" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="44"
- latin:keyHintIcon="@drawable/key_hint_comma_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_comma_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel=","
latin:popupCharacters="," />
<include
latin:keyboardLayout="@xml/kbd_row3_right" />
diff --git a/java/res/xml-sw600dp/kbd_qwerty_rows_scandinavia.xml b/java/res/xml-sw600dp/kbd_rows_scandinavian.xml
index 59e86c5c8..645ef625a 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_rows_scandinavia.xml
+++ b/java/res/xml-sw600dp/kbd_rows_scandinavian.xml
@@ -24,13 +24,12 @@
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
<Row
- latin:keyWidth="8.0%p"
+ latin:keyWidth="7.9%p"
latin:rowEdgeFlags="top"
>
<Key
latin:keyLabel="q"
latin:popupCharacters="@string/alternates_for_q"
- latin:keyXPos="2.15%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="w"
@@ -64,14 +63,15 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="8.0%p"
+ latin:keyWidth="7.9%p"
>
<Key
latin:keyLabel="a"
+ latin:keyXPos="3.5%p"
latin:popupCharacters="@string/alternates_for_a"
latin:keyEdgeFlags="left" />
<Key
@@ -104,11 +104,63 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
- <include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ <Row
+ latin:keyWidth="7.9%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.0%p"
+ latin:keyEdgeFlags="left" />
+ <Spacer
+ latin:keyWidth="4.35%p" />
+ <Key
+ latin:keyLabel="z"
+ latin:popupCharacters="@string/alternates_for_z" />
+ <Key
+ latin:keyLabel="x" />
+ <Key
+ latin:keyLabel="c"
+ latin:popupCharacters="@string/alternates_for_c" />
+ <Key
+ latin:keyLabel="v"
+ latin:popupCharacters="@string/alternates_for_v" />
+ <Key
+ latin:keyLabel="b" />
+ <Key
+ latin:keyLabel="n"
+ latin:popupCharacters="@string/alternates_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:popupCharacters="!" />
+ <Key
+ latin:keyLabel="."
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
+ latin:popupCharacters="\?" />
+ </default>
+ </switch>
+ <Spacer
+ latin:keyWidth="4.35%p" />
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right" />
+ </Row>
<include
latin:keyboardLayout="@xml/kbd_qwerty_row4" />
</merge>
diff --git a/java/res/xml-sw600dp/kbd_sr_rows.xml b/java/res/xml-sw600dp/kbd_rows_serbian.xml
index 09dc2b719..4dfe94400 100644
--- a/java/res/xml-sw600dp/kbd_sr_rows.xml
+++ b/java/res/xml-sw600dp/kbd_rows_serbian.xml
@@ -54,7 +54,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -86,7 +86,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -126,15 +126,13 @@
<default>
<Key
latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="!"
latin:popupCharacters="!" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
latin:popupCharacters="\?" />
</default>
</switch>
diff --git a/java/res/xml-sw600dp/kbd_rows_spanish.xml b/java/res/xml-sw600dp/kbd_rows_spanish.xml
new file mode 100644
index 000000000..7ef44bb53
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_rows_spanish.xml
@@ -0,0 +1,69 @@
+<?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_qwerty_row1" />
+ <Row
+ latin:keyWidth="8.5%p"
+ >
+ <Key
+ latin:keyLabel="a"
+ latin:popupCharacters="@string/alternates_for_a"
+ latin:keyXPos="5.0%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="s"
+ latin:popupCharacters="@string/alternates_for_s" />
+ <Key
+ latin:keyLabel="d"
+ latin:popupCharacters="@string/alternates_for_d" />
+ <Key
+ latin:keyLabel="f" />
+ <Key
+ latin:keyLabel="g"
+ latin:popupCharacters="@string/alternates_for_g" />
+ <Key
+ latin:keyLabel="h" />
+ <Key
+ latin:keyLabel="j" />
+ <Key
+ latin:keyLabel="k"
+ latin:popupCharacters="@string/alternates_for_k" />
+ <Key
+ latin:keyLabel="l"
+ latin:popupCharacters="@string/alternates_for_l" />
+ <Key
+ latin:keyLabel="ñ" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyXPos="-14.6%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_symbols.xml b/java/res/xml-sw600dp/kbd_symbols.xml
index 3f555aa85..77849f6fd 100644
--- a/java/res/xml-sw600dp/kbd_symbols.xml
+++ b/java/res/xml-sw600dp/kbd_symbols.xml
@@ -20,13 +20,6 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -66,7 +59,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -100,7 +93,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -173,7 +166,7 @@
</switch>
<Key
latin:keyLabel="/"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</Row>
<!-- This row is intentionally not marked as a bottom row -->
<Row
@@ -218,7 +211,7 @@
</switch>
<Spacer
latin:keyXPos="-10.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/kbd_symbols_shift.xml b/java/res/xml-sw600dp/kbd_symbols_shift.xml
index 7ad7afc17..b25292f27 100644
--- a/java/res/xml-sw600dp/kbd_symbols_shift.xml
+++ b/java/res/xml-sw600dp/kbd_symbols_shift.xml
@@ -20,13 +20,6 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -67,7 +60,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-10.0%p"
- latin:keyWidth="-10.0%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -104,7 +97,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-14.6%p"
- latin:keyWidth="-14.6%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -156,7 +149,7 @@
latin:keyWidth="39.750%p" />
<Spacer
latin:keyXPos="-10.00%p"
- latin:keyWidth="0dp" />
+ latin:keyWidth="0%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f2" />
</Row>
diff --git a/java/res/xml-sw768dp/kbd_key_styles.xml b/java/res/xml-sw768dp/kbd_key_styles.xml
index fc06d00fc..4c1e3b63e 100644
--- a/java/res/xml-sw768dp/kbd_key_styles.xml
+++ b/java/res/xml-sw768dp/kbd_key_styles.xml
@@ -22,117 +22,54 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- Functional key styles -->
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="functionalKeyStyle"
- latin:isModifier="true" />
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="@drawable/sym_keyboard_shift_holo"
- latin:shiftedIcon="@drawable/sym_keyboard_shift_locked_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_shift"
- latin:parentStyle="functionalKeyStyle"
- latin:isSticky="true" />
- <key-style
- latin:styleName="deleteKeyStyle"
- latin:code="@integer/key_delete"
- latin:keyIcon="@drawable/sym_keyboard_delete_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_delete"
- latin:parentStyle="functionalKeyStyle"
- latin:isRepeatable="true" />
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_keyboard_return_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_return"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyHintIcon="@drawable/hint_popup_holo"
- latin:popupCharacters="@string/alternates_for_smiley"
- latin:maxPopupKeyboardColumn="5" />
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="@drawable/sym_keyboard_settings_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
- latin:keyIcon="@drawable/sym_keyboard_voice_holo"
- latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="functionalKeyStyle" />
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="@drawable/sym_bkeyboard_shift"
- latin:shiftedIcon="@drawable/sym_bkeyboard_shift_locked"
- latin:iconPreview="@drawable/sym_keyboard_feedback_shift"
- latin:parentStyle="functionalKeyStyle"
- latin:isSticky="true" />
- <key-style
- latin:styleName="deleteKeyStyle"
- latin:code="@integer/key_delete"
- latin:keyIcon="@drawable/sym_bkeyboard_delete"
- latin:iconPreview="@drawable/sym_keyboard_feedback_delete"
- latin:parentStyle="functionalKeyStyle"
- latin:isRepeatable="true" />
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_bkeyboard_return"
- latin:iconPreview="@drawable/sym_keyboard_feedback_return"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- <key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyHintIcon="@drawable/hint_popup_holo"
- latin:popupCharacters="@string/alternates_for_smiley"
- latin:maxPopupKeyboardColumn="5" />
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="@drawable/sym_bkeyboard_settings"
- latin:iconPreview="@drawable/sym_keyboard_feedback_settings"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
- latin:keyIcon="@drawable/sym_bkeyboard_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- </switch>
+ <key-style
+ latin:styleName="functionalKeyStyle"
+ latin:isFunctional="true" />
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKey"
+ latin:keyIconShifted="iconShiftedShiftKey"
+ latin:parentStyle="functionalKeyStyle"
+ latin:isSticky="true" />
+ <key-style
+ latin:styleName="deleteKeyStyle"
+ latin:code="@integer/key_delete"
+ latin:keyIcon="iconDeleteKey"
+ latin:parentStyle="functionalKeyStyle"
+ latin:isRepeatable="true" />
+ <key-style
+ latin:styleName="returnKeyStyle"
+ latin:code="@integer/key_return"
+ latin:keyIcon="iconReturnKey"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="spaceKeyStyle"
+ latin:code="@integer/key_space"
+ latin:keyIconPreview="iconPreviewSpaceKey" />
+ <key-style
+ latin:styleName="nonSpecialBackgroundSpaceKeyStyle"
+ latin:code="@integer/key_space"
+ latin:keyIconPreview="iconPreviewSpaceKey" />
+ <key-style
+ latin:styleName="smileyKeyStyle"
+ latin:keyLabel=":-)"
+ latin:keyOutputText=":-) "
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_smiley"
+ latin:maxPopupKeyboardColumn="5" />
+ <key-style
+ latin:styleName="settingsKeyStyle"
+ latin:code="@integer/key_settings"
+ latin:keyIcon="iconSettingsKey"
+ latin:keyIconPreview="iconPreviewSettingsKey"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="shortcutKeyStyle"
+ latin:code="@integer/key_shortcut"
+ latin:keyIcon="iconShortcutKey"
+ latin:keyIconPreview="iconPreviewShortcutKey"
+ latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="tabKeyStyle"
latin:code="@integer/key_tab"
@@ -161,9 +98,8 @@
<key-style
latin:styleName="comKeyStyle"
latin:keyLabel="@string/keylabel_for_popular_domain"
- latin:keyLabelOption="fontNormal"
+ latin:keyLabelOption="fontNormal|hasPopupHint"
latin:keyOutputText="@string/keylabel_for_popular_domain"
- latin:keyHintIcon="@drawable/hint_popup_holo"
latin:popupCharacters="@string/alternates_for_popular_domain" />
<switch>
<case
diff --git a/java/res/xml-sw768dp/kbd_number.xml b/java/res/xml-sw768dp/kbd_number.xml
index 8ffee3cfd..a3bed2f3a 100644
--- a/java/res/xml-sw768dp/kbd_number.xml
+++ b/java/res/xml-sw768dp/kbd_number.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="13.250%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -54,7 +47,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -68,7 +61,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -105,49 +98,60 @@
latin:keyEdgeFlags="left" />
<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:keyLabel="2"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="3" />
+ latin:keyLabel="3"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
- latin:keyLabel="*"
+ latin:keyStyle="numStarKeyStyle"
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="4"
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="43.125%p" />
<Key
- latin:keyLabel="5" />
+ latin:keyLabel="5"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="6" />
+ latin:keyLabel="6"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -156,21 +160,27 @@
edge key. -->
<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="7"
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="43.125%p" />
<Key
- latin:keyLabel="8" />
+ latin:keyLabel="8"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="9" />
+ latin:keyLabel="9"
+ latin:keyStyle="numKeyStyle" />
<!-- There is an empty area below the "Enter" key and right of the "9" key. To
ignore the touch event on the area, "9" is intentionally not marked as a right
edge key. -->
@@ -183,30 +193,28 @@
latin:keyStyle="settingsKeyStyle"
latin:keyWidth="8.047%p" />
</case>
- <default>
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
</switch>
<Key
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
latin:keyXPos="13.829%p"
- latin:keyWidth="24.14%p" />
+ latin:keyWidth="24.140%p" />
<Key
- latin:keyLabel="*"
+ latin:keyStyle="numStarKeyStyle"
latin:keyXPos="43.125%p" />
<Key
- latin:keyLabel="0" />
+ latin:keyLabel="0"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="#" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<switch>
<case
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
+ latin:keyStyle="shortcutKeyStyle"
latin:keyXPos="-8.047%p"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</case>
</switch>
</Row>
diff --git a/java/res/xml-sw768dp/kbd_numkey_styles.xml b/java/res/xml-sw768dp/kbd_numkey_styles.xml
deleted file mode 100644
index e27db94c7..000000000
--- a/java/res/xml-sw768dp/kbd_numkey_styles.xml
+++ /dev/null
@@ -1,148 +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.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="num0KeyStyle"
- latin:code="48"
- latin:keyIcon="@drawable/sym_keyboard_num0_holo" />
- <key-style
- latin:styleName="num1KeyStyle"
- latin:code="49"
- latin:keyIcon="@drawable/sym_keyboard_num1_holo" />
- <key-style
- latin:styleName="num2KeyStyle"
- latin:code="50"
- latin:keyIcon="@drawable/sym_keyboard_num2_holo" />
- <key-style
- latin:styleName="num3KeyStyle"
- latin:code="51"
- latin:keyIcon="@drawable/sym_keyboard_num3_holo" />
- <key-style
- latin:styleName="num4KeyStyle"
- latin:code="52"
- latin:keyIcon="@drawable/sym_keyboard_num4_holo" />
- <key-style
- latin:styleName="num5KeyStyle"
- latin:code="53"
- latin:keyIcon="@drawable/sym_keyboard_num5_holo" />
- <key-style
- latin:styleName="num6KeyStyle"
- latin:code="54"
- latin:keyIcon="@drawable/sym_keyboard_num6_holo" />
- <key-style
- latin:styleName="num7KeyStyle"
- latin:code="55"
- latin:keyIcon="@drawable/sym_keyboard_num7_holo" />
- <key-style
- latin:styleName="num8KeyStyle"
- latin:code="56"
- latin:keyIcon="@drawable/sym_keyboard_num8_holo" />
- <key-style
- latin:styleName="num9KeyStyle"
- latin:code="57"
- latin:keyIcon="@drawable/sym_keyboard_num9_holo" />
- <key-style
- latin:styleName="numStarKeyStyle"
- latin:code="42"
- latin:keyIcon="@drawable/sym_keyboard_numbstar_holo" />
- <key-style
- latin:styleName="numPoundKeyStyle"
- latin:code="35"
- latin:keyIcon="@drawable/sym_keyboard_numbpound_holo" />
- <key-style
- latin:styleName="numAltKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_keyboard_numalt"
- latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" />
- <key-style
- latin:styleName="numSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="num0KeyStyle"
- latin:code="48"
- latin:keyIcon="@drawable/sym_bkeyboard_num0" />
- <key-style
- latin:styleName="num1KeyStyle"
- latin:code="49"
- latin:keyIcon="@drawable/sym_bkeyboard_num1" />
- <key-style
- latin:styleName="num2KeyStyle"
- latin:code="50"
- latin:keyIcon="@drawable/sym_bkeyboard_num2" />
- <key-style
- latin:styleName="num3KeyStyle"
- latin:code="51"
- latin:keyIcon="@drawable/sym_bkeyboard_num3" />
- <key-style
- latin:styleName="num4KeyStyle"
- latin:code="52"
- latin:keyIcon="@drawable/sym_bkeyboard_num4" />
- <key-style
- latin:styleName="num5KeyStyle"
- latin:code="53"
- latin:keyIcon="@drawable/sym_bkeyboard_num5" />
- <key-style
- latin:styleName="num6KeyStyle"
- latin:code="54"
- latin:keyIcon="@drawable/sym_bkeyboard_num6" />
- <key-style
- latin:styleName="num7KeyStyle"
- latin:code="55"
- latin:keyIcon="@drawable/sym_bkeyboard_num7" />
- <key-style
- latin:styleName="num8KeyStyle"
- latin:code="56"
- latin:keyIcon="@drawable/sym_bkeyboard_num8" />
- <key-style
- latin:styleName="num9KeyStyle"
- latin:code="57"
- latin:keyIcon="@drawable/sym_bkeyboard_num9" />
- <key-style
- latin:styleName="numStarKeyStyle"
- latin:code="42"
- latin:keyIcon="@drawable/sym_bkeyboard_numstar" />
- <key-style
- latin:styleName="numPoundKeyStyle"
- latin:code="35"
- latin:keyIcon="@drawable/sym_bkeyboard_numpound" />
- <key-style
- latin:styleName="numAltKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_bkeyboard_numalt"
- latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" />
- <key-style
- latin:styleName="numSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- </case>
- </switch>
-</merge>
diff --git a/java/res/xml-sw768dp/kbd_phone.xml b/java/res/xml-sw768dp/kbd_phone.xml
index 8fc5e7d68..0935992fd 100644
--- a/java/res/xml-sw768dp/kbd_phone.xml
+++ b/java/res/xml-sw768dp/kbd_phone.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="13.250%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -40,16 +33,14 @@
latin:keyLabelOption="alignLeft"
latin:keyWidth="11.172%p"
latin:keyEdgeFlags="left" />
- <!-- To match one character label size with "Tab", I placed spaces around the char '-'
- and '+'. -->
<Key
- latin:code="45"
- latin:keyLabel=" - "
- latin:keyXPos="20.4%p"
+ latin:keyLabel="-"
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="20.400%p"
latin:keyWidth="8.047%p" />
<Key
- latin:code="43"
- latin:keyLabel=" + "
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:keyStyle="num1KeyStyle"
@@ -61,7 +52,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -69,16 +60,14 @@
latin:keyStyle="moreKeyStyle"
latin:keyWidth="11.172%p"
latin:keyEdgeFlags="left" />
- <!-- To match one character label size with "More", I placed spaces around the char ','
- and '.'. -->
<Key
- latin:code="44"
- latin:keyLabel=" , "
- latin:keyXPos="20.4%p"
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="20.400%p"
latin:keyWidth="8.047%p" />
<Key
- latin:code="46"
- latin:keyLabel=" . "
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:keyStyle="num4KeyStyle"
@@ -90,22 +79,20 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
- <!-- To match one character label size with "More", I placed spaces around the char '('
- and ')'. -->
<!-- There is an empty area below the "More" key and left of the "(" key. To ignore
the touch event on the area, "(" is intentionally not marked as a left edge key. -->
<Key
- latin:code="40"
- latin:keyLabel=" ( "
- latin:keyXPos="20.4%p"
+ latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
+ latin:keyXPos="20.400%p"
latin:keyWidth="8.047%p" />
<Key
- latin:code="41"
- latin:keyLabel=" ) "
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:keyStyle="num7KeyStyle"
@@ -125,14 +112,10 @@
latin:keyStyle="settingsKeyStyle"
latin:keyWidth="8.047%p" />
</case>
- <default>
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
</switch>
<Key
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
- latin:keyXPos="20.4%p"
+ latin:keyXPos="20.400%p"
latin:keyWidth="16.084%p" />
<Key
latin:keyStyle="numStarKeyStyle"
@@ -140,15 +123,16 @@
<Key
latin:keyStyle="num0KeyStyle" />
<Key
- latin:keyStyle="numPoundKeyStyle" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<switch>
<case
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
+ latin:keyStyle="shortcutKeyStyle"
latin:keyXPos="-8.047%p"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</case>
</switch>
</Row>
diff --git a/java/res/xml-sw768dp/kbd_phone_symbols.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml
index 449be47ef..6ee57d6a5 100644
--- a/java/res/xml-sw768dp/kbd_phone_symbols.xml
+++ b/java/res/xml-sw768dp/kbd_phone_symbols.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="13.250%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -41,20 +34,18 @@
latin:keyWidth="11.172%p"
latin:keyEdgeFlags="left" />
<Key
- latin:code="45"
- latin:keyLabel=" - "
+ latin:keyLabel="-"
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="13.829%p"
latin:keyWidth="8.047%p" />
<Key
- latin:code="43"
- latin:keyLabel=" + "
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:code="44"
latin:keyLabel="@string/label_pause_key"
latin:keyWidth="8.047%p" />
- <!-- To match one character label size with "Tab" and "Pause, I placed spaces around the
- char '-' and '+'. -->
<Key
latin:keyStyle="num1KeyStyle"
latin:keyXPos="43.125%p" />
@@ -65,7 +56,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -74,20 +65,18 @@
latin:keyWidth="11.172%p"
latin:keyEdgeFlags="left" />
<Key
- latin:code="44"
- latin:keyLabel=" , "
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="13.829%p"
latin:keyWidth="8.047%p" />
<Key
- latin:code="46"
- latin:keyLabel=" . "
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:code="59"
latin:keyLabel="@string/label_wait_key"
latin:keyWidth="8.047%p" />
- <!-- To match one character label size with "More" and "Wait", I placed spaces around the
- char ',' and '.'. -->
<Key
latin:keyStyle="num4KeyStyle"
latin:keyXPos="43.125%p" />
@@ -98,26 +87,24 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-11.172%p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
- <!-- To match one character label size with "More" and etc., I placed spaces around the
- char 'N', '(' and ')'. -->
<!-- There is an empty area below the "More" key and left of the "(" key. To ignore
the touch event on the area, "(" is intentionally not marked as a left edge key. -->
<Key
- latin:code="40"
- latin:keyLabel=" ( "
+ latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
latin:keyXPos="13.829%p"
latin:keyWidth="8.047%p" />
<Key
- latin:code="41"
- latin:keyLabel=" ) "
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
- latin:code="78"
- latin:keyLabel=" N "
+ latin:keyLabel="N"
+ latin:keyStyle="numKeyStyle"
latin:keyWidth="8.047%p" />
<Key
latin:keyStyle="num7KeyStyle"
@@ -137,30 +124,27 @@
latin:keyStyle="settingsKeyStyle"
latin:keyWidth="8.047%p" />
</case>
- <default>
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
</switch>
<Key
latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
latin:keyXPos="13.829%p"
- latin:keyWidth="24.14%p" />
+ latin:keyWidth="24.140%p" />
<Key
latin:keyStyle="numStarKeyStyle"
latin:keyXPos="43.125%p" />
<Key
latin:keyStyle="num0KeyStyle" />
<Key
- latin:keyStyle="numPoundKeyStyle" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<switch>
<case
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
+ latin:keyStyle="shortcutKeyStyle"
latin:keyXPos="-8.047%p"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</case>
</switch>
</Row>
diff --git a/java/res/xml-sw768dp/kbd_qwerty.xml b/java/res/xml-sw768dp/kbd_qwerty.xml
deleted file mode 100644
index 1c8d51ffe..000000000
--- a/java/res/xml-sw768dp/kbd_qwerty.xml
+++ /dev/null
@@ -1,33 +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:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
->
- <include
- latin:keyboardLayout="@xml/kbd_qwerty_rows" />
-</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row1.xml b/java/res/xml-sw768dp/kbd_qwerty_row1.xml
index 0a793028e..3727cf34e 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row1.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row1.xml
@@ -63,7 +63,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row2.xml b/java/res/xml-sw768dp/kbd_qwerty_row2.xml
index aeeab235e..45af120e2 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row2.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row2.xml
@@ -56,7 +56,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row3.xml b/java/res/xml-sw768dp/kbd_qwerty_row3.xml
index e488cf32d..7297ea512 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row3.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row3.xml
@@ -46,34 +46,12 @@
latin:popupCharacters="@string/alternates_for_n" />
<Key
latin:keyLabel="m" />
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
- latin:popupCharacters="!" />
- <Key
- latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
- latin:popupCharacters="\?" />
- </default>
- </switch>
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right2" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_row4.xml b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
index 44e8e10e1..bdef89dcc 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw768dp/kbd_qwerty_row4.xml
@@ -26,51 +26,45 @@
latin:keyWidth="8.047%p"
>
<switch>
- <case latin:hasSettingsKey="true">
+ <case
+ latin:hasSettingsKey="true"
+ >
<Key
latin:keyStyle="settingsKeyStyle"
latin:keyWidth="8.047%p" />
</case>
- <default>
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
</switch>
+ <Spacer
+ latin:keyXPos="15.157%p"
+ latin:keyWidth="fillRight" />
<switch>
<case
- latin:languageCode="ru"
+ latin:mode="url"
>
+ <Key
+ latin:keyStyle="comKeyStyle"
+ latin:keyWidth="16.084%p" />
+ </case>
+ <default>
<switch>
- <!-- TODO: implement logical OR for <case> attribute -->
<case
latin:mode="email"
>
<Key
- latin:keyStyle="comKeyStyle"
- latin:keyXPos="15.157%p" />
- </case>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyStyle="comKeyStyle"
- latin:keyXPos="15.157%p" />
+ latin:keyStyle="comKeyStyle" />
</case>
<case
latin:imeAction="actionSearch"
>
<Key
latin:keyLabel=":"
- latin:manualTemporaryUpperCaseCode="43"
- latin:keyHintIcon="@drawable/key_hint_plus_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_plus_large_holo"
- latin:popupCharacters="+"
- latin:keyXPos="15.157%p" />
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="+"
+ latin:popupCharacters="+" />
</case>
<default>
<Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyXPos="15.157%p" />
+ latin:keyStyle="smileyKeyStyle" />
</default>
</switch>
<switch>
@@ -80,81 +74,14 @@
<Key
latin:keyLabel="\@" />
</case>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyLabel="-"
- latin:manualTemporaryUpperCaseCode="95"
- latin:keyHintIcon="@drawable/key_hint_underline_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_underline_large_holo"
- latin:popupCharacters="_" />
- </case>
<default>
<Key
latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="64"
- latin:keyHintIcon="@drawable/key_hint_at_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_at_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\@"
latin:popupCharacters="\@" />
</default>
</switch>
- </case>
- <!-- not languageCode="ru" -->
- <default>
- <switch>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyStyle="comKeyStyle"
- latin:keyXPos="15.157%p"
- latin:keyWidth="16.084%p" />
- </case>
- <default>
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyStyle="comKeyStyle"
- latin:keyXPos="15.157%p" />
- </case>
- <case
- latin:imeAction="actionSearch"
- >
- <Key
- latin:keyLabel=":"
- latin:manualTemporaryUpperCaseCode="43"
- latin:keyHintIcon="@drawable/key_hint_plus_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_plus_large_holo"
- latin:popupCharacters="+"
- latin:keyXPos="15.157%p" />
- </case>
- <default>
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyXPos="15.157%p" />
- </default>
- </switch>
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="\@" />
- </case>
- <default>
- <Key
- latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="64"
- latin:keyHintIcon="@drawable/key_hint_at_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_at_large_holo"
- latin:popupCharacters="\@" />
- </default>
- </switch>
- </default>
- </switch>
</default>
</switch>
<Key
@@ -163,95 +90,41 @@
latin:keyWidth="37.500%p" />
<switch>
<case
- latin:languageCode="ru"
+ latin:mode="email"
>
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="-" />
- </case>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="58"
- latin:keyHintIcon="@drawable/key_hint_colon_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_colon_large_holo"
- latin:popupCharacters=":" />
- </case>
- <default>
- <Key
- latin:keyLabel="\?"
- latin:manualTemporaryUpperCaseCode="95"
- latin:keyHintIcon="@drawable/key_hint_underline_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_underline_large_holo"
- latin:popupCharacters="_" />
- </default>
- </switch>
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="_" />
- </case>
- <default>
- <Key
- latin:keyLabel="!"
- latin:manualTemporaryUpperCaseCode="34"
- latin:keyHintIcon="@drawable/key_hint_quote_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_quote_large_holo"
- latin:popupCharacters="\'" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="-" />
+ </case>
+ <case
+ latin:mode="url"
+ >
+ <Key
+ latin:keyLabel="/"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel=":"
+ latin:popupCharacters=":" />
</case>
- <!-- not languageCode="ru" -->
<default>
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="-" />
- </case>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyLabel="/"
- latin:manualTemporaryUpperCaseCode="58"
- latin:keyHintIcon="@drawable/key_hint_colon_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_colon_large_holo"
- latin:popupCharacters=":" />
- </case>
- <default>
- <Key
- latin:keyLabel="\'"
- latin:manualTemporaryUpperCaseCode="34"
- latin:keyHintIcon="@drawable/key_hint_quote_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_quote_large_holo"
- latin:popupCharacters="&quot;" />
- </default>
- </switch>
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="_" />
- </case>
- <default>
- <Key
- latin:keyLabel="-"
- latin:manualTemporaryUpperCaseCode="95"
- latin:keyHintIcon="@drawable/key_hint_underline_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_underline_large_holo"
- latin:popupCharacters="_" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="\'"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="&quot;"
+ latin:popupCharacters="&quot;" />
+ </default>
+ </switch>
+ <switch>
+ <case
+ latin:mode="email"
+ >
+ <Key
+ latin:keyLabel="_" />
+ </case>
+ <default>
+ <Key
+ latin:keyLabel="-"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="_"
+ latin:popupCharacters="_" />
</default>
</switch>
<switch>
@@ -259,9 +132,9 @@
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
+ latin:keyStyle="shortcutKeyStyle"
latin:keyXPos="-8.047%p"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</case>
</switch>
</Row>
diff --git a/java/res/xml-sw768dp/kbd_row3_right2.xml b/java/res/xml-sw768dp/kbd_row3_right2.xml
new file mode 100644
index 000000000..25453160f
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_row3_right2.xml
@@ -0,0 +1,46 @@
+<?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:popupCharacters="!" />
+ <Key
+ latin:keyLabel="."
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
+ latin:popupCharacters="\?" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_rows_arabic.xml b/java/res/xml-sw768dp/kbd_rows_arabic.xml
new file mode 100644
index 000000000..c1810026b
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_rows_arabic.xml
@@ -0,0 +1,140 @@
+<?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.
+*/
+-->
+
+<!-- This file for Arabic layout is an alpha version. It allows to enter -->
+<!-- some right-to-left text, but it has gone through no study whatsoever, -->
+<!-- and needs to be run through UX. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/kbd_key_styles" />
+ <Row
+ latin:keyWidth="7.375%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="7.500%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ض" />
+ <Key
+ latin:keyLabel="ص" />
+ <Key
+ latin:keyLabel="ث" />
+ <Key
+ latin:keyLabel="ق" />
+ <Key
+ latin:keyLabel="ف"
+ latin:popupCharacters="ف,ڤ" />
+ <Key
+ latin:keyLabel="غ" />
+ <Key
+ latin:keyLabel="ع" />
+ <Key
+ latin:keyLabel="ه"
+ latin:popupCharacters="ه,هـ" />
+ <Key
+ latin:keyLabel="خ" />
+ <Key
+ latin:keyLabel="ح" />
+ <Key
+ latin:keyLabel="ج"
+ latin:popupCharacters="ج,چ" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-11.500%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="7.375%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="9.375%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ش" />
+ <Key
+ latin:keyLabel="س" />
+ <Key
+ latin:keyLabel="ي" />
+ <Key
+ latin:keyLabel="ب"
+ latin:popupCharacters="ب,پ" />
+ <Key
+ latin:keyLabel="ل"
+ latin:popupCharacters="ل,لا" />
+ <Key
+ latin:keyLabel="ا"
+ latin:popupCharacters="ا,أ,إ,آ" />
+ <Key
+ latin:keyLabel="ت" />
+ <Key
+ latin:keyLabel="ن" />
+ <Key
+ latin:keyLabel="م" />
+ <Key
+ latin:keyLabel="ك"
+ latin:popupCharacters="ك,گ" />
+ <Key
+ latin:keyLabel="ط" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyXPos="-9.375%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="7.375%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="12.750%p"
+ latin:keyEdgeFlags="left" />
+ <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:popupCharacters="ز,ژ" />
+ <Key
+ latin:keyLabel="ظ" />
+ <Key
+ latin:keyLabel="د" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_azerty_rows.xml b/java/res/xml-sw768dp/kbd_rows_azerty.xml
index f6ebfe612..373bda9ce 100644
--- a/java/res/xml-sw768dp/kbd_azerty_rows.xml
+++ b/java/res/xml-sw768dp/kbd_rows_azerty.xml
@@ -64,7 +64,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -105,7 +105,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -133,9 +133,8 @@
latin:popupCharacters="@string/alternates_for_n" />
<Key
latin:keyLabel="\'"
- latin:manualTemporaryUpperCaseCode="58"
- latin:keyHintIcon="@drawable/key_hint_colon_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_colon_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel=":"
latin:popupCharacters=":" />
<switch>
<case
@@ -149,22 +148,20 @@
<default>
<Key
latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="!"
latin:popupCharacters="!" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
latin:popupCharacters="\?" />
</default>
</switch>
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml-sw768dp/kbd_rows_hebrew.xml b/java/res/xml-sw768dp/kbd_rows_hebrew.xml
new file mode 100644
index 000000000..5275a1f15
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_rows_hebrew.xml
@@ -0,0 +1,127 @@
+<?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" />
+ <Row
+ latin:keyWidth="8.000%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyEdgeFlags="left" />
+ <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="deleteKeyStyle"
+ latin:keyXPos="-12.000%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.000%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="9.600%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ש" />
+ <Key
+ latin:keyLabel="ד" />
+ <Key
+ latin:keyLabel="ג"
+ latin:popupCharacters="ג,ג׳" />
+ <Key
+ latin:keyLabel="כ" />
+ <Key
+ latin:keyLabel="ע" />
+ <Key
+ latin:keyLabel="י"
+ latin:popupCharacters="י,ײַ" />
+ <Key
+ latin:keyLabel="ח"
+ latin:popupCharacters="ח,ח׳" />
+ <Key
+ latin:keyLabel="ל" />
+ <Key
+ latin:keyLabel="ך" />
+ <Key
+ latin:keyLabel="ף" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyXPos="-10.400%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.000%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="13.200%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ז"
+ latin:popupCharacters="ז,ז׳" />
+ <Key
+ latin:keyLabel="ס" />
+ <Key
+ latin:keyLabel="ב" />
+ <Key
+ latin:keyLabel="ה" />
+ <Key
+ latin:keyLabel="נ" />
+ <Key
+ latin:keyLabel="מ" />
+ <Key
+ latin:keyLabel="צ"
+ latin:popupCharacters="צ,צ׳" />
+ <Key
+ latin:keyLabel="ת"
+ latin:popupCharacters="ת,ת׳" />
+ <Key
+ latin:keyLabel="ץ"
+ latin:popupCharacters="ץ,ץ׳" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_qwerty_rows.xml b/java/res/xml-sw768dp/kbd_rows_qwerty.xml
index 6237712f6..6237712f6 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_rows.xml
+++ b/java/res/xml-sw768dp/kbd_rows_qwerty.xml
diff --git a/java/res/xml-sw768dp/kbd_qwertz_rows.xml b/java/res/xml-sw768dp/kbd_rows_qwertz.xml
index 9a8b66177..6567c3166 100644
--- a/java/res/xml-sw768dp/kbd_qwertz_rows.xml
+++ b/java/res/xml-sw768dp/kbd_rows_qwertz.xml
@@ -64,7 +64,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<include
@@ -106,22 +106,20 @@
<default>
<Key
latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="!"
latin:popupCharacters="!" />
<Key
latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
+ latin:keyLabelOption="hasUppercaseLetter"
+ latin:keyHintLabel="\?"
latin:popupCharacters="\?" />
</default>
</switch>
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml-sw768dp/kbd_ru_rows.xml b/java/res/xml-sw768dp/kbd_rows_russian.xml
index 22e7d562c..ee91481c1 100644
--- a/java/res/xml-sw768dp/kbd_ru_rows.xml
+++ b/java/res/xml-sw768dp/kbd_rows_russian.xml
@@ -25,12 +25,11 @@
latin:keyboardLayout="@xml/kbd_key_styles" />
<!-- This row is intentionally not marked as a top row -->
<Row
- latin:keyWidth="7.579%p"
+ latin:keyWidth="7.125%p"
>
<Key
latin:keyStyle="tabKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="7.969%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="й" />
@@ -56,18 +55,19 @@
<Key
latin:keyLabel="х" />
<Key
+ latin:keyLabel="ъ" />
+ <Key
latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="7.500%p"
+ latin:keyWidth="7.125%p"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="9.219%p"
+ latin:keyWidth="9.375%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="ф" />
@@ -93,16 +93,16 @@
latin:keyLabel="э" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyXPos="-9.375%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="7.500%p"
+ latin:keyWidth="7.125%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="12.400%p"
+ latin:keyWidth="12.750%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="я" />
@@ -117,22 +117,16 @@
<Key
latin:keyLabel="т" />
<Key
- latin:keyLabel="ь"
- latin:popupCharacters="@string/alternates_for_cyrillic_soft_sign" />
+ latin:keyLabel="ь" />
<Key
latin:keyLabel="б" />
<Key
latin:keyLabel="ю" />
- <Key
- latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="44"
- latin:keyHintIcon="@drawable/key_hint_comma_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_comma_large_holo"
- latin:popupCharacters="," />
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right2" />
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml b/java/res/xml-sw768dp/kbd_rows_scandinavian.xml
index 363de4b8c..7e9f604f5 100644
--- a/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml
+++ b/java/res/xml-sw768dp/kbd_rows_scandinavian.xml
@@ -24,12 +24,12 @@
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
<Row
- latin:keyWidth="7.579%p"
+ latin:keyWidth="7.375%p"
>
<Key
latin:keyStyle="tabKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="7.969%p"
+ latin:keyWidth="7.500%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="q"
@@ -65,17 +65,17 @@
latin:keyLabel="å" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyXPos="-11.500%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="7.500%p"
+ latin:keyWidth="7.375%p"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="7.969%p"
+ latin:keyWidth="9.375%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="a"
@@ -109,13 +109,43 @@
latin:popupCharacters="@string/alternates_for_scandinavia_row2_11" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyXPos="-9.375%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="7.375%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="12.750%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="z"
+ latin:popupCharacters="@string/alternates_for_z" />
+ <Key
+ latin:keyLabel="x" />
+ <Key
+ latin:keyLabel="c"
+ latin:popupCharacters="@string/alternates_for_c" />
+ <Key
+ latin:keyLabel="v"
+ latin:popupCharacters="@string/alternates_for_v" />
+ <Key
+ latin:keyLabel="b" />
+ <Key
+ latin:keyLabel="n"
+ latin:popupCharacters="@string/alternates_for_n" />
+ <Key
+ latin:keyLabel="m" />
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right2" />
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyXPos="-12.750%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
-
</Row>
- <include
- latin:keyboardLayout="@xml/kbd_qwerty_row3" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_row4" />
</merge>
diff --git a/java/res/xml-sw768dp/kbd_sr_rows.xml b/java/res/xml-sw768dp/kbd_rows_serbian.xml
index 693658d09..4997dabb9 100644
--- a/java/res/xml-sw768dp/kbd_sr_rows.xml
+++ b/java/res/xml-sw768dp/kbd_rows_serbian.xml
@@ -25,58 +25,48 @@
latin:keyboardLayout="@xml/kbd_key_styles" />
<!-- This row is intentionally not marked as a top row -->
<Row
- latin:keyWidth="7.579%p"
+ latin:keyWidth="7.125%p"
>
<Key
latin:keyStyle="tabKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="7.969%p"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="љ"
- latin:popupCharacters="1" />
+ latin:keyLabel="љ" />
<Key
- latin:keyLabel="њ"
- latin:popupCharacters="2" />
+ latin:keyLabel="њ" />
<Key
- latin:keyLabel="е"
- latin:popupCharacters="3" />
+ latin:keyLabel="е" />
<Key
- latin:keyLabel="р"
- latin:popupCharacters="4" />
+ latin:keyLabel="р" />
<Key
- latin:keyLabel="т"
- latin:popupCharacters="5" />
+ latin:keyLabel="т" />
<Key
- latin:keyLabel="з"
- latin:popupCharacters="6" />
+ latin:keyLabel="з" />
<Key
- latin:keyLabel="у"
- latin:popupCharacters="7" />
+ latin:keyLabel="у" />
<Key
- latin:keyLabel="и"
- latin:popupCharacters="8" />
+ latin:keyLabel="и" />
<Key
- latin:keyLabel="о"
- latin:popupCharacters="9" />
+ latin:keyLabel="о" />
<Key
- latin:keyLabel="п"
- latin:popupCharacters="0" />
+ latin:keyLabel="п" />
<Key
latin:keyLabel="ш" />
<Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
- latin:keyEdgeFlags="right" />
+ latin:keyLabel="ђ" />
+ <Key
+ latin:keyLabel="ж"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right"/>
</Row>
<Row
- latin:keyWidth="7.500%p"
+ latin:keyWidth="7.250%p"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="9.219%p"
+ latin:keyWidth="11.172%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="а" />
@@ -101,17 +91,17 @@
<Key
latin:keyLabel="ћ" />
<Key
- latin:keyStyle="returnKeyStyle"
- latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyXPos="-9.219%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="7.500%p"
+ latin:keyWidth="7.250%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="9.219%p"
+ latin:keyWidth="13.829%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="ѕ" />
@@ -127,26 +117,12 @@
latin:keyLabel="н" />
<Key
latin:keyLabel="м" />
+ <include
+ latin:keyboardLayout="@xml/kbd_row3_right2" />
<Key
- latin:keyLabel="ђ" />
- <Key
- latin:keyLabel="ж" />
- <Key
- latin:keyLabel=","
- latin:manualTemporaryUpperCaseCode="33"
- latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_exclamation_large_holo"
- latin:popupCharacters="!" />
- <Key
- latin:keyLabel="."
- latin:manualTemporaryUpperCaseCode="63"
- latin:keyHintIcon="@drawable/key_hint_question_holo"
- latin:manualTemporaryUpperCaseHintIcon="@drawable/key_hint_question_large_holo"
- latin:popupCharacters="\?" />
- <Key
- latin:keyStyle="shiftKeyStyle"
+ latin:keyStyle="returnKeyStyle"
latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml-sw768dp/kbd_rows_spanish.xml b/java/res/xml-sw768dp/kbd_rows_spanish.xml
new file mode 100644
index 000000000..300592e6a
--- /dev/null
+++ b/java/res/xml-sw768dp/kbd_rows_spanish.xml
@@ -0,0 +1,72 @@
+<?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_qwerty_row1" />
+ <Row
+ latin:keyWidth="8.125%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="10.167%p"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="a"
+ latin:popupCharacters="@string/alternates_for_a" />
+ <Key
+ latin:keyLabel="s"
+ latin:popupCharacters="@string/alternates_for_s" />
+ <Key
+ latin:keyLabel="d"
+ latin:popupCharacters="@string/alternates_for_d" />
+ <Key
+ latin:keyLabel="f" />
+ <Key
+ latin:keyLabel="g"
+ latin:popupCharacters="@string/alternates_for_g" />
+ <Key
+ latin:keyLabel="h" />
+ <Key
+ latin:keyLabel="j" />
+ <Key
+ latin:keyLabel="k"
+ latin:popupCharacters="@string/alternates_for_k" />
+ <Key
+ latin:keyLabel="l"
+ latin:popupCharacters="@string/alternates_for_l" />
+ <Key
+ latin:keyLabel="ñ" />
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyXPos="-15.704%p"
+ latin:keyWidth="fillBoth"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_symbols.xml b/java/res/xml-sw768dp/kbd_symbols.xml
index 15c75cacc..0e6103ab9 100644
--- a/java/res/xml-sw768dp/kbd_symbols.xml
+++ b/java/res/xml-sw768dp/kbd_symbols.xml
@@ -20,13 +20,6 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -71,7 +64,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -109,7 +102,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -130,12 +123,6 @@
latin:popupCharacters="≠,≈" />
<switch>
<case
- latin:languageCode="ru"
- >
- <Key
- latin:keyLabel=":" />
- </case>
- <case
latin:mode="url"
>
<Key
@@ -149,40 +136,20 @@
</switch>
<Key
latin:keyLabel=";" />
- <switch>
- <case
- latin:languageCode="ru"
- >
- <Key
- latin:keyLabel="\'"
- latin:popupCharacters="‘,’,‚,‛" />
- <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
- <!-- latin:popupCharacters="“,”,„,‟,«,»" -->
- <Key
- latin:keyLabel="&quot;"
- latin:popupCharacters="“,”,«,»" />
- <Key
- latin:keyLabel="." />
- <Key
- latin:keyLabel="," />
- </case>
- <default>
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- <Key
- latin:keyLabel="!"
- latin:popupCharacters="¡" />
- <Key
- latin:keyLabel="\?"
- latin:popupCharacters="¿" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="," />
+ <Key
+ latin:keyLabel="." />
+ <Key
+ latin:keyLabel="!"
+ latin:popupCharacters="¡" />
+ <Key
+ latin:keyLabel="\?"
+ latin:popupCharacters="¿" />
<Key
latin:keyStyle="moreKeyStyle"
latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<!-- This row is intentionally not marked as a bottom row -->
@@ -190,15 +157,13 @@
latin:keyWidth="8.047%p"
>
<switch>
- <case latin:hasSettingsKey="true">
+ <case
+ latin:hasSettingsKey="true"
+ >
<Key
latin:keyStyle="settingsKeyStyle"
latin:keyWidth="8.047%p" />
</case>
- <default>
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
</switch>
<Key
latin:keyLabel="/"
@@ -209,33 +174,21 @@
latin:keyStyle="spaceKeyStyle"
latin:keyXPos="31.250%p"
latin:keyWidth="37.500%p" />
- <switch>
- <case
- latin:languageCode="ru"
- >
- <Key
- latin:keyLabel="_" />
- <Key
- latin:keyLabel="-" />
- </case>
- <default>
- <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
- <!-- latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" -->
- <Key
- latin:keyLabel="&quot;"
- latin:popupCharacters="“,”,«,»,‘,’,‚,‛" />
- <Key
- latin:keyLabel="_" />
- </default>
- </switch>
+ <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
+ <!-- latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" -->
+ <Key
+ latin:keyLabel="&quot;"
+ latin:popupCharacters="“,”,«,»,‘,’,‚,‛" />
+ <Key
+ latin:keyLabel="_" />
<switch>
<case
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
+ latin:keyStyle="shortcutKeyStyle"
latin:keyXPos="-8.047%p"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</case>
</switch>
</Row>
diff --git a/java/res/xml-sw768dp/kbd_symbols_shift.xml b/java/res/xml-sw768dp/kbd_symbols_shift.xml
index 44340ab81..b36814104 100644
--- a/java/res/xml-sw768dp/kbd_symbols_shift.xml
+++ b/java/res/xml-sw768dp/kbd_symbols_shift.xml
@@ -20,13 +20,6 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -72,7 +65,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyXPos="-9.219%p"
- latin:keyWidth="-9.219%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -113,7 +106,7 @@
<Key
latin:keyStyle="returnKeyStyle"
latin:keyXPos="-15.704%p"
- latin:keyWidth="-15.704%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -150,7 +143,7 @@
<Key
latin:keyStyle="moreKeyStyle"
latin:keyXPos="-13.750%p"
- latin:keyWidth="-13.750%p"
+ latin:keyWidth="fillBoth"
latin:keyEdgeFlags="right" />
</Row>
<!-- This row is intentionally not marked as a bottom row -->
@@ -163,10 +156,6 @@
latin:keyStyle="settingsKeyStyle"
latin:keyWidth="8.047%p" />
</case>
- <default>
- <Spacer
- latin:keyWidth="8.047%p" />
- </default>
</switch>
<Key
latin:keyStyle="spaceKeyStyle"
@@ -177,9 +166,9 @@
latin:voiceKeyEnabled="true"
>
<Key
- latin:keyStyle="micKeyStyle"
+ latin:keyStyle="shortcutKeyStyle"
latin:keyXPos="-8.047%p"
- latin:keyWidth="0%p" />
+ latin:keyWidth="fillRight" />
</case>
</switch>
</Row>
diff --git a/java/res/xml-tr/kbd_qwerty.xml b/java/res/xml-tr/kbd_qwerty.xml
new file mode 100644
index 000000000..d2c38f60a
--- /dev/null
+++ b/java/res/xml-tr/kbd_qwerty.xml
@@ -0,0 +1,27 @@
+<?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/kbd_currency_key_styles.xml b/java/res/xml/kbd_currency_key_styles.xml
index b30dd6451..9d3bb4725 100644
--- a/java/res/xml/kbd_currency_key_styles.xml
+++ b/java/res/xml/kbd_currency_key_styles.xml
@@ -27,229 +27,59 @@
>
<key-style
latin:styleName="currencyKeyStyle"
- latin:keyLabel="$"
- latin:popupCharacters="@string/alternates_for_currency_dollar" />
+ latin:keyLabel="$" />
</case>
<!-- Countries using Euro currency, 23 countries as for January 2011. -->
- <!-- 1. Andorra (ca_AD, ca_ES) -->
- <case
- latin:languageCode="ca"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 2. Austria (de_AT) -->
-<!-- <case-->
-<!-- latin:countryCode="AT"-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
- <!-- 3. Belgium (nl_BE, fr_BE, de_BE) -->
-<!-- <case-->
-<!-- latin:countryCode="BE"-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
- <!-- 4. Cyprus (el_CY, tr_CY) -->
- <case
- latin:countryCode="CY"
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 5. Estonia (et_EE) -->
-<!-- <case-->
-<!-- latin:languageCode="et"-->
-<!-- latin:countryCode=""-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
- <!-- 6. Finland (fi_FI, sv_FI) -->
- <case
- latin:languageCode="fi"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 7. France (fr_FR) -->
- <case
- latin:languageCode="fr"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 8. Germany (de_DE) -->
- <case
- latin:languageCode="de"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 9. Greece (el_GR) -->
- <case
- latin:languageCode="el"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 10. Ireland (ga_IE, en_IE) -->
- <case
- latin:countryCode="IE"
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 11. Italy (it_IT) -->
- <case
- latin:languageCode="it"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 12. Kosovo -->
-<!-- <case-->
-<!-- latin:countryCode="XK"-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
- <!-- 13. Luxembourg (lb_LU, fr_LU, de_LU) -->
- <case
- latin:countryCode="LU"
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 14. Malta (mt_MT, en_MT) -->
- <case
- latin:countryCode="MT"
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 15. Monaco (fr_MO) -->
-<!-- <case-->
-<!-- latin:countryCode="MO"-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
- <!-- 16. Montenegro (sla_ME) -->
- <case
- latin:countryCode="ME"
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 17. Netherlands (nl_NL) -->
- <case
- latin:languageCode="nl"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 18. Portugal (pt_PT) -->
- <case
- latin:languageCode="pt"
- latin:countryCode=""
- >
- <key-style
- latin:styleName="currencyKeyStyle"
- latin:keyLabel="€"
- latin:popupCharacters="@string/alternates_for_currency_euro" />
- </case>
- <!-- 19. San Marino (it_SM) -->
-<!-- <case-->
-<!-- latin:countryCode="SM"-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
- <!-- 20. Slovakia (sk_SK) -->
+ 1. Andorra (ca_AD, ca_ES)
+ 2. Austria (de_AT)
+ 3. Belgium (nl_BE, fr_BE, de_BE)
+ 4. Cyprus (el_CY, tr_CY)
+ 5. Estonia (et_EE)
+ 6. Finland (fi_FI, sv_FI)
+ 7. France (fr_FR)
+ 8. Germany (de_DE)
+ 9. Greece (el_GR)
+ 10. Ireland (ga_IE, en_IE)
+ 11. Italy (it_IT)
+ 12. Kosovo (??_XK) ??
+ 13. Luxembourg (lb_LU, fr_LU, de_LU)
+ 14. Malta (mt_MT, en_MT)
+ 15. Monaco (fr_MO)
+ 16. Montenegro (sla_ME)
+ 17. Netherlands (nl_NL)
+ 18. Portugal (pt_PT)
+ 19. San Marino (it_SM)
+ 20. Slovakia (sk_SK)
+ 21. Slovenia (sl_SI)
+ 22. Spain (es_ES, ca_ES)
+ 23. Vatican City (it_VA)
+ -->
+ <!-- Note: Some locales may not have country code, and it it supposed to indicate the
+ country where the language originally/mainly spoken. -->
<case
- latin:languageCode="sk"
- latin:countryCode=""
+ latin:localeCode="de|es|el|fi|fr|it|nl|sk|sl|pt_PT"
>
<key-style
latin:styleName="currencyKeyStyle"
latin:keyLabel="€"
latin:popupCharacters="@string/alternates_for_currency_euro" />
</case>
- <!-- 21. Slovenia (sl_SI) -->
<case
- latin:languageCode="sl"
- latin:countryCode=""
+ latin:languageCode="ca|et|lb|mt|sla"
>
<key-style
latin:styleName="currencyKeyStyle"
latin:keyLabel="€"
latin:popupCharacters="@string/alternates_for_currency_euro" />
</case>
- <!-- 22. Spain (es_ES, ca_ES) -->
<case
- latin:languageCode="es"
- latin:countryCode=""
+ 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"
>
<key-style
latin:styleName="currencyKeyStyle"
latin:keyLabel="€"
latin:popupCharacters="@string/alternates_for_currency_euro" />
</case>
- <!-- 23. Vatican City (it_VA) -->
-<!-- <case-->
-<!-- latin:countryCode="VA"-->
-<!-- >-->
-<!-- <key-style-->
-<!-- latin:styleName="currencyKeyStyle"-->
-<!-- latin:keyLabel="€"-->
-<!-- latin:popupCharacters="@string/alternates_for_currency_euro" />-->
-<!-- </case>-->
<!-- United Kingdom -->
<case
latin:countryCode="GB"
@@ -266,4 +96,4 @@
latin:popupCharacters="@string/alternates_for_currency_dollar" />
</default>
</switch>
-</merge> \ No newline at end of file
+</merge>
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index 28869a87d..cc949c9dc 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -22,187 +22,60 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- Base key style for the functional key -->
+ <key-style
+ latin:styleName="functionalKeyStyle"
+ latin:isFunctional="true" />
+ <!-- Base key style for the key which may have settings key as popup key -->
<switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="functionalKeyStyle"
- latin:isModifier="true" />
- </case>
<case
- latin:colorScheme="black"
+ latin:clobberSettingsKey="true"
>
<key-style
- latin:styleName="functionalKeyStyle" />
+ latin:styleName="settingsPopupStyle"
+ latin:parentStyle="functionalKeyStyle" />
</case>
- </switch>
- <!-- Base key style for the key which may have settings key as popup key -->
- <switch>
<case
- latin:clobberSettingsKey="true"
+ latin:clobberSettingsKey="false"
+ latin:hasSettingsKey="true"
>
<key-style
latin:styleName="settingsPopupStyle"
latin:parentStyle="functionalKeyStyle" />
</case>
- <!-- latin:hasSettingsKey="false" -->
+ <!-- clobberSettingsKey="false" and hasSettingsKey="false" -->
<default>
<key-style
latin:styleName="settingsPopupStyle"
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="\@drawable/sym_keyboard_settings_holo|\@integer/key_settings"
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="\@icon/5|\@integer/key_settings"
latin:parentStyle="functionalKeyStyle" />
</default>
</switch>
<!-- Functional key styles -->
+ <key-style
+ latin:styleName="shiftKeyStyle"
+ latin:code="@integer/key_shift"
+ latin:keyIcon="iconShiftKey"
+ latin:keyIconShifted="iconShiftedShiftKey"
+ latin:parentStyle="functionalKeyStyle"
+ latin:isSticky="true" />
<switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="@drawable/sym_keyboard_shift"
- latin:shiftedIcon="@drawable/sym_keyboard_shift_locked"
- latin:iconPreview="@drawable/sym_keyboard_feedback_shift"
- latin:parentStyle="functionalKeyStyle"
- latin:isSticky="true" />
+ <case latin:localeCode="ar|iw">
<key-style
latin:styleName="deleteKeyStyle"
latin:code="@integer/key_delete"
- latin:keyIcon="@drawable/sym_keyboard_delete"
- latin:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ latin:keyIcon="iconDeleteRtlKey"
latin:parentStyle="functionalKeyStyle"
latin:isRepeatable="true" />
- <switch>
- <!-- When this qwerty keyboard has no voice key but voice key is enabled, then
- symbol keyboard will have mic key. That means we should use "?123mic" key
- here. -->
- <case
- latin:voiceKeyEnabled="true"
- latin:hasVoiceKey="false"
- >
- <key-style
- latin:styleName="toSymbolKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_keyboard_123_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_123_mic"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- <default>
- <key-style
- latin:styleName="toSymbolKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyLabel="@string/label_to_symbol_key"
- latin:parentStyle="functionalKeyStyle" />
- </default>
- </switch>
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="@drawable/sym_keyboard_settings_holo"
- latin:iconPreview="@drawable/sym_keyboard_settings_holo"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space"
- latin:keyIcon="@drawable/sym_keyboard_space_holo"
- latin:iconPreview="@drawable/sym_keyboard_space_holo"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="tabKeyStyle"
- latin:code="@integer/key_tab"
- latin:keyIcon="@drawable/sym_keyboard_tab_holo"
- latin:iconPreview="@drawable/sym_keyboard_tab_holo"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
- latin:keyIcon="@drawable/sym_keyboard_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:parentStyle="settingsPopupStyle" />
- <!-- Note: This key style is not for functional tab key. This is used for the tab key
- which is laid out as normal letter key. -->
- <key-style
- latin:styleName="nonSpecialBackgroundTabKeyStyle"
- latin:code="@integer/key_tab"
- latin:keyIcon="@drawable/sym_keyboard_tab_holo"
- latin:iconPreview="@drawable/sym_keyboard_tab_holo" />
</case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:code="@integer/key_shift"
- latin:keyIcon="@drawable/sym_bkeyboard_shift"
- latin:shiftedIcon="@drawable/sym_bkeyboard_shift_locked"
- latin:iconPreview="@drawable/sym_keyboard_feedback_shift"
- latin:parentStyle="functionalKeyStyle"
- latin:isSticky="true" />
+ <default>
<key-style
latin:styleName="deleteKeyStyle"
latin:code="@integer/key_delete"
- latin:keyIcon="@drawable/sym_bkeyboard_delete"
- latin:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ latin:keyIcon="iconDeleteKey"
latin:parentStyle="functionalKeyStyle"
latin:isRepeatable="true" />
- <switch>
- <!-- When this qwerty keyboard has no voice key but voice key is enabled, then
- symbol keyboard will have mic key. That means we should use "?123mic" key
- here. -->
- <case
- latin:voiceKeyEnabled="true"
- latin:hasVoiceKey="false"
- >
- <key-style
- latin:styleName="toSymbolKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_bkeyboard_123_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_123_mic"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- <default>
- <key-style
- latin:styleName="toSymbolKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyLabel="@string/label_to_symbol_key"
- latin:parentStyle="functionalKeyStyle" />
- </default>
- </switch>
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="@integer/key_settings"
- latin:keyIcon="@drawable/sym_bkeyboard_settings"
- latin:iconPreview="@drawable/sym_keyboard_settings_holo"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="@integer/key_space"
- latin:keyIcon="@drawable/sym_bkeyboard_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="tabKeyStyle"
- latin:code="@integer/key_tab"
- latin:keyIcon="@drawable/sym_bkeyboard_tab"
- latin:iconPreview="@drawable/sym_keyboard_feedback_tab"
- latin:parentStyle="functionalKeyStyle" />
- <key-style
- latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
- latin:keyIcon="@drawable/sym_bkeyboard_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:parentStyle="settingsPopupStyle" />
- <!-- Note: This key style is not for functional tab key. This is used for the tab key
- which is laid out as normal letter key. -->
- <key-style
- latin:styleName="nonSpecialBackgroundTabKeyStyle"
- latin:code="@integer/key_tab"
- latin:keyIcon="@drawable/sym_bkeyboard_tab"
- latin:iconPreview="@drawable/sym_keyboard_feedback_tab" />
- </case>
+ </default>
</switch>
<!-- Return key style -->
<switch>
@@ -245,52 +118,77 @@
<case
latin:imeAction="actionSearch"
>
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_keyboard_search"
- latin:iconPreview="@drawable/sym_keyboard_feedback_search"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_bkeyboard_search"
- latin:iconPreview="@drawable/sym_keyboard_feedback_search"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- </switch>
+ <key-style
+ latin:styleName="returnKeyStyle"
+ latin:code="@integer/key_return"
+ latin:keyIcon="iconSearchKey"
+ latin:parentStyle="functionalKeyStyle" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="returnKeyStyle"
+ latin:code="@integer/key_return"
+ latin:keyIcon="iconReturnKey"
+ latin:parentStyle="functionalKeyStyle" />
+ </default>
+ </switch>
+ <key-style
+ latin:styleName="spaceKeyStyle"
+ latin:code="@integer/key_space"
+ latin:keyIconPreview="iconPreviewSpaceKey"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="smileyKeyStyle"
+ latin:keyLabel=":-)"
+ latin:keyOutputText=":-) "
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_smiley"
+ latin:maxPopupKeyboardColumn="5"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="shortcutKeyStyle"
+ latin:code="@integer/key_shortcut"
+ latin:keyIcon="iconShortcutKey"
+ latin:keyIconPreview="iconPreviewShortcutKey"
+ latin:parentStyle="settingsPopupStyle" />
+ <key-style
+ latin:styleName="settingsKeyStyle"
+ latin:code="@integer/key_settings"
+ latin:keyIcon="iconSettingsKey"
+ latin:keyIconPreview="iconPreviewSettingsKey"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="tabKeyStyle"
+ latin:code="@integer/key_tab"
+ latin:keyIcon="iconTabKey"
+ latin:keyIconPreview="iconPreviewTabKey"
+ latin:parentStyle="functionalKeyStyle" />
+ <!-- Note: This key style is not for functional tab key. This is used for the tab key which is
+ laid out as normal letter key. -->
+ <key-style
+ latin:styleName="nonSpecialBackgroundTabKeyStyle"
+ latin:code="@integer/key_tab"
+ latin:keyIcon="iconTabKey"
+ latin:keyIconPreview="iconPreviewTabKey" />
+ <switch>
+ <!-- When this qwerty keyboard has no voice key but voice key is enabled, then symbol
+ keyboard will have mic key. That means we should use "?123mic" key here. -->
+ <case
+ latin:voiceKeyEnabled="true"
+ latin:hasVoiceKey="false"
+ >
+ <key-style
+ latin:styleName="toSymbolKeyStyle"
+ latin:code="@integer/key_switch_alpha_symbol"
+ latin:keyIcon="iconToSymbolKeyWithShortcut"
+ latin:parentStyle="functionalKeyStyle" />
</case>
<default>
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_keyboard_return_holo"
- latin:iconPreview="@drawable/sym_keyboard_return_holo"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="returnKeyStyle"
- latin:code="@integer/key_return"
- latin:keyIcon="@drawable/sym_bkeyboard_return"
- latin:iconPreview="@drawable/sym_keyboard_feedback_return"
- latin:parentStyle="functionalKeyStyle" />
- </case>
- </switch>
+ <key-style
+ latin:styleName="toSymbolKeyStyle"
+ latin:code="@integer/key_switch_alpha_symbol"
+ latin:keyLabel="@string/label_to_symbol_key"
+ latin:parentStyle="functionalKeyStyle" />
</default>
</switch>
<key-style
@@ -304,14 +202,6 @@
latin:keyLabel="@string/label_alt_key"
latin:parentStyle="functionalKeyStyle"
latin:isSticky="true" />
- <key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_smiley"
- latin:maxPopupKeyboardColumn="5"
- latin:parentStyle="functionalKeyStyle" />
<switch>
<case
latin:passwordInput="true"
diff --git a/java/res/xml/kbd_number.xml b/java/res/xml/kbd_number.xml
index 3c8384604..4d7b6d9a9 100644
--- a/java/res/xml/kbd_number.xml
+++ b/java/res/xml/kbd_number.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="26.67%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -67,7 +60,7 @@
latin:keyStyle="num9KeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -79,52 +72,62 @@
<Spacer />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
</case>
+ <!-- latin:passwordInput="false" -->
<default>
<Row
latin:rowEdgeFlags="top"
>
<Key
latin:keyLabel="1"
+ latin:keyStyle="numKeyStyle"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="2" />
+ latin:keyLabel="2"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="3" />
+ latin:keyLabel="3"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyLabel="-"
- latin:keyStyle="functionalKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
latin:keyLabel="4"
+ latin:keyStyle="numKeyStyle"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="5" />
+ latin:keyLabel="5"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="6" />
+ latin:keyLabel="6"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyLabel=","
- latin:keyStyle="functionalKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
latin:keyLabel="7"
+ latin:keyStyle="numKeyStyle"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="8" />
+ latin:keyLabel="8"
+ latin:keyStyle="numKeyStyle"/>
<Key
- latin:keyLabel="9" />
+ latin:keyLabel="9"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -134,12 +137,14 @@
latin:keyStyle="numSpaceKeyStyle"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="0" />
+ latin:keyLabel="0"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel="." />
+ latin:keyLabel="."
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
</default>
diff --git a/java/res/xml/kbd_numkey_styles.xml b/java/res/xml/kbd_numkey_styles.xml
index 7439d6397..657bfbcbf 100644
--- a/java/res/xml/kbd_numkey_styles.xml
+++ b/java/res/xml/kbd_numkey_styles.xml
@@ -21,130 +21,87 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <switch>
- <case
- latin:colorScheme="white"
- >
- <key-style
- latin:styleName="num0KeyStyle"
- latin:code="48"
- latin:keyIcon="@drawable/sym_keyboard_num0" />
- <key-style
- latin:styleName="num1KeyStyle"
- latin:code="49"
- latin:keyIcon="@drawable/sym_keyboard_num1" />
- <key-style
- latin:styleName="num2KeyStyle"
- latin:code="50"
- latin:keyIcon="@drawable/sym_keyboard_num2" />
- <key-style
- latin:styleName="num3KeyStyle"
- latin:code="51"
- latin:keyIcon="@drawable/sym_keyboard_num3" />
- <key-style
- latin:styleName="num4KeyStyle"
- latin:code="52"
- latin:keyIcon="@drawable/sym_keyboard_num4" />
- <key-style
- latin:styleName="num5KeyStyle"
- latin:code="53"
- latin:keyIcon="@drawable/sym_keyboard_num5" />
- <key-style
- latin:styleName="num6KeyStyle"
- latin:code="54"
- latin:keyIcon="@drawable/sym_keyboard_num6" />
- <key-style
- latin:styleName="num7KeyStyle"
- latin:code="55"
- latin:keyIcon="@drawable/sym_keyboard_num7" />
- <key-style
- latin:styleName="num8KeyStyle"
- latin:code="56"
- latin:keyIcon="@drawable/sym_keyboard_num8" />
- <key-style
- latin:styleName="num9KeyStyle"
- latin:code="57"
- latin:keyIcon="@drawable/sym_keyboard_num9" />
- <key-style
- latin:styleName="numStarKeyStyle"
- latin:code="42"
- latin:keyIcon="@drawable/sym_keyboard_numstar" />
- <key-style
- latin:styleName="numPoundKeyStyle"
- latin:code="35"
- latin:keyIcon="@drawable/sym_keyboard_numpound" />
- <key-style
- latin:styleName="numAltKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_keyboard_numsymbol_holo"
- latin:iconPreview="@drawable/sym_keyboard_numsymbol_holo" />
- <key-style
- latin:styleName="numSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:keyIcon="@drawable/sym_keyboard_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- </case>
- <case
- latin:colorScheme="black"
- >
- <key-style
- latin:styleName="num0KeyStyle"
- latin:code="48"
- latin:keyIcon="@drawable/sym_bkeyboard_num0" />
- <key-style
- latin:styleName="num1KeyStyle"
- latin:code="49"
- latin:keyIcon="@drawable/sym_bkeyboard_num1" />
- <key-style
- latin:styleName="num2KeyStyle"
- latin:code="50"
- latin:keyIcon="@drawable/sym_bkeyboard_num2" />
- <key-style
- latin:styleName="num3KeyStyle"
- latin:code="51"
- latin:keyIcon="@drawable/sym_bkeyboard_num3" />
- <key-style
- latin:styleName="num4KeyStyle"
- latin:code="52"
- latin:keyIcon="@drawable/sym_bkeyboard_num4" />
- <key-style
- latin:styleName="num5KeyStyle"
- latin:code="53"
- latin:keyIcon="@drawable/sym_bkeyboard_num5" />
- <key-style
- latin:styleName="num6KeyStyle"
- latin:code="54"
- latin:keyIcon="@drawable/sym_bkeyboard_num6" />
- <key-style
- latin:styleName="num7KeyStyle"
- latin:code="55"
- latin:keyIcon="@drawable/sym_bkeyboard_num7" />
- <key-style
- latin:styleName="num8KeyStyle"
- latin:code="56"
- latin:keyIcon="@drawable/sym_bkeyboard_num8" />
- <key-style
- latin:styleName="num9KeyStyle"
- latin:code="57"
- latin:keyIcon="@drawable/sym_bkeyboard_num9" />
- <key-style
- latin:styleName="numStarKeyStyle"
- latin:code="42"
- latin:keyIcon="@drawable/sym_bkeyboard_numstar" />
- <key-style
- latin:styleName="numPoundKeyStyle"
- latin:code="35"
- latin:keyIcon="@drawable/sym_bkeyboard_numpound" />
- <key-style
- latin:styleName="numAltKeyStyle"
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_bkeyboard_numalt"
- latin:iconPreview="@drawable/sym_keyboard_feedback_numalt" />
- <key-style
- latin:styleName="numSpaceKeyStyle"
- latin:code="@integer/key_space"
- latin:keyIcon="@drawable/sym_bkeyboard_space"
- latin:iconPreview="@drawable/sym_keyboard_feedback_space" />
- </case>
- </switch>
+ <key-style
+ latin:styleName="numKeyStyle"
+ latin:keyLabelOption="largeLetter|followKeyLetterRatio" />
+ <key-style
+ latin:styleName="numModeKeyStyle"
+ latin:keyLabelOption="fontNormal|followKeyLetterRatio" />
+ <key-style
+ latin:styleName="numFunctionalKeyStyle"
+ latin:keyLabelOption="largeLetter|followKeyLetterRatio"
+ latin:parentStyle="functionalKeyStyle" />
+ <key-style
+ latin:styleName="numberKeyStyle"
+ latin:keyLabelOption="alignLeftOfCenter|hasHintLabel"
+ latin:parentStyle="numKeyStyle" />
+ <key-style
+ latin:styleName="num0KeyStyle"
+ latin:code="48"
+ latin:keyLabel="0 +"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num1KeyStyle"
+ latin:keyLabel="1"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num2KeyStyle"
+ latin:keyLabel="2"
+ latin:keyHintLabel="ABC"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num3KeyStyle"
+ latin:keyLabel="3"
+ latin:keyHintLabel="DEF"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num4KeyStyle"
+ latin:keyLabel="4"
+ latin:keyHintLabel="GHI"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num5KeyStyle"
+ latin:keyLabel="5"
+ latin:keyHintLabel="JKL"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num6KeyStyle"
+ latin:keyLabel="6"
+ latin:keyHintLabel="MNO"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num7KeyStyle"
+ latin:keyLabel="7"
+ latin:keyHintLabel="PQRS"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num8KeyStyle"
+ latin:keyLabel="8"
+ latin:keyHintLabel="TUV"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="num9KeyStyle"
+ latin:keyLabel="9"
+ latin:keyHintLabel="WXYZ"
+ latin:parentStyle="numberKeyStyle" />
+ <key-style
+ latin:styleName="numStarKeyStyle"
+ latin:code="42"
+ latin:keyLabel="\uff0a"
+ latin:parentStyle="numKeyStyle" />
+ <key-style
+ latin:styleName="numSwitchToAltKeyStyle"
+ 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_switch_alpha_symbol"
+ latin:keyLabel="@string/label_to_phone_numeric_key"
+ latin:parentStyle="numModeKeyStyle" />
+ <key-style
+ latin:styleName="numSpaceKeyStyle"
+ latin:code="@integer/key_space"
+ latin:keyIcon="iconSpaceKey"
+ latin:keyIconPreview="iconPreviewSpaceKey" />
</merge>
diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml
index 7af8d07b4..c6508fb03 100644
--- a/java/res/xml/kbd_phone.xml
+++ b/java/res/xml/kbd_phone.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="26.67%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -45,8 +38,8 @@
latin:keyStyle="num3KeyStyle" />
<Key
latin:keyLabel="-"
- latin:keyStyle="functionalKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -59,8 +52,8 @@
latin:keyStyle="num6KeyStyle" />
<Key
latin:keyLabel="."
- latin:keyStyle="functionalKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -73,14 +66,14 @@
latin:keyStyle="num9KeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
latin:rowEdgeFlags="bottom"
>
<Key
- latin:keyStyle="numAltKeyStyle"
+ latin:keyStyle="numSwitchToAltKeyStyle"
latin:keyEdgeFlags="left" />
<Key
latin:keyStyle="num0KeyStyle" />
@@ -88,7 +81,7 @@
latin:keyStyle="numSpaceKeyStyle" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
</Keyboard>
diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml
index 4b6319ef7..5d9912229 100644
--- a/java/res/xml/kbd_phone_symbols.xml
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="26.67%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -38,15 +31,18 @@
>
<Key
latin:keyLabel="("
+ latin:keyStyle="numKeyStyle"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="/" />
+ latin:keyLabel="/"
+ latin:keyStyle="numKeyStyle" />
<Key
- latin:keyLabel=")" />
+ latin:keyLabel=")"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyLabel="-"
- latin:keyStyle="functionalKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -57,13 +53,15 @@
has changed. -->
<Key
latin:code="44"
- latin:keyLabel="Pause" />
+ latin:keyLabel="@string/label_pause_key"
+ latin:keyLabelOption="followKeyHintLabelRatio" />
<Key
- latin:keyLabel="," />
+ latin:keyLabel=","
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyLabel="."
- latin:keyStyle="functionalKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyStyle="numFunctionalKeyStyle"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -73,28 +71,30 @@
<!-- Wait is a semicolon. -->
<Key
latin:code="59"
- latin:keyLabel="Wait" />
+ latin:keyLabel="@string/label_wait_key"
+ latin:keyLabelOption="followKeyHintLabelRatio" />
<Key
- latin:keyStyle="numPoundKeyStyle" />
+ latin:keyLabel="#"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
latin:rowEdgeFlags="bottom"
>
<Key
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyLabel="@string/label_to_numeric_key"
+ latin:keyStyle="numSwitchToNumericKeyStyle"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="+" />
+ latin:keyLabel="+"
+ latin:keyStyle="numKeyStyle" />
<Key
latin:keyStyle="numSpaceKeyStyle" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
</Keyboard>
diff --git a/java/res/xml/kbd_popup_template.xml b/java/res/xml/kbd_popup_template.xml
index 9ee27493d..79db081a1 100644
--- a/java/res/xml/kbd_popup_template.xml
+++ b/java/res/xml/kbd_popup_template.xml
@@ -20,7 +20,7 @@
<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
+ latin:horizontalGap="@fraction/key_horizontal_gap"
latin:verticalGap="0px"
latin:rowHeight="@dimen/popup_key_height"
>
diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml
index 92d92f0e6..40917b921 100644
--- a/java/res/xml/kbd_qwerty.xml
+++ b/java/res/xml/kbd_qwerty.xml
@@ -20,15 +20,8 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
- latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="en_GB,en_US"
>
<include
- latin:keyboardLayout="@xml/kbd_qwerty_rows" />
+ latin:keyboardLayout="@xml/kbd_rows_qwerty" />
</Keyboard>
diff --git a/java/res/xml/kbd_qwerty_f1.xml b/java/res/xml/kbd_qwerty_f1.xml
index e89d02d91..51b9800e0 100644
--- a/java/res/xml/kbd_qwerty_f1.xml
+++ b/java/res/xml/kbd_qwerty_f1.xml
@@ -23,39 +23,92 @@
>
<switch>
<case
- latin:mode="url"
+ latin:hasSettingsKey="true"
>
- <Key
- latin:keyLabel="/"
- latin:keyStyle="settingsPopupStyle" />
- </case>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="\@"
- latin:keyStyle="settingsPopupStyle" />
- </case>
- <default>
<switch>
<case
- latin:hasVoiceKey="true"
+ latin:mode="url"
>
<Key
- latin:keyStyle="micKeyStyle" />
+ latin:keyLabel="/"
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="settingsPopupStyle" />
</case>
- <!-- latin:hasVoiceKey="false" -->
<case
- latin:webInput="true"
+ latin:mode="email"
>
<Key
- latin:keyLabel="."
+ latin:keyLabel="\@"
+ latin:keyWidth="9.2%p"
latin:keyStyle="settingsPopupStyle" />
</case>
<default>
+ <switch>
+ <case
+ latin:hasVoiceKey="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="9.2%p" />
+ </case>
+ <!-- latin:hasVoiceKey="false" -->
+ <case
+ latin:navigateAction="true"
+ >
+ <Key
+ latin:keyLabel="."
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="settingsPopupStyle" />
+ </case>
+ <default>
+ <Key
+ latin:keyLabel=","
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="settingsPopupStyle" />
+ </default>
+ </switch>
+ </default>
+ </switch>
+ </case>
+ <!-- hasSettingsKey="false" -->
+ <default>
+ <switch>
+ <case
+ latin:mode="url"
+ >
+ <Key
+ latin:keyLabel="/"
+ latin:keyStyle="settingsPopupStyle" />
+ </case>
+ <case
+ latin:mode="email"
+ >
<Key
- latin:keyLabel=","
+ latin:keyLabel="\@"
latin:keyStyle="settingsPopupStyle" />
+ </case>
+ <default>
+ <switch>
+ <case
+ latin:hasVoiceKey="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle" />
+ </case>
+ <!-- latin:hasVoiceKey="false" -->
+ <case
+ latin:navigateAction="true"
+ >
+ <Key
+ latin:keyLabel="."
+ latin:keyStyle="settingsPopupStyle" />
+ </case>
+ <default>
+ <Key
+ latin:keyLabel=","
+ latin:keyStyle="settingsPopupStyle" />
+ </default>
+ </switch>
</default>
</switch>
</default>
diff --git a/java/res/xml/kbd_qwerty_row1.xml b/java/res/xml/kbd_qwerty_row1.xml
index 9ee164313..cfd2efd2a 100644
--- a/java/res/xml/kbd_qwerty_row1.xml
+++ b/java/res/xml/kbd_qwerty_row1.xml
@@ -27,46 +27,46 @@
>
<Key
latin:keyLabel="q"
- latin:keyHintIcon="@drawable/key_hint_num1"
+ latin:keyHintLabel="1"
latin:popupCharacters="@string/alternates_for_q"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="w"
- latin:keyHintIcon="@drawable/key_hint_num2"
+ latin:keyHintLabel="2"
latin:popupCharacters="@string/alternates_for_w" />
<Key
latin:keyLabel="e"
- latin:keyHintIcon="@drawable/key_hint_num3"
+ latin:keyHintLabel="3"
latin:popupCharacters="@string/alternates_for_e" />
<Key
latin:keyLabel="r"
- latin:keyHintIcon="@drawable/key_hint_num4"
+ latin:keyHintLabel="4"
latin:popupCharacters="@string/alternates_for_r" />
<Key
latin:keyLabel="t"
- latin:keyHintIcon="@drawable/key_hint_num5"
+ latin:keyHintLabel="5"
latin:popupCharacters="@string/alternates_for_t" />
<Key
latin:keyLabel="y"
- latin:keyHintIcon="@drawable/key_hint_num6"
+ latin:keyHintLabel="6"
latin:popupCharacters="@string/alternates_for_y" />
<Key
latin:keyLabel="u"
- latin:keyHintIcon="@drawable/key_hint_num7"
+ latin:keyHintLabel="7"
latin:popupCharacters="@string/alternates_for_u" />
<Key
latin:keyLabel="i"
- latin:keyHintIcon="@drawable/key_hint_num8"
+ latin:keyHintLabel="8"
latin:popupCharacters="@string/alternates_for_i" />
<Key
latin:keyLabel="o"
- latin:keyHintIcon="@drawable/key_hint_num9"
+ latin:keyHintLabel="9"
latin:popupCharacters="@string/alternates_for_o" />
<Key
latin:keyLabel="p"
- latin:keyHintIcon="@drawable/key_hint_num0"
+ latin:keyHintLabel="0"
latin:popupCharacters="@string/alternates_for_p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml/kbd_qwerty_row2.xml b/java/res/xml/kbd_qwerty_row2.xml
index cf9b3049b..57bbad75a 100644
--- a/java/res/xml/kbd_qwerty_row2.xml
+++ b/java/res/xml/kbd_qwerty_row2.xml
@@ -26,8 +26,8 @@
>
<Key
latin:keyLabel="a"
- latin:keyXPos="5%p"
latin:popupCharacters="@string/alternates_for_a"
+ latin:keyXPos="5%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="s"
@@ -50,7 +50,7 @@
<Key
latin:keyLabel="l"
latin:popupCharacters="@string/alternates_for_l"
- latin:keyWidth="0%p"
latin:keyEdgeFlags="right" />
+ <!-- Here is 5%p space -->
</Row>
</merge>
diff --git a/java/res/xml/kbd_qwerty_row3.xml b/java/res/xml/kbd_qwerty_row3.xml
index ffbf06133..98f0404c0 100644
--- a/java/res/xml/kbd_qwerty_row3.xml
+++ b/java/res/xml/kbd_qwerty_row3.xml
@@ -27,6 +27,7 @@
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="z"
@@ -48,7 +49,8 @@
latin:keyLabel="m" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillBoth"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
</merge>
diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/kbd_qwerty_row4.xml
index 67a1a76a1..ff2ef3acd 100644
--- a/java/res/xml/kbd_qwerty_row4.xml
+++ b/java/res/xml/kbd_qwerty_row4.xml
@@ -27,104 +27,89 @@
>
<switch>
<case
- latin:hasSettingsKey="false"
+ latin:hasSettingsKey="true"
>
<Key
latin:keyStyle="toSymbolKeyStyle"
- latin:keyWidth="20%p"
+ latin:keyWidth="13.75%p"
latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyStyle="settingsKeyStyle"
+ latin:keyWidth="9.2%p" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f1" />
- <switch>
- <case
- latin:webInput="true"
- >
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="20%p" />
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="20%p" />
- </case>
- <default>
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="40%p" />
- </default>
- </switch>
<Key
- latin:keyLabel="."
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_punctuation"
- latin:maxPopupKeyboardColumn="7"
- latin:keyStyle="functionalKeyStyle" />
+ latin:keyStyle="spaceKeyStyle"
+ latin:keyWidth="35.83%p" />
<switch>
<case
- latin:mode="im"
+ latin:navigateAction="true"
>
<Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+ latin:keyWidth="9.2%p"
+ latin:maxPopupKeyboardColumn="8" />
</case>
<default>
<Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
+ latin:keyLabel="."
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_punctuation"
+ latin:keyWidth="9.2%p"
+ latin:maxPopupKeyboardColumn="7"
+ latin:keyStyle="functionalKeyStyle" />
</default>
</switch>
</case>
- <case
- latin:hasSettingsKey="true"
- >
+ <!-- latin:hasSettingsKey="false" -->
+ <default>
<Key
latin:keyStyle="toSymbolKeyStyle"
latin:keyWidth="15%p"
latin:keyEdgeFlags="left" />
- <Key
- latin:keyStyle="settingsKeyStyle" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f1" />
- <switch>
- <case
- latin:webInput="true"
- >
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p" />
- <Key
- latin:keyStyle="tabKeyStyle" />
- </case>
- <default>
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p" />
- </default>
- </switch>
<Key
- latin:keyLabel="."
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_punctuation"
- latin:maxPopupKeyboardColumn="7"
- latin:keyStyle="functionalKeyStyle" />
+ latin:keyStyle="spaceKeyStyle"
+ latin:keyWidth="50%p" />
<switch>
<case
- latin:mode="im"
+ latin:navigateAction="true"
>
<Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+ latin:maxPopupKeyboardColumn="8" />
</case>
<default>
<Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
+ latin:keyLabel="."
+ latin:keyLabelOption="hasPopupHint"
+ latin:popupCharacters="@string/alternates_for_punctuation"
+ latin:maxPopupKeyboardColumn="7"
+ latin:keyStyle="functionalKeyStyle" />
</default>
</switch>
+ </default>
+ </switch>
+ <switch>
+ <case
+ latin:mode="im"
+ >
+ <Key
+ latin:keyStyle="smileyKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
</case>
+ <default>
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
+ </default>
</switch>
</Row>
</merge>
diff --git a/java/res/xml/kbd_rows_arabic.xml b/java/res/xml/kbd_rows_arabic.xml
new file mode 100644
index 000000000..a548775a4
--- /dev/null
+++ b/java/res/xml/kbd_rows_arabic.xml
@@ -0,0 +1,122 @@
+<?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.
+*/
+-->
+
+<!-- This file for Arabic layout is an alpha version. It allows to enter -->
+<!-- some right-to-left text, but it has gone through no study whatsoever, -->
+<!-- and needs to be run through UX. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/kbd_key_styles" />
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyLabel="ض"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ص" />
+ <Key
+ latin:keyLabel="ق" />
+ <Key
+ latin:keyLabel="ف"
+ latin:popupCharacters="ڤ" />
+ <Key
+ latin:keyLabel="غ" />
+ <Key
+ latin:keyLabel="ع" />
+ <Key
+ latin:keyLabel="ه"
+ latin:popupCharacters="هـ" />
+ <Key
+ latin:keyLabel="خ" />
+ <Key
+ latin:keyLabel="ح" />
+ <Key
+ latin:keyLabel="ج"
+ latin:popupCharacters="چ"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyLabel="ش"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="س" />
+ <Key
+ latin:keyLabel="ي"
+ latin:popupCharacters="ى,ئ" />
+ <Key
+ latin:keyLabel="ب"
+ latin:popupCharacters="پ" />
+ <Key
+ latin:keyLabel="ل"
+ latin:popupCharacters="لا" />
+ <Key
+ latin:keyLabel="ا"
+ latin:popupCharacters="أ,إ,آ,ء" />
+ <Key
+ latin:keyLabel="ت" />
+ <Key
+ latin:keyLabel="ن" />
+ <Key
+ latin:keyLabel="م" />
+ <Key
+ latin:keyLabel="ك"
+ latin:popupCharacters="گ"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="9.7%p"
+ >
+ <Key
+ latin:keyLabel="ظ"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="ط" />
+ <Key
+ latin:keyLabel="ذ" />
+ <Key
+ latin:keyLabel="د" />
+ <Key
+ latin:keyLabel="ز"
+ latin:popupCharacters="ژ" />
+ <Key
+ latin:keyLabel="ر" />
+ <Key
+ latin:keyLabel="و"
+ latin:popupCharacters="ؤ" />
+ <Key
+ latin:keyLabel="ة" />
+ <Key
+ latin:keyLabel="ث" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:visualInsetsLeft="1%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml/kbd_azerty_rows.xml b/java/res/xml/kbd_rows_azerty.xml
index 4a766987d..96efb6646 100644
--- a/java/res/xml/kbd_azerty_rows.xml
+++ b/java/res/xml/kbd_rows_azerty.xml
@@ -29,46 +29,46 @@
>
<Key
latin:keyLabel="a"
- latin:keyHintIcon="@drawable/key_hint_num1"
+ latin:keyHintLabel="1"
latin:popupCharacters="@string/alternates_for_a"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="z"
- latin:keyHintIcon="@drawable/key_hint_num2"
+ latin:keyHintLabel="2"
latin:popupCharacters="@string/alternates_for_z" />
<Key
latin:keyLabel="e"
- latin:keyHintIcon="@drawable/key_hint_num3"
+ latin:keyHintLabel="3"
latin:popupCharacters="@string/alternates_for_e" />
<Key
latin:keyLabel="r"
- latin:keyHintIcon="@drawable/key_hint_num4"
+ latin:keyHintLabel="4"
latin:popupCharacters="@string/alternates_for_r" />
<Key
latin:keyLabel="t"
- latin:keyHintIcon="@drawable/key_hint_num5"
+ latin:keyHintLabel="5"
latin:popupCharacters="@string/alternates_for_t" />
<Key
latin:keyLabel="y"
- latin:keyHintIcon="@drawable/key_hint_num6"
+ latin:keyHintLabel="6"
latin:popupCharacters="@string/alternates_for_y" />
<Key
latin:keyLabel="u"
- latin:keyHintIcon="@drawable/key_hint_num7"
+ latin:keyHintLabel="7"
latin:popupCharacters="@string/alternates_for_u" />
<Key
latin:keyLabel="i"
- latin:keyHintIcon="@drawable/key_hint_num8"
+ latin:keyHintLabel="8"
latin:popupCharacters="@string/alternates_for_i" />
<Key
latin:keyLabel="o"
- latin:keyHintIcon="@drawable/key_hint_num9"
+ latin:keyHintLabel="9"
latin:popupCharacters="@string/alternates_for_o" />
<Key
latin:keyLabel="p"
- latin:keyHintIcon="@drawable/key_hint_num0"
+ latin:keyHintLabel="0"
latin:popupCharacters="@string/alternates_for_p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -101,7 +101,7 @@
latin:popupCharacters="@string/alternates_for_l" />
<Key
latin:keyLabel="m"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -110,6 +110,7 @@
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="w"
@@ -129,10 +130,12 @@
latin:keyLabel="n"
latin:popupCharacters="@string/alternates_for_n" />
<Key
- latin:keyLabel="\'" />
+ latin:keyLabel="\'"
+ latin:popupCharacters="‘,’,‚,‛" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_rows_hebrew.xml b/java/res/xml/kbd_rows_hebrew.xml
new file mode 100644
index 000000000..c3c8f7d3e
--- /dev/null
+++ b/java/res/xml/kbd_rows_hebrew.xml
@@ -0,0 +1,111 @@
+<?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.
+*/
+-->
+
+<!-- This file for Hebrew layout is an alpha version. It allows to enter -->
+<!-- some right-to-left text, but it has gone through no study whatsoever, -->
+<!-- and needs to be run through UX. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/kbd_key_styles" />
+ <Row
+ latin:keyWidth="10%p"
+ latin:rowEdgeFlags="top"
+ >
+ <Key
+ latin:keyLabel="ק"
+ latin:keyXPos="5%p"
+ latin:keyEdgeFlags="left" />
+ <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"
+ latin:visualInsetsLeft="1%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyLabel="ש"
+ latin:keyEdgeFlags="left" />
+ <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"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyLabel="ז"
+ latin:keyXPos="5%p"
+ latin:keyEdgeFlags="left" />
+ <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:keyEdgeFlags="right" />
+ <!-- Here is 5%p space -->
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml/kbd_qwerty_rows.xml b/java/res/xml/kbd_rows_qwerty.xml
index 6237712f6..6237712f6 100644
--- a/java/res/xml/kbd_qwerty_rows.xml
+++ b/java/res/xml/kbd_rows_qwerty.xml
diff --git a/java/res/xml/kbd_qwertz_rows.xml b/java/res/xml/kbd_rows_qwertz.xml
index 960b9f5ae..347ef60ad 100644
--- a/java/res/xml/kbd_qwertz_rows.xml
+++ b/java/res/xml/kbd_rows_qwertz.xml
@@ -29,46 +29,46 @@
>
<Key
latin:keyLabel="q"
- latin:keyHintIcon="@drawable/key_hint_num1"
+ latin:keyHintLabel="1"
latin:popupCharacters="@string/alternates_for_q"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="w"
- latin:keyHintIcon="@drawable/key_hint_num2"
+ latin:keyHintLabel="2"
latin:popupCharacters="@string/alternates_for_w" />
<Key
latin:keyLabel="e"
- latin:keyHintIcon="@drawable/key_hint_num3"
+ latin:keyHintLabel="3"
latin:popupCharacters="@string/alternates_for_e" />
<Key
latin:keyLabel="r"
- latin:keyHintIcon="@drawable/key_hint_num4"
+ latin:keyHintLabel="4"
latin:popupCharacters="@string/alternates_for_r" />
<Key
latin:keyLabel="t"
- latin:keyHintIcon="@drawable/key_hint_num5"
+ latin:keyHintLabel="5"
latin:popupCharacters="@string/alternates_for_t" />
<Key
latin:keyLabel="z"
- latin:keyHintIcon="@drawable/key_hint_num6"
+ latin:keyHintLabel="6"
latin:popupCharacters="@string/alternates_for_z" />
<Key
latin:keyLabel="u"
- latin:keyHintIcon="@drawable/key_hint_num7"
+ latin:keyHintLabel="7"
latin:popupCharacters="@string/alternates_for_u" />
<Key
latin:keyLabel="i"
- latin:keyHintIcon="@drawable/key_hint_num8"
+ latin:keyHintLabel="8"
latin:popupCharacters="@string/alternates_for_i" />
<Key
latin:keyLabel="o"
- latin:keyHintIcon="@drawable/key_hint_num9"
+ latin:keyHintLabel="9"
latin:popupCharacters="@string/alternates_for_o" />
<Key
latin:keyLabel="p"
- latin:keyHintIcon="@drawable/key_hint_num0"
+ latin:keyHintLabel="0"
latin:popupCharacters="@string/alternates_for_p"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<include
@@ -79,6 +79,7 @@
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="y"
@@ -100,7 +101,8 @@
latin:keyLabel="m" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_ru_rows.xml b/java/res/xml/kbd_rows_russian.xml
index 5d30221d9..2c10c3141 100644
--- a/java/res/xml/kbd_ru_rows.xml
+++ b/java/res/xml/kbd_rows_russian.xml
@@ -29,49 +29,49 @@
>
<Key
latin:keyLabel="й"
- latin:keyHintIcon="@drawable/key_hint_num1"
+ latin:keyHintLabel="1"
latin:popupCharacters="1"
latin:keyWidth="8.75%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="ц"
- latin:keyHintIcon="@drawable/key_hint_num2"
+ latin:keyHintLabel="2"
latin:popupCharacters="2" />
<Key
latin:keyLabel="у"
- latin:keyHintIcon="@drawable/key_hint_num3"
+ latin:keyHintLabel="3"
latin:popupCharacters="3" />
<Key
latin:keyLabel="к"
- latin:keyHintIcon="@drawable/key_hint_num4"
+ latin:keyHintLabel="4"
latin:popupCharacters="4" />
<Key
latin:keyLabel="е"
- latin:keyHintIcon="@drawable/key_hint_num5"
+ latin:keyHintLabel="5"
latin:popupCharacters="@string/alternates_for_cyrillic_e" />
<Key
latin:keyLabel="н"
- latin:keyHintIcon="@drawable/key_hint_num6"
+ latin:keyHintLabel="6"
latin:popupCharacters="6" />
<Key
latin:keyLabel="г"
- latin:keyHintIcon="@drawable/key_hint_num7"
+ latin:keyHintLabel="7"
latin:popupCharacters="7" />
<Key
latin:keyLabel="ш"
- latin:keyHintIcon="@drawable/key_hint_num8"
+ latin:keyHintLabel="8"
latin:popupCharacters="8" />
<Key
latin:keyLabel="щ"
- latin:keyHintIcon="@drawable/key_hint_num9"
+ latin:keyHintLabel="9"
latin:popupCharacters="9" />
<Key
latin:keyLabel="з"
- latin:keyHintIcon="@drawable/key_hint_num0"
+ latin:keyHintLabel="0"
latin:popupCharacters="0" />
<Key
latin:keyLabel="х"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -101,7 +101,7 @@
latin:keyLabel="ж" />
<Key
latin:keyLabel="э"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -132,7 +132,7 @@
latin:keyLabel="ю" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_qwerty_rows_scandinavia.xml b/java/res/xml/kbd_rows_scandinavian.xml
index be841dccd..3f2560128 100644
--- a/java/res/xml/kbd_qwerty_rows_scandinavia.xml
+++ b/java/res/xml/kbd_rows_scandinavian.xml
@@ -29,49 +29,49 @@
>
<Key
latin:keyLabel="q"
- latin:keyHintIcon="@drawable/key_hint_num1"
+ latin:keyHintLabel="1"
latin:popupCharacters="@string/alternates_for_q"
latin:keyWidth="8.75%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="w"
- latin:keyHintIcon="@drawable/key_hint_num2"
+ latin:keyHintLabel="2"
latin:popupCharacters="@string/alternates_for_w" />
<Key
latin:keyLabel="e"
- latin:keyHintIcon="@drawable/key_hint_num3"
+ latin:keyHintLabel="3"
latin:popupCharacters="@string/alternates_for_e" />
<Key
latin:keyLabel="r"
- latin:keyHintIcon="@drawable/key_hint_num4"
+ latin:keyHintLabel="4"
latin:popupCharacters="@string/alternates_for_r" />
<Key
latin:keyLabel="t"
- latin:keyHintIcon="@drawable/key_hint_num5"
+ latin:keyHintLabel="5"
latin:popupCharacters="@string/alternates_for_t" />
<Key
latin:keyLabel="y"
- latin:keyHintIcon="@drawable/key_hint_num6"
+ latin:keyHintLabel="6"
latin:popupCharacters="@string/alternates_for_y" />
<Key
latin:keyLabel="u"
- latin:keyHintIcon="@drawable/key_hint_num7"
+ latin:keyHintLabel="7"
latin:popupCharacters="@string/alternates_for_u" />
<Key
latin:keyLabel="i"
- latin:keyHintIcon="@drawable/key_hint_num8"
+ latin:keyHintLabel="8"
latin:popupCharacters="@string/alternates_for_i" />
<Key
latin:keyLabel="o"
- latin:keyHintIcon="@drawable/key_hint_num9"
+ latin:keyHintLabel="9"
latin:popupCharacters="@string/alternates_for_o" />
<Key
latin:keyLabel="p"
- latin:keyHintIcon="@drawable/key_hint_num0"
+ latin:keyHintLabel="0"
latin:popupCharacters="@string/alternates_for_p" />
<Key
latin:keyLabel="å"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -109,7 +109,7 @@
<Key
latin:keyLabel="@string/keylabel_for_scandinavia_row2_11"
latin:popupCharacters="@string/alternates_for_scandinavia_row2_11"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_sr_rows.xml b/java/res/xml/kbd_rows_serbian.xml
index 8239f24cb..2bed276d3 100644
--- a/java/res/xml/kbd_sr_rows.xml
+++ b/java/res/xml/kbd_rows_serbian.xml
@@ -29,48 +29,48 @@
>
<Key
latin:keyLabel="љ"
- latin:keyHintIcon="@drawable/key_hint_num1"
+ latin:keyHintLabel="1"
latin:popupCharacters="1"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="њ"
- latin:keyHintIcon="@drawable/key_hint_num2"
+ latin:keyHintLabel="2"
latin:popupCharacters="2" />
<Key
latin:keyLabel="е"
- latin:keyHintIcon="@drawable/key_hint_num3"
+ latin:keyHintLabel="3"
latin:popupCharacters="3" />
<Key
latin:keyLabel="р"
- latin:keyHintIcon="@drawable/key_hint_num4"
+ latin:keyHintLabel="4"
latin:popupCharacters="4" />
<Key
latin:keyLabel="т"
- latin:keyHintIcon="@drawable/key_hint_num5"
+ latin:keyHintLabel="5"
latin:popupCharacters="5" />
<Key
latin:keyLabel="з"
- latin:keyHintIcon="@drawable/key_hint_num6"
+ latin:keyHintLabel="6"
latin:popupCharacters="6" />
<Key
latin:keyLabel="у"
- latin:keyHintIcon="@drawable/key_hint_num7"
+ latin:keyHintLabel="7"
latin:popupCharacters="7" />
<Key
latin:keyLabel="и"
- latin:keyHintIcon="@drawable/key_hint_num8"
+ latin:keyHintLabel="8"
latin:popupCharacters="8" />
<Key
latin:keyLabel="о"
- latin:keyHintIcon="@drawable/key_hint_num9"
+ latin:keyHintLabel="9"
latin:popupCharacters="9" />
<Key
latin:keyLabel="п"
- latin:keyHintIcon="@drawable/key_hint_num0"
+ latin:keyHintLabel="0"
latin:popupCharacters="0" />
<Key
latin:keyLabel="ш"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -99,7 +99,7 @@
latin:keyLabel="ч" />
<Key
latin:keyLabel="ћ"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -128,7 +128,7 @@
latin:keyLabel="ж" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_rows_spanish.xml b/java/res/xml/kbd_rows_spanish.xml
new file mode 100644
index 000000000..c5ead10da
--- /dev/null
+++ b/java/res/xml/kbd_rows_spanish.xml
@@ -0,0 +1,64 @@
+<?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_qwerty_row1" />
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyLabel="a"
+ latin:popupCharacters="@string/alternates_for_a"
+ latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyLabel="s"
+ latin:popupCharacters="@string/alternates_for_s" />
+ <Key
+ latin:keyLabel="d"
+ latin:popupCharacters="@string/alternates_for_d" />
+ <Key
+ latin:keyLabel="f" />
+ <Key
+ latin:keyLabel="g"
+ latin:popupCharacters="@string/alternates_for_g" />
+ <Key
+ latin:keyLabel="h" />
+ <Key
+ latin:keyLabel="j" />
+ <Key
+ latin:keyLabel="k"
+ latin:popupCharacters="@string/alternates_for_k" />
+ <Key
+ latin:keyLabel="l"
+ latin:popupCharacters="@string/alternates_for_l" />
+ <Key
+ latin:keyLabel="ñ"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_row3" />
+ <include
+ latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index 3c9098da7..8e9124f74 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -64,7 +57,7 @@
<Key
latin:keyLabel="0"
latin:popupCharacters="ⁿ,∅"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -95,13 +88,14 @@
<Key
latin:keyLabel=")"
latin:popupCharacters="],},&gt;"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
latin:keyStyle="altKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="!"
@@ -126,7 +120,8 @@
latin:popupCharacters="¿" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
<include latin:keyboardLayout="@xml/kbd_symbols_row4" />
diff --git a/java/res/xml/kbd_symbols_f1.xml b/java/res/xml/kbd_symbols_f1.xml
index 0fb7136b9..da5b5fc8d 100644
--- a/java/res/xml/kbd_symbols_f1.xml
+++ b/java/res/xml/kbd_symbols_f1.xml
@@ -23,16 +23,41 @@
>
<switch>
<case
- latin:hasVoiceKey="true"
+ latin:hasSettingsKey="true"
>
- <Key
- latin:keyStyle="micKeyStyle" />
+ <switch>
+ <case
+ latin:hasVoiceKey="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="9.2%p" />
+ </case>
+ <!-- latin:hasVoiceKey="false" -->
+ <default>
+ <Key
+ latin:keyLabel=","
+ latin:keyWidth="9.2%p"
+ latin:keyStyle="settingsPopupStyle" />
+ </default>
+ </switch>
</case>
- <!-- latin:hasVoiceKey="false" -->
+ <!-- hasSettingsKey="false" -->
<default>
- <Key
- latin:keyLabel=","
- latin:keyStyle="settingsPopupStyle" />
+ <switch>
+ <case
+ latin:hasVoiceKey="true"
+ >
+ <Key
+ latin:keyStyle="shortcutKeyStyle" />
+ </case>
+ <!-- latin:hasVoiceKey="false" -->
+ <default>
+ <Key
+ latin:keyLabel=","
+ latin:keyStyle="settingsPopupStyle" />
+ </default>
+ </switch>
</default>
</switch>
</merge>
diff --git a/java/res/xml/kbd_symbols_row4.xml b/java/res/xml/kbd_symbols_row4.xml
index e92e58bcb..68b79e84d 100644
--- a/java/res/xml/kbd_symbols_row4.xml
+++ b/java/res/xml/kbd_symbols_row4.xml
@@ -27,77 +27,62 @@
>
<switch>
<case
- latin:hasSettingsKey="false"
+ latin:hasSettingsKey="true"
>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="20%p"
+ latin:keyWidth="13.75%p"
latin:keyEdgeFlags="left" />
+ <Key
+ latin:keyStyle="settingsKeyStyle"
+ latin:keyWidth="9.2%p" />
<include
- latin:keyboardLayout="@xml/kbd_symbols_f1" />
+ latin:keyboardLayout="@xml/kbd_qwerty_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="40%p" />
+ latin:keyWidth="35.83%p" />
<Key
latin:keyLabel="."
- latin:keyHintIcon="@drawable/hint_popup_holo"
+ latin:keyLabelOption="hasPopupHint"
latin:popupCharacters="@string/alternates_for_punctuation"
+ latin:keyWidth="9.2%p"
latin:maxPopupKeyboardColumn="7"
latin:keyStyle="functionalKeyStyle" />
- <switch>
- <case
- latin:mode="im"
- >
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </case>
- <default>
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </default>
- </switch>
</case>
- <case
- latin:hasSettingsKey="true"
- >
+ <!-- latin:hasSettingsKey="false" -->
+ <default>
<Key
latin:keyStyle="toAlphaKeyStyle"
latin:keyWidth="15%p"
latin:keyEdgeFlags="left" />
- <Key
- latin:keyStyle="settingsKeyStyle" />
<include
latin:keyboardLayout="@xml/kbd_symbols_f1" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p" />
+ latin:keyWidth="50%p" />
<Key
latin:keyLabel="."
- latin:keyHintIcon="@drawable/hint_popup_holo"
+ latin:keyLabelOption="hasPopupHint"
latin:popupCharacters="@string/alternates_for_punctuation"
latin:maxPopupKeyboardColumn="7"
latin:keyStyle="functionalKeyStyle" />
- <switch>
- <case
- latin:mode="im"
- >
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </case>
- <default>
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </default>
- </switch>
+ </default>
+ </switch>
+ <switch>
+ <case
+ latin:mode="im"
+ >
+ <Key
+ latin:keyStyle="smileyKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
</case>
+ <default>
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
+ </default>
</switch>
</Row>
</merge>
diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml
index 0f9ea3b77..f22d45aff 100644
--- a/java/res/xml/kbd_symbols_shift.xml
+++ b/java/res/xml/kbd_symbols_shift.xml
@@ -20,14 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardHeight="@dimen/keyboardHeight"
- latin:maxKeyboardHeight="50%p"
- latin:rowHeight="25%p"
latin:keyWidth="10%p"
- latin:horizontalGap="@dimen/key_horizontal_gap"
- latin:verticalGap="@dimen/key_bottom_gap"
- latin:popupKeyboardTemplate="@xml/kbd_popup_template"
- latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
>
<include
latin:keyboardLayout="@xml/kbd_key_styles" />
@@ -62,7 +55,7 @@
latin:keyLabel="{" />
<Key
latin:keyLabel="}"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
@@ -94,13 +87,14 @@
latin:keyLabel="[" />
<Key
latin:keyLabel="]"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
latin:keyEdgeFlags="right" />
</Row>
<Row>
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyStyle="nonPasswordSymbolKeyStyle"
@@ -125,7 +119,8 @@
latin:popupCharacters="≥,»,›" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="0%p"
+ latin:keyWidth="fillRight"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
<include latin:keyboardLayout="@xml/kbd_symbols_shift_row4" />
diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/kbd_symbols_shift_row4.xml
index 3ed76ea58..90a96e4bc 100644
--- a/java/res/xml/kbd_symbols_shift_row4.xml
+++ b/java/res/xml/kbd_symbols_shift_row4.xml
@@ -27,73 +27,61 @@
>
<switch>
<case
- latin:hasSettingsKey="false"
+ latin:hasSettingsKey="true"
>
<Key
latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="20%p"
+ latin:keyWidth="13.75%p"
latin:keyEdgeFlags="left" />
<Key
+ latin:keyStyle="settingsKeyStyle"
+ latin:keyWidth="9.2%p" />
+ <Key
latin:keyLabel="„"
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
+ latin:keyWidth="9.2%p"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="40%p" />
+ latin:keyWidth="35.83%p" />
<Key
latin:keyLabel="…"
+ latin:keyWidth="9.2%p"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
- <switch>
- <case
- latin:mode="im"
- >
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </case>
- <default>
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </default>
- </switch>
</case>
- <case
- latin:hasSettingsKey="true"
- >
+ <!-- latin:hasSettingsKey="false" -->
+ <default>
<Key
latin:keyStyle="toAlphaKeyStyle"
latin:keyWidth="15%p"
latin:keyEdgeFlags="left" />
<Key
- latin:keyStyle="settingsKeyStyle" />
- <Key
latin:keyLabel="„"
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p" />
+ latin:keyWidth="50%p" />
<Key
latin:keyLabel="…"
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
- <switch>
- <case
- latin:mode="im"
- >
- <Key
- latin:keyStyle="smileyKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </case>
- <default>
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="0%p"
- latin:keyEdgeFlags="right" />
- </default>
- </switch>
+ </default>
+ </switch>
+ <switch>
+ <case
+ latin:mode="im"
+ >
+ <Key
+ latin:keyStyle="smileyKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
</case>
+ <default>
+ <Key
+ latin:keyStyle="returnKeyStyle"
+ latin:keyWidth="fillRight"
+ latin:keyEdgeFlags="right" />
+ </default>
</switch>
</Row>
</merge>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 8dec7abec..7aaf57b47 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -20,10 +20,11 @@
<!-- The attributes in this XML file provide configuration information -->
<!-- for the Input Method Manager. -->
-<!-- Keyboard: en_US, en_GB, cs, da, de, es, es_US, fr, fr_CA, fr_CH, it, nb, nl, sr, sv -->
+<!-- Keyboard: en_US, en_GB, ar, cs, da, de, es, es_US, fi, fr, fr_CA, fr_CH, hr, hu, it, iw, nb, nl, pl, pt, ru, sr, sv, tr -->
<!-- Voice: af, cs, da, de, en, es, fr, it, ja, ko, nl, pl, pt, ru, tr, yue, zh, zu -->
<!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. -->
<!-- TODO: use <lang>_mic icon instead of a common mic icon. -->
+<!-- TODO: remove all comment outed voice subtypes -->
<!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default
subtype.-->
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
@@ -33,29 +34,37 @@
android:label="@string/subtype_mode_en_US_keyboard"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_en_voice"
- android:imeSubtypeLocale="en"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher"
+ />
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_en_voice" -->
+<!-- android:imeSubtypeLocale="en" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_en_GB_keyboard"
android:imeSubtypeLocale="en_GB"
android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher"
/>
+ <!-- The file for Arabic layout is an alpha version. It needs to be run through UX. -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
- android:label="@string/subtype_mode_cs_keyboard"
- android:imeSubtypeLocale="cs"
+ android:label="@string/subtype_mode_ar_keyboard"
+ android:imeSubtypeLocale="ar"
android:imeSubtypeMode="keyboard"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_cs_voice"
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_cs_keyboard"
android:imeSubtypeLocale="cs"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
+ android:imeSubtypeMode="keyboard"
/>
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_cs_voice" -->
+<!-- android:imeSubtypeLocale="cs" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_da_keyboard"
android:imeSubtypeLocale="da"
@@ -65,36 +74,45 @@
android:label="@string/subtype_mode_de_keyboard"
android:imeSubtypeLocale="de"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="requiresGermanUmlautProcessing"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_de_voice"
- android:imeSubtypeLocale="de"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_de_qwerty_keyboard"
+ android:imeSubtypeLocale="de_ZZ"
+ android:imeSubtypeMode="keyboard"
/>
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_de_voice" -->
+<!-- android:imeSubtypeLocale="de" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_es_keyboard"
android:imeSubtypeLocale="es"
android:imeSubtypeMode="keyboard"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_es_voice"
- android:imeSubtypeLocale="es"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_es_voice" -->
+<!-- android:imeSubtypeLocale="es" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_fi_keyboard"
+ android:imeSubtypeLocale="fi"
+ android:imeSubtypeMode="keyboard"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_fr_keyboard"
android:imeSubtypeLocale="fr"
android:imeSubtypeMode="keyboard"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_fr_voice"
- android:imeSubtypeLocale="fr"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_fr_voice" -->
+<!-- android:imeSubtypeLocale="fr" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_fr_CA_keyboard"
android:imeSubtypeLocale="fr_CA"
@@ -106,16 +124,33 @@
android:imeSubtypeMode="keyboard"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_hr_keyboard"
+ android:imeSubtypeLocale="hr"
+ android:imeSubtypeMode="keyboard"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_hu_keyboard"
+ android:imeSubtypeLocale="hu"
+ android:imeSubtypeMode="keyboard"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_it_keyboard"
android:imeSubtypeLocale="it"
android:imeSubtypeMode="keyboard"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_it_voice"
- android:imeSubtypeLocale="it"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
+ <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
+ <!-- The file for Hebrew layout is an alpha version. It needs to be run through UX. -->
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_iw_keyboard"
+ android:imeSubtypeLocale="iw"
+ android:imeSubtypeMode="keyboard"
/>
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_it_voice" -->
+<!-- android:imeSubtypeLocale="it" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_nb_keyboard"
android:imeSubtypeLocale="nb"
@@ -126,11 +161,21 @@
android:imeSubtypeLocale="nl"
android:imeSubtypeMode="keyboard"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_nl_voice"
- android:imeSubtypeLocale="nl"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_nl_voice" -->
+<!-- android:imeSubtypeLocale="nl" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_pl_keyboard"
+ android:imeSubtypeLocale="pl"
+ android:imeSubtypeMode="keyboard"
+ />
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_pt_keyboard"
+ android:imeSubtypeLocale="pt"
+ android:imeSubtypeMode="keyboard"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_mode_ru_keyboard"
@@ -147,64 +192,69 @@
android:imeSubtypeLocale="sv"
android:imeSubtypeMode="keyboard"
/>
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_af_voice"
- android:imeSubtypeLocale="af"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_ja_voice"
- android:imeSubtypeLocale="ja"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_ko_voice"
- android:imeSubtypeLocale="ko"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_pl_voice"
- android:imeSubtypeLocale="pl"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_pt_voice"
- android:imeSubtypeLocale="pt"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_ru_voice"
- android:imeSubtypeLocale="ru"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_tr_voice"
+ <subtype android:icon="@drawable/ic_subtype_keyboard"
+ android:label="@string/subtype_mode_tr_keyboard"
android:imeSubtypeLocale="tr"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_yue_voice"
- android:imeSubtypeLocale="yue"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_zh_voice"
- android:imeSubtypeLocale="zh"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
- />
- <subtype android:icon="@drawable/ic_subtype_mic"
- android:label="@string/subtype_mode_zu_voice"
- android:imeSubtypeLocale="zu"
- android:imeSubtypeMode="voice"
- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity"
+ android:imeSubtypeMode="keyboard"
/>
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_af_voice" -->
+<!-- android:imeSubtypeLocale="af" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_ja_voice" -->
+<!-- android:imeSubtypeLocale="ja" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_ko_voice" -->
+<!-- android:imeSubtypeLocale="ko" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_pl_voice" -->
+<!-- android:imeSubtypeLocale="pl" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_pt_voice" -->
+<!-- android:imeSubtypeLocale="pt" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_ru_voice" -->
+<!-- android:imeSubtypeLocale="ru" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_tr_voice" -->
+<!-- android:imeSubtypeLocale="tr" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_yue_voice" -->
+<!-- android:imeSubtypeLocale="yue" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_zh_voice" -->
+<!-- android:imeSubtypeLocale="zh" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
+<!-- <subtype android:icon="@drawable/ic_subtype_mic" -->
+<!-- android:label="@string/subtype_mode_zu_voice" -->
+<!-- android:imeSubtypeLocale="zu" -->
+<!-- android:imeSubtypeMode="voice" -->
+<!-- android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" -->
+<!-- /> -->
</input-method>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index d031415d7..0bf117b30 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -14,86 +14,73 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/english_ime_settings"
- android:key="english_ime_settings">
-
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/english_ime_settings"
+ android:key="english_ime_settings">
<PreferenceCategory
- android:title="@string/general_category"
- android:key="general_settings">
-
+ android:title="@string/general_category"
+ android:key="general_settings">
+ <PreferenceScreen
+ android:key="subtype_settings"
+ android:title="@string/language_selection_title" />
<CheckBoxPreference
- android:key="auto_cap"
- android:title="@string/auto_cap"
- android:persistent="true"
- android:defaultValue="true"
- />
-
+ android:key="auto_cap"
+ android:title="@string/auto_cap"
+ android:persistent="true"
+ android:defaultValue="true" />
<CheckBoxPreference
- android:key="vibrate_on"
- android:title="@string/vibrate_on_keypress"
- android:persistent="true"
- />
-
+ android:key="vibrate_on"
+ android:title="@string/vibrate_on_keypress"
+ android:persistent="true" />
<CheckBoxPreference
- android:key="sound_on"
- android:title="@string/sound_on_keypress"
- android:defaultValue="@bool/config_default_sound_enabled"
- android:persistent="true"
- />
-
+ android:key="sound_on"
+ android:title="@string/sound_on_keypress"
+ android:defaultValue="@bool/config_default_sound_enabled"
+ android:persistent="true" />
<CheckBoxPreference
- android:key="popup_on"
- android:title="@string/popup_on_keypress"
- android:persistent="true"
- android:defaultValue="@bool/config_default_popup_preview"
- />
-
+ android:key="popup_on"
+ android:title="@string/popup_on_keypress"
+ android:persistent="true"
+ android:defaultValue="@bool/config_default_popup_preview" />
<CheckBoxPreference
- android:key="recorrection_enabled"
- android:title="@string/prefs_enable_recorrection"
- android:summary="@string/prefs_enable_recorrection_summary"
- android:persistent="true"
- android:defaultValue="@bool/config_default_recorrection_enabled"
- />
-
+ android:key="recorrection_enabled"
+ android:title="@string/prefs_enable_recorrection"
+ android:summary="@string/prefs_enable_recorrection_summary"
+ android:persistent="true"
+ android:defaultValue="@bool/config_default_recorrection_enabled" />
<ListPreference
- android:key="settings_key"
- android:title="@string/prefs_settings_key"
- android:persistent="true"
- android:entryValues="@array/settings_key_modes_values"
- android:entries="@array/settings_key_modes"
- android:defaultValue="@string/settings_key_mode_auto"
- />
-
+ android:key="settings_key"
+ android:title="@string/prefs_settings_key"
+ android:persistent="true"
+ android:entryValues="@array/settings_key_modes_values"
+ android:entries="@array/settings_key_modes"
+ android:defaultValue="@string/settings_key_mode_auto" />
<ListPreference
- android:key="voice_mode"
- android:title="@string/voice_input"
- android:persistent="true"
- android:entryValues="@array/voice_input_modes_values"
- android:entries="@array/voice_input_modes"
- android:defaultValue="@string/voice_mode_main"
- />
-
- <PreferenceScreen
- android:key="subtype_settings"
- android:title="@string/language_selection_title"
- android:summary="@string/language_selection_summary" />
-
+ android:key="voice_mode"
+ android:title="@string/voice_input"
+ android:persistent="true"
+ android:entryValues="@array/voice_input_modes_values"
+ android:entries="@array/voice_input_modes"
+ android:defaultValue="@string/voice_mode_main" />
</PreferenceCategory>
-
<PreferenceCategory
- android:title="@string/prediction_category"
- android:key="prediction_settings">
-
+ android:title="@string/correction_category"
+ android:key="correction_settings">
+ <PreferenceScreen
+ android:key="configure_dictionaries_key"
+ android:title="@string/configure_dictionaries_title">
+ <intent
+ android:action="android.intent.action.MAIN"
+ android:targetPackage="com.google.android.inputmethod.latin.dictionarypack"
+ android:targetClass="com.google.android.inputmethod.latin.dictionarypack.DictionarySettings" />
+ </PreferenceScreen>
<CheckBoxPreference
android:key="quick_fixes"
android:title="@string/quick_fixes"
android:summary="@string/quick_fixes_summary"
android:persistent="true"
- android:defaultValue="true"
- />
-
+ android:defaultValue="true" />
<ListPreference
android:key="auto_correction_threshold"
android:title="@string/auto_correction"
@@ -101,9 +88,7 @@
android:persistent="true"
android:entryValues="@array/auto_correction_threshold_mode_indexes"
android:entries="@array/auto_correction_threshold_modes"
- android:defaultValue="@string/auto_correction_threshold_mode_index_modest"
- />
-
+ android:defaultValue="@string/auto_correction_threshold_mode_index_modest" />
<ListPreference
android:key="show_suggestions_setting"
android:summary="@string/prefs_show_suggestions_summary"
@@ -111,23 +96,68 @@
android:persistent="true"
android:entryValues="@array/prefs_suggestion_visibility_values"
android:entries="@array/prefs_suggestion_visibilities"
- android:defaultValue="@string/prefs_suggestion_visibility_default_value"
- />
-
+ android:defaultValue="@string/prefs_suggestion_visibility_default_value" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:title="@string/ngram_category"
+ android:key="ngram_settings">
<CheckBoxPreference
android:key="bigram_suggestion"
android:title="@string/bigram_suggestion"
android:summary="@string/bigram_suggestion_summary"
android:persistent="true"
- android:defaultValue="true"
- />
- </PreferenceCategory>
-
- <CheckBoxPreference
- android:key="usability_study_mode"
- android:title="@string/prefs_usability_study_mode"
+ android:defaultValue="true" />
+ <CheckBoxPreference
+ android:key="bigram_prediction"
+ android:dependency="bigram_suggestion"
+ android:title="@string/bigram_prediction"
+ android:summary="@string/bigram_prediction_summary"
android:persistent="true"
- android:defaultValue="false"
- />
-
+ android:defaultValue="false" />
+ </PreferenceCategory>
+ <PreferenceCategory
+ android:title="@string/misc_category"
+ android:key="misc_settings">
+ <CheckBoxPreference
+ android:key="usability_study_mode"
+ android:title="@string/prefs_usability_study_mode"
+ android:persistent="true"
+ android:defaultValue="false" />
+ <CheckBoxPreference
+ android:key="enable_logging"
+ android:title="@string/prefs_enable_log"
+ android:summary="@string/prefs_description_log"
+ android:persistent="true"
+ android:defaultValue="true" />
+ <ListPreference
+ android:key="pref_keyboard_layout_20100902"
+ android:title="@string/keyboard_layout"
+ android:persistent="true"
+ android:entryValues="@array/keyboard_layout_modes_values"
+ android:entries="@array/keyboard_layout_modes"
+ android:defaultValue="@string/config_default_keyboard_theme_id" />
+ </PreferenceCategory>
+ <PreferenceScreen
+ android:key="pref_advanced_settings"
+ android:title="@string/advanced_settings"
+ android:summary="@string/advanced_settings_summary">
+ <!-- Values for popup dismiss delay are added programatically -->
+ <ListPreference
+ android:key="pref_key_preview_popup_dismiss_delay"
+ android:title="@string/key_preview_popup_dismiss_delay" />
+ <CheckBoxPreference
+ android:key="pref_key_use_contacts_dict"
+ android:title="@string/use_contacts_dict"
+ android:summary="@string/use_contacts_dict_summary"
+ android:persistent="true"
+ android:defaultValue="true" />
+ </PreferenceScreen>
+ <!-- <Preference
+ android:title="Debug Settings"
+ android:key="debug_settings">
+ <intent
+ android:action="android.intent.action.MAIN"
+ android:targetPackage="com.android.inputmethod.latin"
+ android:targetClass="com.android.inputmethod.latin.DebugSettings" />
+ </Preference>-->
</PreferenceScreen>
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
index 2dad17148..477461df4 100644
--- a/java/res/xml/prefs_for_debug.xml
+++ b/java/res/xml/prefs_for_debug.xml
@@ -36,6 +36,13 @@
/>
<CheckBoxPreference
+ android:key="use_spacebar_language_switch"
+ android:title="@string/prefs_use_spacebar_language_switch"
+ android:persistent="true"
+ android:defaultValue="false"
+ />
+
+ <CheckBoxPreference
android:key="debug_mode"
android:title="@string/prefs_debug_mode"
android:persistent="true"
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
new file mode 100644
index 000000000..ae614b7e0
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -0,0 +1,133 @@
+/*
+ * 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.accessibility;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.inputmethodservice.InputMethodService;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.inputmethod.compat.AccessibilityEventCompatUtils;
+import com.android.inputmethod.compat.AccessibilityManagerCompatWrapper;
+import com.android.inputmethod.compat.MotionEventCompatUtils;
+
+public class AccessibilityUtils {
+ private static final String TAG = AccessibilityUtils.class.getSimpleName();
+ private static final String CLASS = AccessibilityUtils.class.getClass().getName();
+ private static final String PACKAGE = AccessibilityUtils.class.getClass().getPackage()
+ .getName();
+
+ private static final AccessibilityUtils sInstance = new AccessibilityUtils();
+
+ private AccessibilityManager mAccessibilityManager;
+ private AccessibilityManagerCompatWrapper mCompatManager;
+
+ /*
+ * Setting this constant to {@code false} will disable all keyboard
+ * accessibility code, regardless of whether Accessibility is turned on in
+ * the system settings. It should ONLY be used in the event of an emergency.
+ */
+ private static final boolean ENABLE_ACCESSIBILITY = true;
+
+ public static void init(InputMethodService inputMethod, SharedPreferences prefs) {
+ 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);
+ }
+
+ public static AccessibilityUtils getInstance() {
+ return sInstance;
+ }
+
+ private AccessibilityUtils() {
+ // This class is not publicly instantiable.
+ }
+
+ private void initInternal(Context context, SharedPreferences prefs) {
+ mAccessibilityManager = (AccessibilityManager) context
+ .getSystemService(Context.ACCESSIBILITY_SERVICE);
+ mCompatManager = new AccessibilityManagerCompatWrapper(mAccessibilityManager);
+ }
+
+ /**
+ * Returns {@code true} if touch exploration is enabled. Currently, this
+ * means that the kill switch is off, the device supports touch exploration,
+ * and a spoken feedback service is turned on.
+ *
+ * @return {@code true} if touch exploration is enabled.
+ */
+ public boolean isTouchExplorationEnabled() {
+ return ENABLE_ACCESSIBILITY
+ && AccessibilityEventCompatUtils.supportsTouchExploration()
+ && mAccessibilityManager.isEnabled()
+ && !mCompatManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty();
+ }
+
+ /**
+ * Returns {@true} if the provided event is a touch exploration (e.g. hover)
+ * event. This is used to determine whether the event should be processed by
+ * the touch exploration code within the keyboard.
+ *
+ * @param event The event to check.
+ * @return {@true} is the event is a touch exploration event
+ */
+ public boolean isTouchExplorationEvent(MotionEvent event) {
+ final int action = event.getAction();
+
+ return action == MotionEventCompatUtils.ACTION_HOVER_ENTER
+ || action == MotionEventCompatUtils.ACTION_HOVER_EXIT
+ || action == MotionEventCompatUtils.ACTION_HOVER_MOVE;
+ }
+
+ /**
+ * Sends the specified text to the {@link AccessibilityManager} to be
+ * spoken.
+ *
+ * @param text the text to speak
+ */
+ public void speak(CharSequence text) {
+ if (!mAccessibilityManager.isEnabled()) {
+ Log.e(TAG, "Attempted to speak when accessibility was disabled!");
+ return;
+ }
+
+ // The following is a hack to avoid using the heavy-weight TextToSpeech
+ // class. Instead, we're just forcing a fake AccessibilityEvent into
+ // the screen reader to make it speak.
+ final AccessibilityEvent event = AccessibilityEvent
+ .obtain(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER);
+
+ event.setPackageName(PACKAGE);
+ event.setClassName(CLASS);
+ event.setEventTime(SystemClock.uptimeMillis());
+ event.setEnabled(true);
+ event.getText().add(text);
+
+ mAccessibilityManager.sendAccessibilityEvent(event);
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java
new file mode 100644
index 000000000..89adc15f2
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java
@@ -0,0 +1,172 @@
+/*
+ * 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.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.
+ */
+ private static final long VIBRATE_KEY_CLICK = 50;
+
+ 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 AccessibleInputMethodServiceProxy getInstance() {
+ return sInstance;
+ }
+
+ private AccessibleInputMethodServiceProxy() {
+ // Not publicly instantiable.
+ }
+
+ private void initInternal(InputMethodService inputMethod, SharedPreferences prefs) {
+ 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();
+ }
+
+ /**
+ * Handle flick gestures by mapping them to directional pad keys.
+ */
+ @Override
+ public void onFlickGesture(int direction) {
+ final int keyEventCode;
+
+ switch (direction) {
+ case FlickGestureDetector.FLICK_LEFT:
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
+ break;
+ case FlickGestureDetector.FLICK_RIGHT:
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
+ break;
+ }
+ }
+
+ /**
+ * Provide haptic feedback and send the specified keyCode to the input
+ * connection as a pair of down/up events.
+ *
+ * @param keyCode
+ */
+ private void sendDownUpKeyEvents(int keyCode) {
+ mVibrator.vibrate(VIBRATE_KEY_CLICK);
+ mAudioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
+ 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
new file mode 100644
index 000000000..c1e92bec8
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java
@@ -0,0 +1,48 @@
+/*
+ * 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.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}
+ * <li>{@link FlickGestureDetector#FLICK_DOWN}
+ * <li>{@link FlickGestureDetector#FLICK_LEFT}
+ * <li>{@link FlickGestureDetector#FLICK_RIGHT}
+ * </ul>
+ */
+ public void onFlickGesture(int direction);
+}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
new file mode 100644
index 000000000..8ca834148
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -0,0 +1,220 @@
+/*
+ * 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.accessibility;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+
+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.LatinKeyboardBaseView;
+import com.android.inputmethod.keyboard.PointerTracker;
+
+public class AccessibleKeyboardViewProxy {
+ private static final String TAG = AccessibleKeyboardViewProxy.class.getSimpleName();
+ private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
+
+ // Delay in milliseconds between key press DOWN and UP events
+ private static final long DELAY_KEY_PRESS = 10;
+
+ private int mScaledEdgeSlop;
+ private LatinKeyboardBaseView mView;
+ private AccessibleKeyboardActionListener mListener;
+ private FlickGestureDetector mGestureDetector;
+
+ private int mLastHoverKeyIndex = KeyDetector.NOT_A_KEY;
+ private int mLastX = -1;
+ private int mLastY = -1;
+
+ public static void init(Context context, SharedPreferences prefs) {
+ sInstance.initInternal(context, prefs);
+ sInstance.mListener = AccessibleInputMethodServiceProxy.getInstance();
+ }
+
+ public static AccessibleKeyboardViewProxy getInstance() {
+ return sInstance;
+ }
+
+ public static void setView(LatinKeyboardBaseView view) {
+ sInstance.mView = view;
+ }
+
+ private AccessibleKeyboardViewProxy() {
+ // Not publicly instantiable.
+ }
+
+ private void initInternal(Context context, SharedPreferences prefs) {
+ final Paint paint = new Paint();
+ paint.setTextAlign(Paint.Align.LEFT);
+ paint.setTextSize(14.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(Color.YELLOW);
+
+ mGestureDetector = new KeyboardFlickGestureDetector(context);
+ mScaledEdgeSlop = ViewConfiguration.get(context).getScaledEdgeSlop();
+ }
+
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event,
+ PointerTracker tracker) {
+ if (mView == null) {
+ Log.e(TAG, "No keyboard view set!");
+ return false;
+ }
+
+ switch (event.getEventType()) {
+ case AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER:
+ final Key key = tracker.getKey(mLastHoverKeyIndex);
+
+ if (key == null)
+ break;
+
+ final CharSequence description = KeyCodeDescriptionMapper.getInstance()
+ .getDescriptionForKey(mView.getContext(), mView.getKeyboard(), key);
+
+ if (description == null)
+ return false;
+
+ event.getText().add(description);
+
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * Receives hover events when accessibility is turned on in API > 11. In
+ * earlier API levels, events are manually routed from onTouchEvent.
+ *
+ * @param event The hover event.
+ * @return {@code true} if the event is handled
+ */
+ public boolean onHoverEvent(MotionEvent event, PointerTracker tracker) {
+ if (mGestureDetector.onHoverEvent(event, this, tracker))
+ return true;
+
+ return onHoverEventInternal(event, tracker);
+ }
+
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ // Since touch exploration translates hover double-tap to a regular
+ // single-tap, we're going to drop non-touch exploration events.
+ if (!AccessibilityUtils.getInstance().isTouchExplorationEvent(event))
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Handles touch exploration events when Accessibility is turned on.
+ *
+ * @param event The touch exploration hover event.
+ * @return {@code true} if the event was handled
+ */
+ /*package*/ boolean onHoverEventInternal(MotionEvent event, PointerTracker tracker) {
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+
+ switch (event.getAction()) {
+ case MotionEventCompatUtils.ACTION_HOVER_ENTER:
+ case MotionEventCompatUtils.ACTION_HOVER_MOVE:
+ final int keyIndex = tracker.getKeyIndexOn(x, y);
+
+ if (keyIndex != mLastHoverKeyIndex) {
+ fireKeyHoverEvent(tracker, mLastHoverKeyIndex, false);
+ mLastHoverKeyIndex = keyIndex;
+ mLastX = x;
+ mLastY = y;
+ fireKeyHoverEvent(tracker, mLastHoverKeyIndex, true);
+ }
+
+ return true;
+ case MotionEventCompatUtils.ACTION_HOVER_EXIT:
+ final int width = mView.getWidth();
+ final int height = mView.getHeight();
+
+ if (x < mScaledEdgeSlop || y < mScaledEdgeSlop || x >= (width - mScaledEdgeSlop)
+ || y >= (height - mScaledEdgeSlop)) {
+ fireKeyHoverEvent(tracker, mLastHoverKeyIndex, false);
+ mLastHoverKeyIndex = KeyDetector.NOT_A_KEY;
+ mLastX = -1;
+ mLastY = -1;
+ } else if (mLastHoverKeyIndex != KeyDetector.NOT_A_KEY) {
+ fireKeyPressEvent(tracker, mLastX, mLastY, event.getEventTime());
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private void fireKeyHoverEvent(PointerTracker tracker, int keyIndex, boolean entering) {
+ if (mListener == null) {
+ Log.e(TAG, "No accessible keyboard action listener set!");
+ return;
+ }
+
+ if (mView == null) {
+ Log.e(TAG, "No keyboard view set!");
+ 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);
+ }
+ }
+
+ private void fireKeyPressEvent(PointerTracker tracker, int x, int y, long eventTime) {
+ tracker.onDownEvent(x, y, eventTime, mView);
+ tracker.onUpEvent(x, y, eventTime + DELAY_KEY_PRESS);
+ }
+
+ private class KeyboardFlickGestureDetector extends FlickGestureDetector {
+ public KeyboardFlickGestureDetector(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean onFlick(MotionEvent e1, MotionEvent e2, int direction) {
+ if (mListener != null) {
+ mListener.onFlickGesture(direction);
+ }
+ return true;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java
new file mode 100644
index 000000000..9d99e3131
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java
@@ -0,0 +1,227 @@
+/*
+ * 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.accessibility;
+
+import android.content.Context;
+import android.os.Message;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import com.android.inputmethod.compat.MotionEventCompatUtils;
+import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+
+/**
+ * Detects flick gestures within a stream of hover events.
+ * <p>
+ * A flick gesture is defined as a stream of hover events with the following
+ * properties:
+ * <ul>
+ * <li>Begins with a {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event
+ * <li>Contains any number of {@link MotionEventCompatUtils#ACTION_HOVER_MOVE}
+ * events
+ * <li>Ends with a {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event
+ * <li>Maximum duration of 250 milliseconds
+ * <li>Minimum distance between enter and exit points must be at least equal to
+ * scaled double tap slop (see
+ * {@link ViewConfiguration#getScaledDoubleTapSlop()})
+ * </ul>
+ * <p>
+ * Initial enter events are intercepted and cached until the stream fails to
+ * satisfy the constraints defined above, at which point the cached enter event
+ * is sent to its source {@link AccessibleKeyboardViewProxy} and subsequent move
+ * and exit events are ignored.
+ */
+public abstract class FlickGestureDetector {
+ public static final int FLICK_UP = 0;
+ public static final int FLICK_RIGHT = 1;
+ public static final int FLICK_LEFT = 2;
+ public static final int FLICK_DOWN = 3;
+
+ private final FlickHandler mFlickHandler;
+ private final int mFlickRadiusSquare;
+
+ private AccessibleKeyboardViewProxy mCachedView;
+ private PointerTracker mCachedTracker;
+ private MotionEvent mCachedHoverEnter;
+
+ private static class FlickHandler extends StaticInnerHandlerWrapper<FlickGestureDetector> {
+ private static final int MSG_FLICK_TIMEOUT = 1;
+
+ /** The maximum duration of a flick gesture in milliseconds. */
+ private static final int DELAY_FLICK_TIMEOUT = 250;
+
+ public FlickHandler(FlickGestureDetector outerInstance) {
+ super(outerInstance);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ final FlickGestureDetector gestureDetector = getOuterInstance();
+
+ switch (msg.what) {
+ case MSG_FLICK_TIMEOUT:
+ gestureDetector.clearFlick(true);
+ }
+ }
+
+ public void startFlickTimeout() {
+ cancelFlickTimeout();
+ sendEmptyMessageDelayed(MSG_FLICK_TIMEOUT, DELAY_FLICK_TIMEOUT);
+ }
+
+ public void cancelFlickTimeout() {
+ removeMessages(MSG_FLICK_TIMEOUT);
+ }
+ }
+
+ /**
+ * Creates a new flick gesture detector.
+ *
+ * @param context The parent context.
+ */
+ public FlickGestureDetector(Context context) {
+ final int doubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
+
+ mFlickHandler = new FlickHandler(this);
+ mFlickRadiusSquare = doubleTapSlop * doubleTapSlop;
+ }
+
+ /**
+ * Processes motion events to detect flick gestures.
+ *
+ * @param event The current event.
+ * @param view The source of the event.
+ * @param tracker A pointer tracker for the event.
+ * @return {@code true} if the event was handled.
+ */
+ public boolean onHoverEvent(MotionEvent event, AccessibleKeyboardViewProxy view,
+ PointerTracker tracker) {
+ // Always cache and consume the first hover event.
+ if (event.getAction() == MotionEventCompatUtils.ACTION_HOVER_ENTER) {
+ mCachedView = view;
+ mCachedTracker = tracker;
+ mCachedHoverEnter = MotionEvent.obtain(event);
+ mFlickHandler.startFlickTimeout();
+ return true;
+ }
+
+ // Stop if the event has already been canceled.
+ if (mCachedHoverEnter == null) {
+ return false;
+ }
+
+ final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event);
+ final long timeout = event.getEventTime() - mCachedHoverEnter.getEventTime();
+
+ switch (event.getAction()) {
+ case MotionEventCompatUtils.ACTION_HOVER_MOVE:
+ // Consume all valid move events before timeout.
+ return true;
+ case MotionEventCompatUtils.ACTION_HOVER_EXIT:
+ // Ignore exit events outside the flick radius.
+ if (distanceSquare < mFlickRadiusSquare) {
+ clearFlick(true);
+ return false;
+ } else {
+ return dispatchFlick(mCachedHoverEnter, event);
+ }
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Clears the cached flick information and optionally forwards the event to
+ * the source view's internal hover event handler.
+ *
+ * @param sendCachedEvent Set to {@code true} to forward the hover event to
+ * the source view.
+ */
+ private void clearFlick(boolean sendCachedEvent) {
+ mFlickHandler.cancelFlickTimeout();
+
+ if (mCachedHoverEnter != null) {
+ if (sendCachedEvent) {
+ mCachedView.onHoverEventInternal(mCachedHoverEnter, mCachedTracker);
+ }
+ mCachedHoverEnter.recycle();
+ mCachedHoverEnter = null;
+ }
+
+ mCachedTracker = null;
+ mCachedView = null;
+ }
+
+ /**
+ * Computes the direction of a flick gesture and forwards it to
+ * {@link #onFlick(MotionEvent, MotionEvent, int)} for handling.
+ *
+ * @param e1 The {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event
+ * where the flick started.
+ * @param e2 The {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event
+ * where the flick ended.
+ * @return {@code true} if the flick event was handled.
+ */
+ private boolean dispatchFlick(MotionEvent e1, MotionEvent e2) {
+ clearFlick(false);
+
+ final float dX = e2.getX() - e1.getX();
+ final float dY = e2.getY() - e1.getY();
+ final int direction;
+
+ if (dY > dX) {
+ if (dY > -dX) {
+ direction = FLICK_DOWN;
+ } else {
+ direction = FLICK_LEFT;
+ }
+ } else {
+ if (dY > -dX) {
+ direction = FLICK_RIGHT;
+ } else {
+ direction = FLICK_UP;
+ }
+ }
+
+ return onFlick(e1, e2, direction);
+ }
+
+ private float calculateDistanceSquare(MotionEvent e1, MotionEvent e2) {
+ final float dX = e2.getX() - e1.getX();
+ final float dY = e2.getY() - e1.getY();
+ return (dX * dX) + (dY * dY);
+ }
+
+ /**
+ * Handles a detected flick gesture.
+ *
+ * @param e1 The {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event
+ * where the flick started.
+ * @param e2 The {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event
+ * where the flick ended.
+ * @param direction The direction of the flick event, one of:
+ * <ul>
+ * <li>{@link #FLICK_UP}
+ * <li>{@link #FLICK_DOWN}
+ * <li>{@link #FLICK_LEFT}
+ * <li>{@link #FLICK_RIGHT}
+ * </ul>
+ * @return {@code true} if the flick event was handled.
+ */
+ public abstract boolean onFlick(MotionEvent e1, MotionEvent e2, int direction);
+}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
new file mode 100644
index 000000000..d196c8955
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -0,0 +1,227 @@
+/*
+ * 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.accessibility;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.text.TextUtils;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.latin.R;
+
+import java.util.HashMap;
+
+public class KeyCodeDescriptionMapper {
+ private static KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper();
+
+ // Map of key labels to spoken description resource IDs
+ private final HashMap<CharSequence, Integer> mKeyLabelMap;
+
+ // 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 KeyCodeDescriptionMapper getInstance() {
+ return sInstance;
+ }
+
+ 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) {
+ // 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);
+ mKeyCodeMap.put(Keyboard.CODE_SETTINGS, R.string.spoken_description_settings);
+ mKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift);
+ 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);
+ }
+
+ /**
+ * Returns the localized description of the action performed by a specified
+ * key based on the current keyboard state.
+ * <p>
+ * The order of precedence for key descriptions is:
+ * <ol>
+ * <li>Manually-defined based on the key label</li>
+ * <li>Automatic or manually-defined based on the key code</li>
+ * <li>Automatically based on the key label</li>
+ * <li>{code null} for keys with no label or key code defined</li>
+ * </p>
+ *
+ * @param context The package's context.
+ * @param keyboard The keyboard on which the key resides.
+ * @param key The key from which to obtain a description.
+ * @return a character sequence describing the action performed by pressing
+ * the key
+ */
+ public CharSequence getDescriptionForKey(Context context, Keyboard keyboard, Key key) {
+ if (key.mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ final CharSequence description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
+ if (description != null)
+ return description;
+ }
+
+ if (!TextUtils.isEmpty(key.mLabel)) {
+ final String label = key.mLabel.toString().trim();
+
+ 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);
+ } else {
+ return label;
+ }
+ } else if (key.mCode != Keyboard.CODE_DUMMY) {
+ return getDescriptionForKeyCode(context, keyboard, key);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a context-specific description for the CODE_SWITCH_ALPHA_SYMBOL
+ * key or {@code null} if there is not a description provided for the
+ * current keyboard context.
+ *
+ * @param context The package's context.
+ * @param keyboard The keyboard on which the key resides.
+ * @return a character sequence describing the action performed by pressing
+ * 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.isPhoneSymbolsKeyboard()) {
+ return context.getString(R.string.spoken_description_to_numeric);
+ } else if (id.isPhoneKeyboard()) {
+ return context.getString(R.string.spoken_description_to_symbol);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the keycode for the specified key given the current keyboard
+ * state.
+ *
+ * @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
+ */
+ private int getCorrectKeyCode(Keyboard keyboard, Key key) {
+ if (keyboard.isManualTemporaryUpperCase() && !TextUtils.isEmpty(key.mHintLabel)) {
+ return key.mHintLabel.charAt(0);
+ } else {
+ return key.mCode;
+ }
+ }
+
+ /**
+ * Returns a localized character sequence describing what will happen when
+ * the specified key is pressed based on its key code.
+ * <p>
+ * The order of precedence for key code descriptions is:
+ * <ol>
+ * <li>Manually-defined shift-locked description</li>
+ * <li>Manually-defined shifted description</li>
+ * <li>Manually-defined normal description</li>
+ * <li>Automatic based on the character represented by the key code</li>
+ * <li>Fall-back for undefined or control characters</li>
+ * </ol>
+ * </p>
+ *
+ * @param context The package's context.
+ * @param keyboard The keyboard on which the key resides.
+ * @param key The key from which to obtain a description.
+ * @return a character sequence describing the action performed by pressing
+ * the key
+ */
+ private CharSequence getDescriptionForKeyCode(Context context, Keyboard keyboard, Key key) {
+ 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));
+ } else if (mKeyCodeMap.containsKey(code)) {
+ return context.getString(mKeyCodeMap.get(code));
+ } else if (Character.isDefined(code) && !Character.isISOControl(code)) {
+ return Character.toString((char) code);
+ } else {
+ return context.getString(R.string.spoken_description_unknown, code);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java
new file mode 100644
index 000000000..65949357f
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.Log;
+
+public abstract class AbstractCompatWrapper {
+ private static final String TAG = AbstractCompatWrapper.class.getSimpleName();
+ protected final Object mObj;
+
+ public AbstractCompatWrapper(Object obj) {
+ if (obj == null) {
+ Log.e(TAG, "Invalid input to AbstructCompatWrapper");
+ }
+ mObj = obj;
+ }
+
+ public Object getOriginalObject() {
+ return mObj;
+ }
+
+ public boolean hasOriginalObject() {
+ return mObj != null;
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java b/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java
new file mode 100644
index 000000000..50057727a
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java
@@ -0,0 +1,39 @@
+/*
+ * 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.accessibility.AccessibilityEvent;
+
+import java.lang.reflect.Field;
+
+public class AccessibilityEventCompatUtils {
+ public static final int TYPE_VIEW_HOVER_ENTER = 0x80;
+ public static final int TYPE_VIEW_HOVER_EXIT = 0x100;
+
+ private static final Field FIELD_TYPE_VIEW_HOVER_ENTER = CompatUtils.getField(
+ AccessibilityEvent.class, "TYPE_VIEW_HOVER_ENTER");
+ private static final Field FIELD_TYPE_VIEW_HOVER_EXIT = CompatUtils.getField(
+ AccessibilityEvent.class, "TYPE_VIEW_HOVER_EXIT");
+ private static final Integer OBJ_TYPE_VIEW_HOVER_ENTER = (Integer) CompatUtils
+ .getFieldValue(null, null, FIELD_TYPE_VIEW_HOVER_ENTER);
+ private static final Integer OBJ_TYPE_VIEW_HOVER_EXIT = (Integer) CompatUtils
+ .getFieldValue(null, null, FIELD_TYPE_VIEW_HOVER_EXIT);
+
+ public static boolean supportsTouchExploration() {
+ return OBJ_TYPE_VIEW_HOVER_ENTER != null && OBJ_TYPE_VIEW_HOVER_EXIT != null;
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java
new file mode 100644
index 000000000..4db1c7a24
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * 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.accessibilityservice.AccessibilityServiceInfo;
+import android.view.accessibility.AccessibilityManager;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+public class AccessibilityManagerCompatWrapper {
+ private static final Method METHOD_getEnabledAccessibilityServiceList = CompatUtils.getMethod(
+ AccessibilityManager.class, "getEnabledAccessibilityServiceList", int.class);
+
+ private final AccessibilityManager mManager;
+
+ public AccessibilityManagerCompatWrapper(AccessibilityManager manager) {
+ mManager = manager;
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) {
+ return (List<AccessibilityServiceInfo>) CompatUtils.invoke(mManager,
+ Collections.<AccessibilityServiceInfo>emptyList(),
+ METHOD_getEnabledAccessibilityServiceList, feedbackType);
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java b/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java
new file mode 100644
index 000000000..f6afbcfe2
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ArraysCompatUtils.java
@@ -0,0 +1,50 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.Arrays;
+
+public class ArraysCompatUtils {
+ private static final Method METHOD_Arrays_binarySearch = CompatUtils
+ .getMethod(Arrays.class, "binarySearch", int[].class, int.class, int.class, int.class);
+
+ public static int binarySearch(int[] array, int startIndex, int endIndex, int value) {
+ if (METHOD_Arrays_binarySearch != null) {
+ final Object index = CompatUtils.invoke(null, 0, METHOD_Arrays_binarySearch,
+ array, startIndex, endIndex, value);
+ return (Integer)index;
+ } else {
+ return compatBinarySearch(array, startIndex, endIndex, value);
+ }
+ }
+
+ /* package */ static int compatBinarySearch(int[] array, int startIndex, int endIndex,
+ int value) {
+ if (startIndex > endIndex) throw new IllegalArgumentException();
+ if (startIndex < 0 || endIndex > array.length) throw new ArrayIndexOutOfBoundsException();
+
+ final int work[] = new int[endIndex - startIndex];
+ System.arraycopy(array, startIndex, work, 0, work.length);
+ final int index = Arrays.binarySearch(work, value);
+ if (index >= 0) {
+ return index + startIndex;
+ } else {
+ return ~(~index + startIndex);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java
new file mode 100644
index 000000000..b42633cd9
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/CompatUtils.java
@@ -0,0 +1,156 @@
+/*
+ * 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.content.Intent;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CompatUtils {
+ private static final String TAG = CompatUtils.class.getSimpleName();
+ private static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
+ // TODO: Can these be constants instead of literal String constants?
+ private static final String INPUT_METHOD_SUBTYPE_SETTINGS =
+ "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
+ private static final String INPUT_LANGUAGE_SELECTION =
+ "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION";
+
+ public static Intent getInputLanguageSelectionIntent(String inputMethodId,
+ int flagsForSubtypeSettings) {
+ final String action;
+ Intent intent;
+ if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED
+ /* android.os.Build.VERSION_CODES.HONEYCOMB */
+ && android.os.Build.VERSION.SDK_INT >= 11) {
+ // Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS
+ action = INPUT_METHOD_SUBTYPE_SETTINGS;
+ intent = new Intent(action);
+ if (!TextUtils.isEmpty(inputMethodId)) {
+ intent.putExtra(EXTRA_INPUT_METHOD_ID, inputMethodId);
+ }
+ if (flagsForSubtypeSettings > 0) {
+ intent.setFlags(flagsForSubtypeSettings);
+ }
+ } else {
+ action = INPUT_LANGUAGE_SELECTION;
+ intent = new Intent(action);
+ }
+ return intent;
+ }
+
+ public static Class<?> getClass(String className) {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ public static Method getMethod(Class<?> targetClass, String name,
+ Class<?>... parameterTypes) {
+ if (targetClass == null || TextUtils.isEmpty(name)) return null;
+ try {
+ return targetClass.getMethod(name, parameterTypes);
+ } catch (SecurityException e) {
+ // ignore
+ } catch (NoSuchMethodException e) {
+ // ignore
+ }
+ return null;
+ }
+
+ public static Field getField(Class<?> targetClass, String name) {
+ if (targetClass == null || TextUtils.isEmpty(name)) return null;
+ try {
+ return targetClass.getField(name);
+ } catch (SecurityException e) {
+ // ignore
+ } catch (NoSuchFieldException e) {
+ // ignore
+ }
+ return null;
+ }
+
+ public static Constructor<?> getConstructor(Class<?> targetClass, Class<?> ... types) {
+ if (targetClass == null || types == null) return null;
+ try {
+ return targetClass.getConstructor(types);
+ } catch (SecurityException e) {
+ // ignore
+ } catch (NoSuchMethodException e) {
+ // ignore
+ }
+ return null;
+ }
+
+ public static Object newInstance(Constructor<?> constructor, Object ... args) {
+ if (constructor == null) return null;
+ try {
+ return constructor.newInstance(args);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in newInstance: " + e.getClass().getSimpleName());
+ }
+ return null;
+ }
+
+ public static Object invoke(
+ Object receiver, Object defaultValue, Method method, Object... args) {
+ if (method == null) return defaultValue;
+ try {
+ return method.invoke(receiver, args);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in invoke: " + e.getClass().getSimpleName());
+ }
+ return defaultValue;
+ }
+
+ public static Object getFieldValue(Object receiver, Object defaultValue, Field field) {
+ if (field == null) return defaultValue;
+ try {
+ return field.get(receiver);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in getFieldValue: " + e.getClass().getSimpleName());
+ }
+ return defaultValue;
+ }
+
+ public static void setFieldValue(Object receiver, Field field, Object value) {
+ if (field == null) return;
+ try {
+ field.set(receiver, value);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in setFieldValue: " + e.getClass().getSimpleName());
+ }
+ }
+
+ public static List<InputMethodSubtypeCompatWrapper> copyInputMethodSubtypeListToWrapper(
+ Object listObject) {
+ if (!(listObject instanceof List<?>)) return null;
+ final List<InputMethodSubtypeCompatWrapper> subtypes =
+ new ArrayList<InputMethodSubtypeCompatWrapper>();
+ for (Object o: (List<?>)listObject) {
+ subtypes.add(new InputMethodSubtypeCompatWrapper(o));
+ }
+ return subtypes;
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
new file mode 100644
index 000000000..bcdcef7dc
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
@@ -0,0 +1,102 @@
+/*
+ * 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.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+import java.lang.reflect.Field;
+
+public class EditorInfoCompatUtils {
+ private static final Field FIELD_IME_FLAG_NAVIGATE_NEXT = CompatUtils.getField(
+ 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_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_ACTION_PREVIOUS = (Integer) CompatUtils
+ .getFieldValue(null, null, FIELD_IME_ACTION_PREVIOUS);
+
+ public static boolean hasFlagNavigateNext(int imeOptions) {
+ if (OBJ_IME_FLAG_NAVIGATE_NEXT == null)
+ return false;
+ return (imeOptions & OBJ_IME_FLAG_NAVIGATE_NEXT) != 0;
+ }
+
+ public static boolean hasFlagNavigatePrevious(int imeOptions) {
+ if (OBJ_IME_FLAG_NAVIGATE_PREVIOUS == null)
+ return false;
+ return (imeOptions & OBJ_IME_FLAG_NAVIGATE_PREVIOUS) != 0;
+ }
+
+ public static void performEditorActionNext(InputConnection ic) {
+ ic.performEditorAction(EditorInfo.IME_ACTION_NEXT);
+ }
+
+ public static void performEditorActionPrevious(InputConnection ic) {
+ if (OBJ_IME_ACTION_PREVIOUS == null)
+ return;
+ ic.performEditorAction(OBJ_IME_ACTION_PREVIOUS);
+ }
+
+ public static String imeOptionsName(int imeOptions) {
+ if (imeOptions == -1)
+ return null;
+ 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;
+ }
+ }
+ if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
+ return "flagNoEnterAction|" + action;
+ } else {
+ return action;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/FrameLayoutCompatUtils.java b/java/src/com/android/inputmethod/compat/FrameLayoutCompatUtils.java
new file mode 100644
index 000000000..523bf7d0e
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/FrameLayoutCompatUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
+
+public class FrameLayoutCompatUtils {
+ private static final boolean NEEDS_FRAME_LAYOUT_HACK = (
+ android.os.Build.VERSION.SDK_INT < 11 /* Honeycomb */);
+
+ public static ViewGroup getPlacer(ViewGroup container) {
+ if (NEEDS_FRAME_LAYOUT_HACK) {
+ // Insert RelativeLayout to be able to setMargin because pre-Honeycomb FrameLayout
+ // could not handle setMargin properly.
+ final ViewGroup placer = new RelativeLayout(container.getContext());
+ container.addView(placer);
+ return placer;
+ } else {
+ return container;
+ }
+ }
+
+ public static MarginLayoutParams newLayoutParam(ViewGroup placer, int width, int height) {
+ if (placer instanceof FrameLayout) {
+ return new FrameLayout.LayoutParams(width, height);
+ } else if (placer instanceof RelativeLayout) {
+ return new RelativeLayout.LayoutParams(width, height);
+ } else if (placer == null) {
+ throw new NullPointerException("placer is null");
+ } else {
+ throw new IllegalArgumentException("placer is neither FrameLayout nor RelativeLayout: "
+ + placer.getClass().getName());
+ }
+ }
+
+ public static void placeViewAt(View view, int x, int y, int w, int h) {
+ final ViewGroup.LayoutParams lp = view.getLayoutParams();
+ if (lp instanceof MarginLayoutParams) {
+ final MarginLayoutParams marginLayoutParams = (MarginLayoutParams)lp;
+ marginLayoutParams.width = w;
+ marginLayoutParams.height = h;
+ marginLayoutParams.setMargins(x, y, 0, 0);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
new file mode 100644
index 000000000..7d00b6007
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.android.inputmethod.latin.EditingUtils.SelectedWord;
+
+import android.view.inputmethod.InputConnection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class InputConnectionCompatUtils {
+ private static final Class<?> CLASS_CorrectionInfo = CompatUtils
+ .getClass("android.view.inputmethod.CorrectionInfo");
+ private static final Class<?>[] INPUT_TYPE_CorrectionInfo = new Class<?>[] { int.class,
+ CharSequence.class, CharSequence.class };
+ private static final Constructor<?> CONSTRUCTOR_CorrectionInfo = CompatUtils
+ .getConstructor(CLASS_CorrectionInfo, INPUT_TYPE_CorrectionInfo);
+ private static final Method METHOD_InputConnection_commitCorrection = CompatUtils
+ .getMethod(InputConnection.class, "commitCorrection", CLASS_CorrectionInfo);
+ private static final Method METHOD_getSelectedText = CompatUtils
+ .getMethod(InputConnection.class, "getSelectedText", int.class);
+ private static final Method METHOD_setComposingRegion = CompatUtils
+ .getMethod(InputConnection.class, "setComposingRegion", int.class, int.class);
+ public static final boolean RECORRECTION_SUPPORTED;
+
+ static {
+ RECORRECTION_SUPPORTED = METHOD_getSelectedText != null
+ && METHOD_setComposingRegion != null;
+ }
+
+ public static void commitCorrection(InputConnection ic, int offset, CharSequence oldText,
+ CharSequence newText) {
+ if (ic == null || CONSTRUCTOR_CorrectionInfo == null
+ || METHOD_InputConnection_commitCorrection == null) {
+ return;
+ }
+ Object[] args = { offset, oldText, newText };
+ Object correctionInfo = CompatUtils.newInstance(CONSTRUCTOR_CorrectionInfo, args);
+ if (correctionInfo != null) {
+ CompatUtils.invoke(ic, null, METHOD_InputConnection_commitCorrection,
+ correctionInfo);
+ }
+ }
+
+
+ /**
+ * Returns the selected text between the selStart and selEnd positions.
+ */
+ public static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) {
+ // Use reflection, for backward compatibility
+ return (CharSequence) CompatUtils.invoke(
+ ic, null, METHOD_getSelectedText, 0);
+ }
+
+ /**
+ * Tries to set the text into composition mode if there is support for it in the framework.
+ */
+ public static void underlineWord(InputConnection ic, SelectedWord word) {
+ // Use reflection, for backward compatibility
+ // If method not found, there's nothing we can do. It still works but just wont underline
+ // the word.
+ CompatUtils.invoke(
+ ic, null, METHOD_setComposingRegion, word.mStart, word.mEnd);
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java
new file mode 100644
index 000000000..8e22bbc79
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java
@@ -0,0 +1,59 @@
+/*
+ * 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.content.pm.ServiceInfo;
+import android.view.inputmethod.InputMethodInfo;
+
+import java.lang.reflect.Method;
+
+public class InputMethodInfoCompatWrapper {
+ private final InputMethodInfo mImi;
+ private static final Method METHOD_getSubtypeAt = CompatUtils.getMethod(
+ InputMethodInfo.class, "getSubtypeAt", int.class);
+ private static final Method METHOD_getSubtypeCount = CompatUtils.getMethod(
+ InputMethodInfo.class, "getSubtypeCount");
+
+ public InputMethodInfoCompatWrapper(InputMethodInfo imi) {
+ mImi = imi;
+ }
+
+ public InputMethodInfo getInputMethodInfo() {
+ return mImi;
+ }
+
+ public String getId() {
+ return mImi.getId();
+ }
+
+ public String getPackageName() {
+ return mImi.getPackageName();
+ }
+
+ public ServiceInfo getServiceInfo() {
+ return mImi.getServiceInfo();
+ }
+
+ public int getSubtypeCount() {
+ return (Integer) CompatUtils.invoke(mImi, 0, METHOD_getSubtypeCount);
+ }
+
+ public InputMethodSubtypeCompatWrapper getSubtypeAt(int index) {
+ return new InputMethodSubtypeCompatWrapper(CompatUtils.invoke(mImi, null,
+ METHOD_getSubtypeAt, index));
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
new file mode 100644
index 000000000..1cc13f249
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
@@ -0,0 +1,227 @@
+/*
+ * 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 com.android.inputmethod.deprecated.LanguageSwitcherProxy;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.Utils;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+// TODO: Override this class with the concrete implementation if we need to take care of the
+// performance.
+public class InputMethodManagerCompatWrapper {
+ private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName();
+ private static final Method METHOD_getCurrentInputMethodSubtype =
+ CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype");
+ private static final Method METHOD_getEnabledInputMethodSubtypeList =
+ CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList",
+ InputMethodInfo.class, boolean.class);
+ private static final Method METHOD_getShortcutInputMethodsAndSubtypes =
+ CompatUtils.getMethod(InputMethodManager.class, "getShortcutInputMethodsAndSubtypes");
+ private static final Method METHOD_setInputMethodAndSubtype =
+ CompatUtils.getMethod(
+ InputMethodManager.class, "setInputMethodAndSubtype", IBinder.class,
+ String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype);
+ private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod(
+ InputMethodManager.class, "switchToLastInputMethod", IBinder.class);
+
+ private static final InputMethodManagerCompatWrapper sInstance =
+ new InputMethodManagerCompatWrapper();
+
+ public static final boolean SUBTYPE_SUPPORTED;
+
+ static {
+ // This static initializer guarantees that METHOD_getShortcutInputMethodsAndSubtypes is
+ // already instantiated.
+ SUBTYPE_SUPPORTED = METHOD_getShortcutInputMethodsAndSubtypes != null;
+ }
+
+ // For the compatibility, IMM will create dummy subtypes if subtypes are not found.
+ // This is required to be false if the current behavior is broken. For now, it's ok to be true.
+ public static final boolean FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES =
+ !InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED;
+ private static final String VOICE_MODE = "voice";
+ private static final String KEYBOARD_MODE = "keyboard";
+
+ private InputMethodManager mImm;
+ private LanguageSwitcherProxy mLanguageSwitcherProxy;
+ private String mLatinImePackageName;
+
+ private InputMethodManagerCompatWrapper() {
+ }
+
+ public static InputMethodManagerCompatWrapper getInstance(Context context) {
+ if (sInstance.mImm == null) {
+ sInstance.init(context);
+ }
+ return sInstance;
+ }
+
+ private synchronized void init(Context context) {
+ mImm = (InputMethodManager) context.getSystemService(
+ Context.INPUT_METHOD_SERVICE);
+ if (context instanceof LatinIME) {
+ mLatinImePackageName = context.getPackageName();
+ }
+ mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance();
+ }
+
+ public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() {
+ if (!SUBTYPE_SUPPORTED) {
+ return new InputMethodSubtypeCompatWrapper(
+ 0, 0, mLanguageSwitcherProxy.getInputLocale().toString(), KEYBOARD_MODE, "");
+ }
+ Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype);
+ return new InputMethodSubtypeCompatWrapper(o);
+ }
+
+ public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
+ InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
+ if (!SUBTYPE_SUPPORTED) {
+ String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(
+ allowsImplicitlySelectedSubtypes);
+ List<InputMethodSubtypeCompatWrapper> subtypeList =
+ new ArrayList<InputMethodSubtypeCompatWrapper>();
+ for (String lang: languages) {
+ subtypeList.add(new InputMethodSubtypeCompatWrapper(0, 0, lang, KEYBOARD_MODE, ""));
+ }
+ return subtypeList;
+ }
+ Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList,
+ (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes);
+ if (retval == null || !(retval instanceof List<?>) || ((List<?>)retval).isEmpty()) {
+ if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
+ // Returns an empty list
+ return Collections.emptyList();
+ }
+ // Creates dummy subtypes
+ @SuppressWarnings("unused")
+ List<InputMethodSubtypeCompatWrapper> subtypeList =
+ new ArrayList<InputMethodSubtypeCompatWrapper>();
+ InputMethodSubtypeCompatWrapper keyboardSubtype = getLastResortSubtype(KEYBOARD_MODE);
+ InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE);
+ if (keyboardSubtype != null) {
+ subtypeList.add(keyboardSubtype);
+ }
+ if (voiceSubtype != null) {
+ subtypeList.add(voiceSubtype);
+ }
+ return subtypeList;
+ }
+ return CompatUtils.copyInputMethodSubtypeListToWrapper(retval);
+ }
+
+ private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() {
+ if (TextUtils.isEmpty(mLatinImePackageName))
+ return null;
+ return Utils.getInputMethodInfo(this, mLatinImePackageName);
+ }
+
+ @SuppressWarnings("unused")
+ private InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) {
+ if (VOICE_MODE.equals(mode) && !FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES)
+ return null;
+ Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale();
+ if (inputLocale == null)
+ return null;
+ return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, "");
+ }
+
+ public Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
+ getShortcutInputMethodsAndSubtypes() {
+ Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes);
+ if (retval == null || !(retval instanceof Map<?, ?>) || ((Map<?, ?>)retval).isEmpty()) {
+ if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
+ // Returns an empty map
+ return Collections.emptyMap();
+ }
+ // Creates dummy subtypes
+ @SuppressWarnings("unused")
+ InputMethodInfoCompatWrapper imi = getLatinImeInputMethodInfo();
+ InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE);
+ if (imi != null && voiceSubtype != null) {
+ Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
+ shortcutMap =
+ new HashMap<InputMethodInfoCompatWrapper,
+ List<InputMethodSubtypeCompatWrapper>>();
+ List<InputMethodSubtypeCompatWrapper> subtypeList =
+ new ArrayList<InputMethodSubtypeCompatWrapper>();
+ subtypeList.add(voiceSubtype);
+ shortcutMap.put(imi, subtypeList);
+ return shortcutMap;
+ } else {
+ return Collections.emptyMap();
+ }
+ }
+ Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcutMap =
+ new HashMap<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>();
+ final Map<?, ?> retvalMap = (Map<?, ?>)retval;
+ for (Object key : retvalMap.keySet()) {
+ if (!(key instanceof InputMethodInfo)) {
+ Log.e(TAG, "Class type error.");
+ return null;
+ }
+ shortcutMap.put(new InputMethodInfoCompatWrapper((InputMethodInfo)key),
+ CompatUtils.copyInputMethodSubtypeListToWrapper(retvalMap.get(key)));
+ }
+ return shortcutMap;
+ }
+
+ public void setInputMethodAndSubtype(
+ IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) {
+ if (subtype != null && subtype.hasOriginalObject()) {
+ CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype,
+ token, id, subtype.getOriginalObject());
+ }
+ }
+
+ public boolean switchToLastInputMethod(IBinder token) {
+ if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) {
+ return true;
+ }
+ return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token);
+ }
+
+ public List<InputMethodInfoCompatWrapper> getEnabledInputMethodList() {
+ if (mImm == null) return null;
+ List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>();
+ for (InputMethodInfo imi : mImm.getEnabledInputMethodList()) {
+ imis.add(new InputMethodInfoCompatWrapper(imi));
+ }
+ return imis;
+ }
+
+ public void showInputMethodPicker() {
+ if (mImm == null) return;
+ mImm.showInputMethodPicker();
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java
new file mode 100644
index 000000000..7d8c745c3
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java
@@ -0,0 +1,84 @@
+/*
+ * 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.inputmethodservice.InputMethodService;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+
+public class InputMethodServiceCompatWrapper extends InputMethodService {
+ // CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10
+ // or previous. Note that InputMethodSubtype was added in the API level 11.
+ // For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged().
+ // For the API level 10 or previous, we handle the "subtype changed" events by ourselves
+ // without having support from framework -- onCurrentInputMethodSubtypeChanged().
+ public static final boolean CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED = true;
+
+ private InputMethodManagerCompatWrapper mImm;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mImm = InputMethodManagerCompatWrapper.getInstance(this);
+ }
+
+ // When the API level is 10 or previous, notifyOnCurrentInputMethodSubtypeChanged should
+ // handle the event the current subtype was changed. LatinIME calls
+ // notifyOnCurrentInputMethodSubtypeChanged every time LatinIME
+ // changes the current subtype.
+ // This call is required to let LatinIME itself know a subtype changed
+ // event when the API level is 10 or previous.
+ @SuppressWarnings("unused")
+ public void notifyOnCurrentInputMethodSubtypeChanged(InputMethodSubtypeCompatWrapper subtype) {
+ // Do nothing when the API level is 11 or later
+ // and FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES is not true
+ if (CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED && !InputMethodManagerCompatWrapper.
+ FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
+ return;
+ }
+ if (subtype == null) {
+ subtype = mImm.getCurrentInputMethodSubtype();
+ }
+ if (subtype != null) {
+ if (!InputMethodManagerCompatWrapper.FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES
+ && !subtype.isDummy()) return;
+ if (!InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) {
+ LanguageSwitcherProxy.getInstance().setLocale(subtype.getLocale());
+ }
+ SubtypeSwitcher.getInstance().updateSubtype(subtype);
+ }
+ }
+
+ //////////////////////////////////////
+ // Functions using API v11 or later //
+ //////////////////////////////////////
+ @Override
+ public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
+ // Do nothing when the API level is 10 or previous
+ if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) return;
+ SubtypeSwitcher.getInstance().updateSubtype(
+ new InputMethodSubtypeCompatWrapper(subtype));
+ }
+
+ protected static void setTouchableRegionCompat(InputMethodService.Insets outInsets,
+ int x, int y, int width, int height) {
+ outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
+ outInsets.touchableRegion.set(x, y, width, height);
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java
new file mode 100644
index 000000000..667d86c42
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java
@@ -0,0 +1,161 @@
+/*
+ * 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 com.android.inputmethod.latin.LatinImeLogger;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+// TODO: Override this class with the concrete implementation if we need to take care of the
+// performance.
+public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper {
+ private static final boolean DBG = LatinImeLogger.sDBG;
+ private static final String TAG = InputMethodSubtypeCompatWrapper.class.getSimpleName();
+ private static final String DEFAULT_LOCALE = "en_US";
+ private static final String DEFAULT_MODE = "keyboard";
+
+ public static final Class<?> CLASS_InputMethodSubtype =
+ CompatUtils.getClass("android.view.inputmethod.InputMethodSubtype");
+ private static final Method METHOD_getNameResId =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "getNameResId");
+ private static final Method METHOD_getIconResId =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "getIconResId");
+ private static final Method METHOD_getLocale =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "getLocale");
+ private static final Method METHOD_getMode =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "getMode");
+ private static final Method METHOD_getExtraValue =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValue");
+ private static final Method METHOD_containsExtraValueKey =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "containsExtraValueKey", String.class);
+ private static final Method METHOD_getExtraValueOf =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class);
+ private static final Method METHOD_isAuxiliary =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "isAuxiliary");
+
+ private final int mDummyNameResId;
+ private final int mDummyIconResId;
+ private final String mDummyLocale;
+ private final String mDummyMode;
+ private final String mDummyExtraValues;
+
+ public InputMethodSubtypeCompatWrapper(Object subtype) {
+ super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype))
+ ? subtype : null);
+ mDummyNameResId = 0;
+ mDummyIconResId = 0;
+ mDummyLocale = DEFAULT_LOCALE;
+ mDummyMode = DEFAULT_MODE;
+ mDummyExtraValues = "";
+ }
+
+ // Constructor for creating a dummy subtype.
+ public InputMethodSubtypeCompatWrapper(int nameResId, int iconResId, String locale,
+ String mode, String extraValues) {
+ super(null);
+ if (DBG) {
+ Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper");
+ }
+ mDummyNameResId = nameResId;
+ mDummyIconResId = iconResId;
+ mDummyLocale = locale != null ? locale : "";
+ mDummyMode = mode != null ? mode : "";
+ mDummyExtraValues = extraValues != null ? extraValues : "";
+ }
+
+ public int getNameResId() {
+ if (mObj == null) return mDummyNameResId;
+ return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getNameResId);
+ }
+
+ public int getIconResId() {
+ if (mObj == null) return mDummyIconResId;
+ return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getIconResId);
+ }
+
+ public String getLocale() {
+ if (mObj == null) return mDummyLocale;
+ final String s = (String)CompatUtils.invoke(mObj, null, METHOD_getLocale);
+ if (TextUtils.isEmpty(s)) return DEFAULT_LOCALE;
+ return s;
+ }
+
+ public String getMode() {
+ if (mObj == null) return mDummyMode;
+ String s = (String)CompatUtils.invoke(mObj, null, METHOD_getMode);
+ if (TextUtils.isEmpty(s)) return DEFAULT_MODE;
+ return s;
+ }
+
+ public String getExtraValue() {
+ if (mObj == null) return mDummyExtraValues;
+ return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValue);
+ }
+
+ public boolean containsExtraValueKey(String key) {
+ return (Boolean)CompatUtils.invoke(mObj, false, METHOD_containsExtraValueKey, key);
+ }
+
+ public String getExtraValueOf(String key) {
+ return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValueOf, key);
+ }
+
+ public boolean isAuxiliary() {
+ return (Boolean)CompatUtils.invoke(mObj, false, METHOD_isAuxiliary);
+ }
+
+ public boolean isDummy() {
+ return !hasOriginalObject();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof InputMethodSubtypeCompatWrapper) {
+ InputMethodSubtypeCompatWrapper subtype = (InputMethodSubtypeCompatWrapper)o;
+ if (mObj == null) {
+ // easy check of dummy subtypes
+ return (mDummyNameResId == subtype.mDummyNameResId
+ && mDummyIconResId == subtype.mDummyIconResId
+ && mDummyLocale.equals(subtype.mDummyLocale)
+ && mDummyMode.equals(subtype.mDummyMode)
+ && mDummyExtraValues.equals(subtype.mDummyExtraValues));
+ }
+ return mObj.equals(subtype.getOriginalObject());
+ } else {
+ return mObj.equals(o);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ if (mObj == null) {
+ return hashCodeInternal(mDummyNameResId, mDummyIconResId, mDummyLocale,
+ mDummyMode, mDummyExtraValues);
+ }
+ return mObj.hashCode();
+ }
+
+ private static int hashCodeInternal(int nameResId, int iconResId, String locale,
+ String mode, String extraValue) {
+ return Arrays
+ .hashCode(new Object[] { nameResId, iconResId, locale, mode, extraValue });
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java
new file mode 100644
index 000000000..6c2f0f799
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java
@@ -0,0 +1,118 @@
+/*
+ * 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.text.InputType;
+
+import java.lang.reflect.Field;
+
+public class InputTypeCompatUtils {
+ private static final Field FIELD_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS =
+ CompatUtils.getField(InputType.class, "TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS");
+ private static final Field FIELD_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD = CompatUtils
+ .getField(InputType.class, "TYPE_TEXT_VARIATION_WEB_PASSWORD");
+ private static final Field FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD = CompatUtils
+ .getField(InputType.class, "TYPE_NUMBER_VARIATION_PASSWORD");
+ private static final Integer OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS =
+ (Integer) CompatUtils.getFieldValue(null, null,
+ FIELD_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS);
+ private static final Integer OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD =
+ (Integer) CompatUtils.getFieldValue(null, null,
+ FIELD_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD);
+ private static final Integer OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD =
+ (Integer) CompatUtils.getFieldValue(null, null,
+ FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD);
+ private static final int WEB_TEXT_PASSWORD_INPUT_TYPE;
+ private static final int WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE;
+ private static final int NUMBER_PASSWORD_INPUT_TYPE;
+ private static final int TEXT_PASSWORD_INPUT_TYPE =
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+ private static final int TEXT_VISIBLE_PASSWORD_INPUT_TYPE =
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
+
+ static {
+ WEB_TEXT_PASSWORD_INPUT_TYPE =
+ OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD != null
+ ? InputType.TYPE_CLASS_TEXT | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD
+ : 0;
+ WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE =
+ OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != null
+ ? InputType.TYPE_CLASS_TEXT
+ | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS
+ : 0;
+ NUMBER_PASSWORD_INPUT_TYPE =
+ OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD != null
+ ? InputType.TYPE_CLASS_NUMBER | OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD
+ : 0;
+ }
+
+ private static boolean isWebEditTextInputType(int inputType) {
+ return inputType == (InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
+ }
+
+ private static boolean isWebPasswordInputType(int inputType) {
+ return WEB_TEXT_PASSWORD_INPUT_TYPE != 0
+ && inputType == WEB_TEXT_PASSWORD_INPUT_TYPE;
+ }
+
+ private static boolean isWebEmailAddressInputType(int inputType) {
+ return WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE != 0
+ && inputType == WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE;
+ }
+
+ private static boolean isNumberPasswordInputType(int inputType) {
+ return NUMBER_PASSWORD_INPUT_TYPE != 0
+ && inputType == NUMBER_PASSWORD_INPUT_TYPE;
+ }
+
+ private static boolean isTextPasswordInputType(int inputType) {
+ return inputType == TEXT_PASSWORD_INPUT_TYPE;
+ }
+
+ private static boolean isWebEmailAddressVariation(int variation) {
+ return OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != null
+ && variation == OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
+ }
+
+ public static boolean isEmailVariation(int variation) {
+ return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
+ || isWebEmailAddressVariation(variation);
+ }
+
+ public static boolean isWebInputType(int inputType) {
+ final int maskedInputType =
+ inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
+ return isWebEditTextInputType(maskedInputType) || isWebPasswordInputType(maskedInputType)
+ || isWebEmailAddressInputType(maskedInputType);
+ }
+
+ // Please refer to TextView.isPasswordInputType
+ public static boolean isPasswordInputType(int inputType) {
+ final int maskedInputType =
+ inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
+ return isTextPasswordInputType(maskedInputType) || isWebPasswordInputType(maskedInputType)
+ || isNumberPasswordInputType(maskedInputType);
+ }
+
+ // Please refer to TextView.isVisiblePasswordInputType
+ public static boolean isVisiblePasswordInputType(int inputType) {
+ final int maskedInputType =
+ inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
+ return maskedInputType == TEXT_VISIBLE_PASSWORD_INPUT_TYPE;
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java b/java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java
new file mode 100644
index 000000000..674cbe74b
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/LinearLayoutCompatUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+
+public class LinearLayoutCompatUtils {
+ private static final String TAG = LinearLayoutCompatUtils.class.getSimpleName();
+
+ private static final Class<?> CLASS_R_STYLEABLE = CompatUtils.getClass(
+ "com.android.internal.R$styleable");
+ private static final Field STYLEABLE_VIEW = CompatUtils.getField(
+ CLASS_R_STYLEABLE, "View");
+ private static final Field STYLEABLE_VIEW_BACKGROUND = CompatUtils.getField(
+ CLASS_R_STYLEABLE, "View_background");
+ private static final Object VALUE_STYLEABLE_VIEW = CompatUtils.getFieldValue(
+ null, null, STYLEABLE_VIEW);
+ private static final Integer VALUE_STYLEABLE_VIEW_BACKGROUND =
+ (Integer)CompatUtils.getFieldValue(null, null, STYLEABLE_VIEW_BACKGROUND);
+
+ public static Drawable getBackgroundDrawable(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ if (!(VALUE_STYLEABLE_VIEW instanceof int[]) || VALUE_STYLEABLE_VIEW_BACKGROUND == null) {
+ Log.w(TAG, "Can't get View background attribute using reflection");
+ return null;
+ }
+
+ final int[] styleableView = (int[])VALUE_STYLEABLE_VIEW;
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, styleableView, defStyleAttr, defStyleRes);
+ final Drawable background = a.getDrawable(VALUE_STYLEABLE_VIEW_BACKGROUND);
+ a.recycle();
+ return background;
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java b/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java
new file mode 100644
index 000000000..8518a4a78
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+public class MotionEventCompatUtils {
+ public static final int ACTION_HOVER_MOVE = 0x7;
+ public static final int ACTION_HOVER_ENTER = 0x9;
+ public static final int ACTION_HOVER_EXIT = 0xA;
+}
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
new file mode 100644
index 000000000..4929dd948
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -0,0 +1,87 @@
+/*
+ * 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 com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
+
+import android.content.Context;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextUtils;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Locale;
+
+public class SuggestionSpanUtils {
+ // TODO: Use reflection to get field values
+ public static final String ACTION_SUGGESTION_PICKED =
+ "android.text.style.SUGGESTION_PICKED";
+ public static final String SUGGESTION_SPAN_PICKED_AFTER = "after";
+ public static final String SUGGESTION_SPAN_PICKED_BEFORE = "before";
+ public static final String SUGGESTION_SPAN_PICKED_HASHCODE = "hashcode";
+ public static final int SUGGESTION_MAX_SIZE = 5;
+ public static final boolean SUGGESTION_SPAN_IS_SUPPORTED;
+
+ private static final Class<?> CLASS_SuggestionSpan = CompatUtils
+ .getClass("android.text.style.SuggestionSpan");
+ private static final Class<?>[] INPUT_TYPE_SuggestionSpan = new Class<?>[] {
+ Context.class, Locale.class, String[].class, int.class, Class.class };
+ private static final Constructor<?> CONSTRUCTOR_SuggestionSpan = CompatUtils
+ .getConstructor(CLASS_SuggestionSpan, INPUT_TYPE_SuggestionSpan);
+ static {
+ SUGGESTION_SPAN_IS_SUPPORTED =
+ CLASS_SuggestionSpan != null && CONSTRUCTOR_SuggestionSpan != null;
+ }
+
+ public static CharSequence getTextWithSuggestionSpan(Context context,
+ CharSequence pickedWord, SuggestedWords suggestedWords) {
+ if (TextUtils.isEmpty(pickedWord) || CONSTRUCTOR_SuggestionSpan == null
+ || suggestedWords == null || suggestedWords.size() == 0) {
+ return pickedWord;
+ }
+
+ final Spannable spannable;
+ if (pickedWord instanceof Spannable) {
+ spannable = (Spannable) pickedWord;
+ } else {
+ spannable = new SpannableString(pickedWord);
+ }
+ final ArrayList<String> suggestionsList = new ArrayList<String>();
+ for (int i = 0; i < suggestedWords.size(); ++i) {
+ if (suggestionsList.size() >= SUGGESTION_MAX_SIZE) {
+ break;
+ }
+ final CharSequence word = suggestedWords.getWord(i);
+ if (!TextUtils.equals(pickedWord, word)) {
+ suggestionsList.add(word.toString());
+ }
+ }
+
+ final Object[] args =
+ { context, null, suggestionsList.toArray(new String[suggestionsList.size()]), 0,
+ (Class<?>) SuggestionSpanPickedNotificationReceiver.class };
+ final Object ss = CompatUtils.newInstance(CONSTRUCTOR_SuggestionSpan, args);
+ if (ss == null) {
+ return pickedWord;
+ }
+ spannable.setSpan(ss, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return spannable;
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java b/java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java
new file mode 100644
index 000000000..8e2a2e0b8
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/VibratorCompatWrapper.java
@@ -0,0 +1,47 @@
+/*
+ * 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.content.Context;
+import android.os.Vibrator;
+
+import java.lang.reflect.Method;
+
+public class VibratorCompatWrapper {
+ private static final Method METHOD_hasVibrator = CompatUtils.getMethod(Vibrator.class,
+ "hasVibrator", int.class);
+
+ private static final VibratorCompatWrapper sInstance = new VibratorCompatWrapper();
+ private Vibrator mVibrator;
+
+ private VibratorCompatWrapper() {
+ }
+
+ public static VibratorCompatWrapper getInstance(Context context) {
+ if (sInstance.mVibrator == null) {
+ sInstance.mVibrator =
+ (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ }
+ return sInstance;
+ }
+
+ public boolean hasVibrator() {
+ if (mVibrator == null)
+ return false;
+ return (Boolean) CompatUtils.invoke(mVibrator, true, METHOD_hasVibrator);
+ }
+}
diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
new file mode 100644
index 000000000..290e6b554
--- /dev/null
+++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
@@ -0,0 +1,90 @@
+/*
+ * 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.deprecated;
+
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.Settings;
+
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+
+import java.util.Locale;
+
+// This class is used only when the IME doesn't use method.xml for language switching.
+public class LanguageSwitcherProxy implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy();
+ private LatinIME mService;
+ private LanguageSwitcher mLanguageSwitcher;
+ private SharedPreferences mPrefs;
+
+ public static LanguageSwitcherProxy getInstance() {
+ if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return null;
+ return sInstance;
+ }
+
+ public static void init(LatinIME service, SharedPreferences prefs) {
+ if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return;
+ final Configuration conf = service.getResources().getConfiguration();
+ sInstance.mLanguageSwitcher = new LanguageSwitcher(service);
+ sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale);
+ sInstance.mPrefs = prefs;
+ sInstance.mService = service;
+ prefs.registerOnSharedPreferenceChangeListener(sInstance);
+ }
+
+ public static void onConfigurationChanged(Configuration conf) {
+ if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return;
+ sInstance.mLanguageSwitcher.onConfigurationChanged(conf, sInstance.mPrefs);
+ }
+
+ public static void loadSettings() {
+ if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return;
+ sInstance.mLanguageSwitcher.loadLocales(sInstance.mPrefs, null);
+ }
+
+ public int getLocaleCount() {
+ return mLanguageSwitcher.getLocaleCount();
+ }
+
+ public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) {
+ return mLanguageSwitcher.getEnabledLanguages(allowImplicitlySelectedLanguages);
+ }
+
+ public Locale getInputLocale() {
+ return mLanguageSwitcher.getInputLocale();
+ }
+
+ public void setLocale(String localeStr) {
+ mLanguageSwitcher.setLocale(localeStr);
+ mLanguageSwitcher.persist(mPrefs);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ // PREF_SELECTED_LANGUAGES: enabled input subtypes
+ // PREF_INPUT_LANGUAGE: current input subtype
+ if (key.equals(Settings.PREF_SELECTED_LANGUAGES)
+ || key.equals(Settings.PREF_INPUT_LANGUAGE)) {
+ mLanguageSwitcher.loadLocales(prefs, null);
+ if (mService != null) {
+ mService.onRefreshKeyboard();
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index a244c9e41..85993ea4d 100644
--- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -14,8 +14,14 @@
* the License.
*/
-package com.android.inputmethod.voice;
-
+package com.android.inputmethod.deprecated;
+
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+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.deprecated.voice.VoiceInputLogger;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.latin.EditingUtils;
import com.android.inputmethod.latin.LatinIME;
@@ -28,6 +34,7 @@ import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.Utils;
import android.app.AlertDialog;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -54,7 +61,6 @@ import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import java.util.ArrayList;
@@ -62,8 +68,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-public class VoiceIMEConnector implements VoiceInput.UiListener {
- private static final VoiceIMEConnector sInstance = new VoiceIMEConnector();
+public class VoiceProxy implements VoiceInput.UiListener {
+ private static final VoiceProxy sInstance = new VoiceProxy();
public static final boolean VOICE_INSTALLED = true;
private static final boolean ENABLE_VOICE_BUTTON = true;
@@ -76,8 +82,10 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE =
"has_used_voice_input_unsupported_locale";
private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6;
+ // TODO: Adjusted on phones for now
+ private static final int RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP = 244;
- private static final String TAG = VoiceIMEConnector.class.getSimpleName();
+ private static final String TAG = VoiceProxy.class.getSimpleName();
private static final boolean DEBUG = LatinImeLogger.sDBG;
private boolean mAfterVoiceInput;
@@ -93,7 +101,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
private boolean mVoiceButtonOnPrimary;
private boolean mVoiceInputHighlighted;
- private InputMethodManager mImm;
+ private int mMinimumVoiceRecognitionViewHeightPixel;
+ private InputMethodManagerCompatWrapper mImm;
private LatinIME mService;
private AlertDialog mVoiceWarningDialog;
private VoiceInput mVoiceInput;
@@ -101,23 +110,26 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
private Hints mHints;
private UIHandler mHandler;
private SubtypeSwitcher mSubtypeSwitcher;
+
// For each word, a list of potential replacements, usually from voice.
private final Map<String, List<CharSequence>> mWordToSuggestions =
new HashMap<String, List<CharSequence>>();
- public static VoiceIMEConnector init(LatinIME context, SharedPreferences prefs, UIHandler h) {
+ public static VoiceProxy init(LatinIME context, SharedPreferences prefs, UIHandler h) {
sInstance.initInternal(context, prefs, h);
return sInstance;
}
- public static VoiceIMEConnector getInstance() {
+ public static VoiceProxy getInstance() {
return sInstance;
}
private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) {
mService = service;
mHandler = h;
- mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE);
+ mMinimumVoiceRecognitionViewHeightPixel = Utils.dipToPixel(
+ Utils.getDipScale(service), RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP);
+ mImm = InputMethodManagerCompatWrapper.getInstance(service);
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
if (VOICE_INSTALLED) {
mVoiceInput = new VoiceInput(service, this);
@@ -125,15 +137,15 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
@Override
public void showHint(int viewResource) {
View view = LayoutInflater.from(mService).inflate(viewResource, null);
- mService.setCandidatesView(view);
- mService.setCandidatesViewShown(true);
+// mService.setCandidatesView(view);
+// mService.setCandidatesViewShown(true);
mIsShowingHint = true;
}
});
}
}
- private VoiceIMEConnector() {
+ private VoiceProxy() {
// Intentional empty constructor for singleton.
}
@@ -429,7 +441,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
}
builder.setTypedWordValid(true).setHasMinimalSuggestion(true);
mService.setSuggestions(builder.build());
- mService.setCandidatesViewShown(true);
+// mService.setCandidatesViewShown(true);
return true;
}
return false;
@@ -514,7 +526,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
mHandler.post(new Runnable() {
@Override
public void run() {
- mService.setCandidatesViewShown(false);
+// mService.setCandidatesViewShown(false);
mRecognizing = true;
mVoiceInput.newView();
View v = mVoiceInput.getView();
@@ -524,7 +536,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
((ViewGroup) p).removeView(v);
}
- View keyboardView = KeyboardSwitcher.getInstance().getInputView();
+ View keyboardView = KeyboardSwitcher.getInstance().getKeyboardView();
// The full height of the keyboard is difficult to calculate
// as the dimension is expressed in "mm" and not in "pixel"
@@ -536,7 +548,11 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
mService.getResources().getDisplayMetrics().heightPixels;
final int currentHeight = popupLayout.getLayoutParams().height;
final int keyboardHeight = keyboardView.getHeight();
- if (keyboardHeight > currentHeight || keyboardHeight
+ if (mMinimumVoiceRecognitionViewHeightPixel > keyboardHeight
+ || mMinimumVoiceRecognitionViewHeightPixel > currentHeight) {
+ popupLayout.getLayoutParams().height =
+ mMinimumVoiceRecognitionViewHeightPixel;
+ } else if (keyboardHeight > currentHeight || keyboardHeight
> (displayHeight / RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO)) {
popupLayout.getLayoutParams().height = keyboardHeight;
}
@@ -560,14 +576,24 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
@Override
protected void onPostExecute(Boolean result) {
+ // Calls in this method need to be done in the same thread as the thread which
+ // called switchToLastInputMethod()
if (!result) {
if (DEBUG) {
Log.d(TAG, "Couldn't switch back to last IME.");
}
- // Needs to reset here because LatinIME failed to back to any IME and
- // the same voice subtype will be triggered in the next time.
+ // Because the current IME and subtype failed to switch to any other IME and
+ // subtype by switchToLastInputMethod, the current IME and subtype should keep
+ // being LatinIME and voice subtype in the next time. And for re-showing voice
+ // mode, the state of voice input should be reset and the voice view should be
+ // hidden.
mVoiceInput.reset();
mService.requestHideSelf(0);
+ } else {
+ // Notify an event that the current subtype was changed. This event will be
+ // handled if "onCurrentInputMethodSubtypeChanged" can't be implemented
+ // when the API level is 10 or previous.
+ mService.notifyOnCurrentInputMethodSubtypeChanged(null);
}
}
}.execute();
@@ -624,6 +650,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
}
private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) {
+ @SuppressWarnings("deprecation")
final boolean noMic = Utils.inPrivateImeOptions(null,
LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, attribute)
|| Utils.inPrivateImeOptions(mService.getPackageName(),
@@ -664,7 +691,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) {
// Close keyboard view if it is been shown.
if (KeyboardSwitcher.getInstance().isInputViewShown())
- KeyboardSwitcher.getInstance().getInputView().purgeKeyboardAndClosing();
+ KeyboardSwitcher.getInstance().getKeyboardView().purgeKeyboardAndClosing();
startListening(false, windowToken);
}
// If we have no token, onAttachedToWindow will take care of showing dialog and start
@@ -674,7 +701,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
public void onAttachedToWindow() {
// After onAttachedToWindow, we can show the voice warning dialog. See startListening()
// above.
- mSubtypeSwitcher.setVoiceInput(mVoiceInput);
+ VoiceInputWrapper.getInstance().setVoiceInput(mVoiceInput, mSubtypeSwitcher);
}
public void onConfigurationChanged(Configuration configuration) {
@@ -725,4 +752,91 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
List<String> candidates;
Map<String, List<CharSequence>> alternatives;
}
+
+ public static class VoiceLoggerWrapper {
+ private static final VoiceLoggerWrapper sLoggerWrapperInstance = new VoiceLoggerWrapper();
+ private VoiceInputLogger mLogger;
+
+ public static VoiceLoggerWrapper getInstance(Context context) {
+ if (sLoggerWrapperInstance.mLogger == null) {
+ // Not thread safe, but it's ok.
+ sLoggerWrapperInstance.mLogger = VoiceInputLogger.getLogger(context);
+ }
+ return sLoggerWrapperInstance;
+ }
+
+ // private for the singleton
+ private VoiceLoggerWrapper() {
+ }
+
+ public void settingsWarningDialogCancel() {
+ mLogger.settingsWarningDialogCancel();
+ }
+
+ public void settingsWarningDialogOk() {
+ mLogger.settingsWarningDialogOk();
+ }
+
+ public void settingsWarningDialogShown() {
+ mLogger.settingsWarningDialogShown();
+ }
+
+ public void settingsWarningDialogDismissed() {
+ mLogger.settingsWarningDialogDismissed();
+ }
+
+ public void voiceInputSettingEnabled(boolean enabled) {
+ if (enabled) {
+ mLogger.voiceInputSettingEnabled();
+ } else {
+ mLogger.voiceInputSettingDisabled();
+ }
+ }
+ }
+
+ public static class VoiceInputWrapper {
+ private static final VoiceInputWrapper sInputWrapperInstance = new VoiceInputWrapper();
+ private VoiceInput mVoiceInput;
+ public static VoiceInputWrapper getInstance() {
+ return sInputWrapperInstance;
+ }
+ public void setVoiceInput(VoiceInput voiceInput, SubtypeSwitcher switcher) {
+ if (mVoiceInput == null && voiceInput != null) {
+ mVoiceInput = voiceInput;
+ }
+ switcher.setVoiceInputWrapper(this);
+ }
+
+ private VoiceInputWrapper() {
+ }
+
+ public void cancel() {
+ if (mVoiceInput != null) mVoiceInput.cancel();
+ }
+
+ public void reset() {
+ if (mVoiceInput != null) mVoiceInput.reset();
+ }
+ }
+
+ // A list of locales which are supported by default for voice input, unless we get a
+ // different list from Gservices.
+ private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES =
+ "en " +
+ "en_US " +
+ "en_GB " +
+ "en_AU " +
+ "en_CA " +
+ "en_IE " +
+ "en_IN " +
+ "en_NZ " +
+ "en_SG " +
+ "en_ZA ";
+
+ public static String getSupportedLocalesString (ContentResolver resolver) {
+ return SettingsUtil.getSettingsString(
+ resolver,
+ SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
+ DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
+ }
}
diff --git a/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java b/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java
new file mode 100644
index 000000000..488390fbc
--- /dev/null
+++ b/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java
@@ -0,0 +1,36 @@
+/*
+ * 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.deprecated.compat;
+
+import com.android.common.userhappiness.UserHappinessSignals;
+import com.android.inputmethod.compat.CompatUtils;
+
+import java.lang.reflect.Method;
+
+public class VoiceInputLoggerCompatUtils {
+ public static final String EXTRA_TEXT_REPLACED_LENGTH = "length";
+ public static final String EXTRA_BEFORE_N_BEST_CHOOSE = "before";
+ public static final String EXTRA_AFTER_N_BEST_CHOOSE = "after";
+ private static final Method METHOD_UserHappinessSignals_setHasVoiceLoggingInfo =
+ CompatUtils.getMethod(UserHappinessSignals.class, "setHasVoiceLoggingInfo",
+ boolean.class);
+
+ public static void setHasVoiceLoggingInfoCompat(boolean hasLoggingInfo) {
+ CompatUtils.invoke(null, null, METHOD_UserHappinessSignals_setHasVoiceLoggingInfo,
+ hasLoggingInfo);
+ }
+}
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
new file mode 100644
index 000000000..cf6cd0f5e
--- /dev/null
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2008-2009 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.deprecated.languageswitcher;
+
+import com.android.inputmethod.keyboard.internal.KeyboardParser;
+import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.SharedPreferencesCompat;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.Utils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import java.io.IOException;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+public class InputLanguageSelection extends PreferenceActivity {
+
+ private SharedPreferences mPrefs;
+ private String mSelectedLanguages;
+ private HashMap<CheckBoxPreference, Locale> mLocaleMap =
+ new HashMap<CheckBoxPreference, Locale>();
+
+ private static class LocaleEntry implements Comparable<Object> {
+ private static Collator sCollator = Collator.getInstance();
+
+ private String mLabel;
+ public final Locale mLocale;
+
+ public LocaleEntry(String label, Locale locale) {
+ this.mLabel = label;
+ this.mLocale = locale;
+ }
+
+ @Override
+ public String toString() {
+ return this.mLabel;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return sCollator.compare(this.mLabel, ((LocaleEntry) o).mLabel);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.language_prefs);
+ // Get the settings preferences
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, "");
+ String[] languageList = mSelectedLanguages.split(",");
+ ArrayList<LocaleEntry> availableLanguages = getUniqueLocales();
+ PreferenceGroup parent = getPreferenceScreen();
+ final HashMap<Long, LocaleEntry> dictionaryIdLocaleMap = new HashMap<Long, LocaleEntry>();
+ final TreeMap<LocaleEntry, Boolean> localeHasDictionaryMap =
+ new TreeMap<LocaleEntry, Boolean>();
+ for (int i = 0; i < availableLanguages.size(); i++) {
+ LocaleEntry loc = availableLanguages.get(i);
+ Locale locale = loc.mLocale;
+ final Pair<Long, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale);
+ final Long dictionaryId = hasDictionaryOrLayout.first;
+ final boolean hasLayout = hasDictionaryOrLayout.second;
+ final boolean hasDictionary = dictionaryId != null;
+ // Add this locale to the supported list if:
+ // 1) this locale has a layout/ 2) this locale has a dictionary
+ // If some locales have no layout but have a same dictionary, the shortest locale
+ // will be added to the supported list.
+ if (!hasLayout && !hasDictionary) {
+ continue;
+ }
+ if (hasLayout) {
+ localeHasDictionaryMap.put(loc, hasDictionary);
+ }
+ if (!hasDictionary) {
+ continue;
+ }
+ if (dictionaryIdLocaleMap.containsKey(dictionaryId)) {
+ final String newLocale = locale.toString();
+ final String oldLocale =
+ dictionaryIdLocaleMap.get(dictionaryId).mLocale.toString();
+ // Check if this locale is more appropriate to be the candidate of the input locale.
+ if (oldLocale.length() <= newLocale.length() && !hasLayout) {
+ // Don't add this new locale to the map<dictionary id, locale> if:
+ // 1) the new locale's name is longer than the existing one, and
+ // 2) the new locale doesn't have its layout
+ continue;
+ }
+ }
+ dictionaryIdLocaleMap.put(dictionaryId, loc);
+ }
+
+ for (LocaleEntry localeEntry : dictionaryIdLocaleMap.values()) {
+ if (!localeHasDictionaryMap.containsKey(localeEntry)) {
+ localeHasDictionaryMap.put(localeEntry, true);
+ }
+ }
+
+ for (Entry<LocaleEntry, Boolean> entry : localeHasDictionaryMap.entrySet()) {
+ final LocaleEntry localeEntry = entry.getKey();
+ final Locale locale = localeEntry.mLocale;
+ final Boolean hasDictionary = entry.getValue();
+ CheckBoxPreference pref = new CheckBoxPreference(this);
+ pref.setTitle(localeEntry.mLabel);
+ boolean checked = isLocaleIn(locale, languageList);
+ pref.setChecked(checked);
+ if (hasDictionary) {
+ pref.setSummary(R.string.has_dictionary);
+ }
+ mLocaleMap.put(pref, locale);
+ parent.addPreference(pref);
+ }
+ }
+
+ private boolean isLocaleIn(Locale locale, String[] list) {
+ String lang = get5Code(locale);
+ for (int i = 0; i < list.length; i++) {
+ if (lang.equalsIgnoreCase(list[i])) return true;
+ }
+ return false;
+ }
+
+ private Pair<Long, Boolean> hasDictionaryOrLayout(Locale locale) {
+ if (locale == null) return new Pair<Long, Boolean>(null, false);
+ final Resources res = getResources();
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+ final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale);
+ boolean hasLayout = false;
+
+ try {
+ final String localeStr = locale.toString();
+ final String[] layoutCountryCodes = KeyboardParser.parseKeyboardLocale(
+ this, R.xml.kbd_qwerty).split(",", -1);
+ if (!TextUtils.isEmpty(localeStr) && layoutCountryCodes.length > 0) {
+ for (String s : layoutCountryCodes) {
+ if (s.equals(localeStr)) {
+ hasLayout = true;
+ break;
+ }
+ }
+ }
+ } catch (XmlPullParserException e) {
+ } catch (IOException e) {
+ }
+ Utils.setSystemLocale(res, saveLocale);
+ return new Pair<Long, Boolean>(dictionaryId, hasLayout);
+ }
+
+ private String get5Code(Locale locale) {
+ String country = locale.getCountry();
+ return locale.getLanguage()
+ + (TextUtils.isEmpty(country) ? "" : "_" + country);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ // Save the selected languages
+ String checkedLanguages = "";
+ PreferenceGroup parent = getPreferenceScreen();
+ int count = parent.getPreferenceCount();
+ for (int i = 0; i < count; i++) {
+ CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i);
+ if (pref.isChecked()) {
+ checkedLanguages += get5Code(mLocaleMap.get(pref)) + ",";
+ }
+ }
+ if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null
+ Editor editor = mPrefs.edit();
+ editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages);
+ SharedPreferencesCompat.apply(editor);
+ }
+
+ public ArrayList<LocaleEntry> getUniqueLocales() {
+ String[] locales = getAssets().getLocales();
+ Arrays.sort(locales);
+ ArrayList<LocaleEntry> uniqueLocales = new ArrayList<LocaleEntry>();
+
+ final int origSize = locales.length;
+ LocaleEntry[] preprocess = new LocaleEntry[origSize];
+ int finalSize = 0;
+ for (int i = 0 ; i < origSize; i++ ) {
+ String s = locales[i];
+ int len = s.length();
+ String language = "";
+ String country = "";
+ if (len == 5) {
+ language = s.substring(0, 2);
+ country = s.substring(3, 5);
+ } else if (len < 5) {
+ language = s;
+ }
+ Locale l = new Locale(language, country);
+
+ // Exclude languages that are not relevant to LatinIME
+ if (TextUtils.isEmpty(language)) {
+ continue;
+ }
+
+ if (finalSize == 0) {
+ preprocess[finalSize++] =
+ new LocaleEntry(SubtypeSwitcher.getFullDisplayName(l, false), l);
+ } else {
+ if (s.equals("zz_ZZ")) {
+ // ignore this locale
+ } else {
+ final String displayName = SubtypeSwitcher.getFullDisplayName(l, false);
+ preprocess[finalSize++] = new LocaleEntry(displayName, l);
+ }
+ }
+ }
+ for (int i = 0; i < finalSize ; i++) {
+ uniqueLocales.add(preprocess[i]);
+ }
+ return uniqueLocales;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
index 2dd3038f9..1eedb5ee1 100644
--- a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
@@ -14,11 +14,19 @@
* the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.deprecated.languageswitcher;
+
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.SharedPreferencesCompat;
+import com.android.inputmethod.latin.Utils;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
+import android.content.res.Configuration;
import android.text.TextUtils;
+import android.util.Log;
import java.util.ArrayList;
import java.util.Locale;
@@ -28,10 +36,15 @@ import java.util.Locale;
* input language that the user has selected.
*/
public class LanguageSwitcher {
+ private static final String TAG = LanguageSwitcher.class.getSimpleName();
+
+ @SuppressWarnings("unused")
+ private static final String KEYBOARD_MODE = "keyboard";
+ private static final String[] EMPTY_STIRNG_ARRAY = new String[0];
private final ArrayList<Locale> mLocales = new ArrayList<Locale>();
private final LatinIME mIme;
- private String[] mSelectedLanguageArray;
+ private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY;
private String mSelectedLanguages;
private int mCurrentIndex = 0;
private String mDefaultInputLanguage;
@@ -46,15 +59,32 @@ public class LanguageSwitcher {
return mLocales.size();
}
+ public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) {
+ final Locale newLocale = conf.locale;
+ if (!getSystemLocale().toString().equals(newLocale.toString())) {
+ loadLocales(prefs, newLocale);
+ }
+ }
+
/**
* Loads the currently selected input languages from shared preferences.
- * @param sp
+ * @param sp shared preference for getting the current input language and enabled languages
+ * @param systemLocale the current system locale, stored for changing the current input language
+ * based on the system current system locale.
* @return whether there was any change
*/
- public boolean loadLocales(SharedPreferences sp) {
+ public boolean loadLocales(SharedPreferences sp, Locale systemLocale) {
+ if (LatinImeLogger.sDBG) {
+ Log.d(TAG, "load locales");
+ }
+ if (systemLocale != null) {
+ setSystemLocale(systemLocale);
+ }
String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null);
String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null);
- if (selectedLanguages == null || selectedLanguages.length() < 1) {
+ if (TextUtils.isEmpty(selectedLanguages)) {
+ mSelectedLanguageArray = EMPTY_STIRNG_ARRAY;
+ mSelectedLanguages = null;
loadDefaults();
if (mLocales.size() == 0) {
return false;
@@ -84,6 +114,9 @@ public class LanguageSwitcher {
}
private void loadDefaults() {
+ if (LatinImeLogger.sDBG) {
+ Log.d(TAG, "load default locales:");
+ }
mDefaultInputLocale = mIme.getResources().getConfiguration().locale;
String country = mDefaultInputLocale.getCountry();
mDefaultInputLanguage = mDefaultInputLocale.getLanguage() +
@@ -93,8 +126,7 @@ public class LanguageSwitcher {
private void constructLocales() {
mLocales.clear();
for (final String lang : mSelectedLanguageArray) {
- final Locale locale = new Locale(lang.substring(0, 2),
- lang.length() > 4 ? lang.substring(3, 5) : "");
+ final Locale locale = Utils.constructLocaleFromString(lang);
mLocales.add(locale);
}
}
@@ -112,14 +144,16 @@ public class LanguageSwitcher {
/**
* Returns the list of enabled language codes.
*/
- public String[] getEnabledLanguages() {
+ public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) {
+ if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) {
+ return new String[] { mDefaultInputLanguage };
+ }
return mSelectedLanguageArray;
}
/**
* Returns the currently selected input locale, or the display locale if no specific
* locale was selected for input.
- * @return
*/
public Locale getInputLocale() {
if (getLocaleCount() == 0) return mDefaultInputLocale;
@@ -140,7 +174,6 @@ public class LanguageSwitcher {
/**
* Returns the next input locale in the list. Wraps around to the beginning of the
* list if we're at the end of the list.
- * @return
*/
public Locale getNextInputLocale() {
if (getLocaleCount() == 0) return mDefaultInputLocale;
@@ -151,7 +184,7 @@ public class LanguageSwitcher {
* Sets the system locale (display UI) used for comparing with the input language.
* @param locale the locale of the system
*/
- public void setSystemLocale(Locale locale) {
+ private void setSystemLocale(Locale locale) {
mSystemLocale = locale;
}
@@ -159,14 +192,13 @@ public class LanguageSwitcher {
* Returns the system locale.
* @return the system locale
*/
- public Locale getSystemLocale() {
+ private Locale getSystemLocale() {
return mSystemLocale;
}
/**
* Returns the previous input locale in the list. Wraps around to the end of the
* list if we're at the beginning of the list.
- * @return
*/
public Locale getPrevInputLocale() {
if (getLocaleCount() == 0) return mDefaultInputLocale;
@@ -185,6 +217,15 @@ public class LanguageSwitcher {
mCurrentIndex = prevLocaleIndex();
}
+ public void setLocale(String localeStr) {
+ final int N = mLocales.size();
+ for (int i = 0; i < N; ++i) {
+ if (mLocales.get(i).toString().equals(localeStr)) {
+ mCurrentIndex = i;
+ }
+ }
+ }
+
public void persist(SharedPreferences prefs) {
Editor editor = prefs.edit();
editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage());
diff --git a/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java
new file mode 100644
index 000000000..d40728d25
--- /dev/null
+++ b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java
@@ -0,0 +1,287 @@
+/*
+ * 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.deprecated.recorrection;
+
+import com.android.inputmethod.compat.InputConnectionCompatUtils;
+import com.android.inputmethod.compat.SuggestionSpanUtils;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.AutoCorrection;
+import com.android.inputmethod.latin.CandidateView;
+import com.android.inputmethod.latin.EditingUtils;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.TextEntryState;
+import com.android.inputmethod.latin.WordComposer;
+
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.text.TextUtils;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
+
+import java.util.ArrayList;
+
+/**
+ * Manager of re-correction functionalities
+ */
+public class Recorrection implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final Recorrection sInstance = new Recorrection();
+
+ private LatinIME mService;
+ private boolean mRecorrectionEnabled = false;
+ private final ArrayList<RecorrectionSuggestionEntries> mRecorrectionSuggestionsList =
+ new ArrayList<RecorrectionSuggestionEntries>();
+
+ public static Recorrection getInstance() {
+ return sInstance;
+ }
+
+ public static void init(LatinIME context, SharedPreferences prefs) {
+ if (context == null || prefs == null) {
+ return;
+ }
+ sInstance.initInternal(context, prefs);
+ }
+
+ private Recorrection() {
+ }
+
+ public boolean isRecorrectionEnabled() {
+ return mRecorrectionEnabled;
+ }
+
+ private void initInternal(LatinIME context, SharedPreferences prefs) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) {
+ mRecorrectionEnabled = false;
+ return;
+ }
+ updateRecorrectionEnabled(context.getResources(), prefs);
+ mService = context;
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ public void checkRecorrectionOnStart() {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
+
+ final InputConnection ic = mService.getCurrentInputConnection();
+ if (ic == null) return;
+ // There could be a pending composing span. Clean it up first.
+ ic.finishComposingText();
+
+ if (mService.isShowingSuggestionsStrip() && mService.isSuggestionsRequested()) {
+ // First get the cursor position. This is required by setOldSuggestions(), so that
+ // it can pass the correct range to setComposingRegion(). At this point, we don't
+ // have valid values for mLastSelectionStart/End because onUpdateSelection() has
+ // not been called yet.
+ ExtractedTextRequest etr = new ExtractedTextRequest();
+ etr.token = 0; // anything is fine here
+ ExtractedText et = ic.getExtractedText(etr, 0);
+ if (et == null) return;
+ mService.setLastSelection(
+ et.startOffset + et.selectionStart, et.startOffset + et.selectionEnd);
+
+ // Then look for possible corrections in a delayed fashion
+ if (!TextUtils.isEmpty(et.text) && mService.isCursorTouchingWord()) {
+ mService.mHandler.postUpdateOldSuggestions();
+ }
+ }
+ }
+
+ public void updateRecorrectionSelection(KeyboardSwitcher keyboardSwitcher,
+ CandidateView candidateView, int candidatesStart, int candidatesEnd,
+ int newSelStart, int newSelEnd, int oldSelStart, int lastSelectionStart,
+ int lastSelectionEnd, boolean hasUncommittedTypedChars) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
+ if (!mService.isShowingSuggestionsStrip()) return;
+ if (!keyboardSwitcher.isInputViewShown()) return;
+ if (!mService.isSuggestionsRequested()) return;
+ // Don't look for corrections if the keyboard is not visible
+ // Check if we should go in or out of correction mode.
+ if ((candidatesStart == candidatesEnd || newSelStart != oldSelStart || TextEntryState
+ .isRecorrecting())
+ && (newSelStart < newSelEnd - 1 || !hasUncommittedTypedChars)) {
+ if (mService.isCursorTouchingWord() || lastSelectionStart < lastSelectionEnd) {
+ mService.mHandler.cancelUpdateBigramPredictions();
+ mService.mHandler.postUpdateOldSuggestions();
+ } else {
+ abortRecorrection(false);
+ // If showing the "touch again to save" hint, do not replace it. Else,
+ // show the bigrams if we are at the end of the text, punctuation
+ // otherwise.
+ if (candidateView != null && !candidateView.isShowingAddToDictionaryHint()) {
+ InputConnection ic = mService.getCurrentInputConnection();
+ if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) {
+ if (!mService.isShowingPunctuationList()) {
+ mService.setPunctuationSuggestions();
+ }
+ } else {
+ mService.mHandler.postUpdateBigramPredictions();
+ }
+ }
+ }
+ }
+ }
+
+ public void saveRecorrectionSuggestion(WordComposer word, CharSequence result) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
+ if (word.size() <= 1) {
+ return;
+ }
+ // Skip if result is null. It happens in some edge case.
+ if (TextUtils.isEmpty(result)) {
+ return;
+ }
+
+ // Make a copy of the CharSequence, since it is/could be a mutable CharSequence
+ final String resultCopy = result.toString();
+ RecorrectionSuggestionEntries entry = new RecorrectionSuggestionEntries(
+ resultCopy, new WordComposer(word));
+ mRecorrectionSuggestionsList.add(entry);
+ }
+
+ public void clearWordsInHistory() {
+ mRecorrectionSuggestionsList.clear();
+ }
+
+ /**
+ * Tries to apply any typed alternatives for the word if we have any cached alternatives,
+ * otherwise tries to find new corrections and completions for the word.
+ * @param touching The word that the cursor is touching, with position information
+ * @return true if an alternative was found, false otherwise.
+ */
+ public boolean applyTypedAlternatives(WordComposer word, Suggest suggest,
+ KeyboardSwitcher keyboardSwitcher, EditingUtils.SelectedWord touching) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return false;
+ // If we didn't find a match, search for result in typed word history
+ WordComposer foundWord = null;
+ RecorrectionSuggestionEntries alternatives = null;
+ // Search old suggestions to suggest re-corrected suggestions.
+ for (RecorrectionSuggestionEntries entry : mRecorrectionSuggestionsList) {
+ if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) {
+ foundWord = entry.mWordComposer;
+ alternatives = entry;
+ break;
+ }
+ }
+ // If we didn't find a match, at least suggest corrections as re-corrected suggestions.
+ if (foundWord == null
+ && (AutoCorrection.isValidWord(suggest.getUnigramDictionaries(),
+ touching.mWord, true))) {
+ foundWord = new WordComposer();
+ for (int i = 0; i < touching.mWord.length(); i++) {
+ foundWord.add(touching.mWord.charAt(i),
+ new int[] { touching.mWord.charAt(i) }, WordComposer.NOT_A_COORDINATE,
+ WordComposer.NOT_A_COORDINATE);
+ }
+ foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0)));
+ }
+ // Found a match, show suggestions
+ if (foundWord != null || alternatives != null) {
+ if (alternatives == null) {
+ alternatives = new RecorrectionSuggestionEntries(touching.mWord, foundWord);
+ }
+ showRecorrections(suggest, keyboardSwitcher, alternatives);
+ if (foundWord != null) {
+ word.init(foundWord);
+ } else {
+ word.reset();
+ }
+ return true;
+ }
+ return false;
+ }
+
+
+ private void showRecorrections(Suggest suggest, KeyboardSwitcher keyboardSwitcher,
+ RecorrectionSuggestionEntries entries) {
+ SuggestedWords.Builder builder = entries.getAlternatives(suggest, keyboardSwitcher);
+ builder.setTypedWordValid(false).setHasMinimalSuggestion(false);
+ mService.showSuggestions(builder.build(), entries.getOriginalWord());
+ }
+
+ public void fetchAndDisplayRecorrectionSuggestions(VoiceProxy voiceProxy,
+ CandidateView candidateView, Suggest suggest, KeyboardSwitcher keyboardSwitcher,
+ WordComposer word, boolean hasUncommittedTypedChars, int lastSelectionStart,
+ int lastSelectionEnd, String wordSeparators) {
+ if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) return;
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
+ voiceProxy.setShowingVoiceSuggestions(false);
+ if (candidateView != null && candidateView.isShowingAddToDictionaryHint()) {
+ return;
+ }
+ InputConnection ic = mService.getCurrentInputConnection();
+ if (ic == null) return;
+ if (!hasUncommittedTypedChars) {
+ // Extract the selected or touching text
+ EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic,
+ lastSelectionStart, lastSelectionEnd, wordSeparators);
+
+ if (touching != null && touching.mWord.length() > 1) {
+ ic.beginBatchEdit();
+
+ if (applyTypedAlternatives(word, suggest, keyboardSwitcher, touching)
+ || voiceProxy.applyVoiceAlternatives(touching)) {
+ TextEntryState.selectedForRecorrection();
+ InputConnectionCompatUtils.underlineWord(ic, touching);
+ } else {
+ abortRecorrection(true);
+ }
+
+ ic.endBatchEdit();
+ } else {
+ abortRecorrection(true);
+ mService.updateBigramPredictions();
+ }
+ } else {
+ abortRecorrection(true);
+ }
+ }
+
+ public void abortRecorrection(boolean force) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) return;
+ if (force || TextEntryState.isRecorrecting()) {
+ TextEntryState.onAbortRecorrection();
+ mService.setCandidatesViewShown(mService.isCandidateStripVisible());
+ mService.getCurrentInputConnection().finishComposingText();
+ mService.clearSuggestions();
+ }
+ }
+
+ public void updateRecorrectionEnabled(Resources res, SharedPreferences prefs) {
+ // If the option should not be shown, do not read the re-correction preference
+ // but always use the default setting defined in the resources.
+ if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
+ mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
+ res.getBoolean(R.bool.config_default_recorrection_enabled));
+ } else {
+ mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled);
+ }
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) return;
+ if (key.equals(Settings.PREF_RECORRECTION_ENABLED)) {
+ updateRecorrectionEnabled(mService.getResources(), prefs);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java
new file mode 100644
index 000000000..5e6c87044
--- /dev/null
+++ b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java
@@ -0,0 +1,62 @@
+/*
+ * 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.deprecated.recorrection;
+
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.WordComposer;
+
+import android.text.TextUtils;
+
+public class RecorrectionSuggestionEntries {
+ public final CharSequence mChosenWord;
+ public final WordComposer mWordComposer;
+
+ public RecorrectionSuggestionEntries(CharSequence chosenWord, WordComposer wordComposer) {
+ mChosenWord = chosenWord;
+ mWordComposer = wordComposer;
+ }
+
+ public CharSequence getChosenWord() {
+ return mChosenWord;
+ }
+
+ public CharSequence getOriginalWord() {
+ return mWordComposer.getTypedWord();
+ }
+
+ public SuggestedWords.Builder getAlternatives(
+ Suggest suggest, KeyboardSwitcher keyboardSwitcher) {
+ return getTypedSuggestions(suggest, keyboardSwitcher, mWordComposer);
+ }
+
+ @Override
+ public int hashCode() {
+ return mChosenWord.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof CharSequence && TextUtils.equals(mChosenWord, (CharSequence)o);
+ }
+
+ private static SuggestedWords.Builder getTypedSuggestions(
+ Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word) {
+ return suggest.getSuggestedWordBuilder(keyboardSwitcher.getKeyboardView(), word, null);
+ }
+}
diff --git a/java/src/com/android/inputmethod/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
index 95c7f5be0..3c79cc218 100644
--- a/java/src/com/android/inputmethod/voice/FieldContext.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import android.os.Bundle;
import android.util.Log;
diff --git a/java/src/com/android/inputmethod/voice/Hints.java b/java/src/com/android/inputmethod/deprecated/voice/Hints.java
index f5689092f..06b234381 100644
--- a/java/src/com/android/inputmethod/voice/Hints.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/Hints.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SharedPreferencesCompat;
diff --git a/java/src/com/android/inputmethod/voice/RecognitionView.java b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
index d26a877d5..dcb826e8f 100644
--- a/java/src/com/android/inputmethod/voice/RecognitionView.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
@@ -50,7 +50,6 @@ import java.util.Locale;
* plays beeps, shows errors, etc.
*/
public class RecognitionView {
- @SuppressWarnings("unused")
private static final String TAG = "RecognitionView";
private Handler mUiHandler; // Reference to UI thread
diff --git a/java/src/com/android/inputmethod/voice/SettingsUtil.java b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
index 372e8d6da..855a09a1d 100644
--- a/java/src/com/android/inputmethod/voice/SettingsUtil.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import android.content.ContentResolver;
import android.provider.Settings;
diff --git a/java/src/com/android/inputmethod/voice/SoundIndicator.java b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
index 40b68996a..25b314085 100644
--- a/java/src/com/android/inputmethod/voice/SoundIndicator.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import android.content.Context;
import android.graphics.Bitmap;
diff --git a/java/src/com/android/inputmethod/voice/VoiceInput.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
index 392eea364..8969a2168 100644
--- a/java/src/com/android/inputmethod/voice/VoiceInput.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
@@ -14,11 +14,12 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import com.android.inputmethod.latin.EditingUtils;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
import android.content.ContentResolver;
import android.content.Context;
@@ -26,7 +27,6 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.speech.RecognitionListener;
@@ -129,16 +129,23 @@ public class VoiceInput implements OnClickListener {
private int mAfterVoiceInputSelectionSpan = 0;
private int mState = DEFAULT;
-
+
private final static int MSG_RESET = 1;
- private final Handler mHandler = new Handler() {
+ private final UIHandler mHandler = new UIHandler(this);
+
+ private static class UIHandler extends StaticInnerHandlerWrapper<VoiceInput> {
+ public UIHandler(VoiceInput outerInstance) {
+ super(outerInstance);
+ }
+
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_RESET) {
- mState = DEFAULT;
- mRecognitionView.finish();
- mUiListener.onCancelVoice();
+ final VoiceInput voiceInput = getOuterInstance();
+ voiceInput.mState = DEFAULT;
+ voiceInput.mRecognitionView.finish();
+ voiceInput.mUiListener.onCancelVoice();
}
}
};
@@ -192,7 +199,7 @@ public class VoiceInput implements OnClickListener {
}
mBlacklist = new Whitelist();
- mBlacklist.addApp("com.android.setupwizard");
+ mBlacklist.addApp("com.google.android.setupwizard");
}
public void setCursorPos(int pos) {
diff --git a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
index 07f2bd1c5..22e8207bf 100644
--- a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
@@ -14,10 +14,10 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import com.android.common.speech.LoggingEvents;
-import com.android.common.userhappiness.UserHappinessSignals;
+import com.android.inputmethod.deprecated.compat.VoiceInputLoggerCompatUtils;
import android.content.Context;
import android.content.Intent;
@@ -212,13 +212,12 @@ public class VoiceInputLogger {
setHasLoggingInfo(true);
Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED);
i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, suggestionLength);
- i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_REPLACED_LENGTH, replacedPhraseLength);
+ i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_TEXT_REPLACED_LENGTH, replacedPhraseLength);
i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE,
LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_CHOOSE_SUGGESTION);
-
i.putExtra(LoggingEvents.VoiceIme.EXTRA_N_BEST_CHOOSE_INDEX, index);
- i.putExtra(LoggingEvents.VoiceIme.EXTRA_BEFORE_N_BEST_CHOOSE, before);
- i.putExtra(LoggingEvents.VoiceIme.EXTRA_AFTER_N_BEST_CHOOSE, after);
+ i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_BEFORE_N_BEST_CHOOSE, before);
+ i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_AFTER_N_BEST_CHOOSE, after);
mContext.sendBroadcast(i);
}
@@ -257,7 +256,7 @@ public class VoiceInputLogger {
// 2. type subject in subject field
// 3. speak message in message field
// 4. press send
- UserHappinessSignals.setHasVoiceLoggingInfo(hasLoggingInfo);
+ VoiceInputLoggerCompatUtils.setHasVoiceLoggingInfoCompat(hasLoggingInfo);
}
private boolean hasLoggingInfo(){
diff --git a/java/src/com/android/inputmethod/voice/WaveformImage.java b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
index b0ea99b79..8ed279f42 100644
--- a/java/src/com/android/inputmethod/voice/WaveformImage.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import android.graphics.Bitmap;
import android.graphics.Canvas;
diff --git a/java/src/com/android/inputmethod/voice/Whitelist.java b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
index adbd59135..6c5f52ae2 100644
--- a/java/src/com/android/inputmethod/voice/Whitelist.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.voice;
+package com.android.inputmethod.deprecated.voice;
import android.os.Bundle;
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 98a7f98c2..955885366 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -19,12 +19,18 @@ package com.android.inputmethod.keyboard;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Xml;
-import com.android.inputmethod.keyboard.KeyStyles.KeyStyle;
-import com.android.inputmethod.keyboard.KeyboardParser.ParseException;
+import com.android.inputmethod.keyboard.internal.KeyStyles;
+import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle;
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.internal.KeyboardParser;
+import com.android.inputmethod.keyboard.internal.KeyboardParser.ParseException;
+import com.android.inputmethod.keyboard.internal.PopupCharactersParser;
+import com.android.inputmethod.keyboard.internal.Row;
import com.android.inputmethod.latin.R;
import java.util.ArrayList;
@@ -37,32 +43,39 @@ public class Key {
* The key code (unicode or custom code) that this key generates.
*/
public final int mCode;
- /** The unicode that this key generates in manual temporary upper case mode. */
- public final int mManualTemporaryUpperCaseCode;
/** Label to display */
public final CharSequence mLabel;
+ /** Hint label to display on the key in conjunction with the label */
+ public final CharSequence mHintLabel;
/** Option of the label */
public final int mLabelOption;
+ public static final int LABEL_OPTION_ALIGN_LEFT = 0x01;
+ public static final int LABEL_OPTION_ALIGN_RIGHT = 0x02;
+ public 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;
/** Icon to display instead of a label. Icon takes precedence over a label */
private Drawable mIcon;
/** Preview version of the icon, for the preview popup */
private Drawable mPreviewIcon;
- /** Hint icon to display on the key in conjunction with the label */
- public final Drawable mHintIcon;
- /**
- * The hint icon to display on the key when keyboard is in manual temporary upper case
- * mode.
- */
- public final Drawable mManualTemporaryUpperCaseHintIcon;
/** Width of the key, not including the gap */
public final int mWidth;
/** Height of the key, not including the gap */
public final int mHeight;
- /** The horizontal gap before this key */
+ /** The horizontal gap around this key */
public final int mGap;
+ /** The visual insets */
+ public final int mVisualInsetsLeft;
+ public final int mVisualInsetsRight;
/** Whether this key is sticky, i.e., a toggle key */
public final boolean mSticky;
/** X coordinate of the key in the keyboard layout */
@@ -83,8 +96,8 @@ public class Key {
* {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}.
*/
public final int mEdgeFlags;
- /** Whether this is a modifier key, such as Shift or Alt */
- public final boolean mModifier;
+ /** Whether this is a functional key which has different key top than normal key */
+ public final boolean mFunctional;
/** Whether this key repeats itself when held down */
public final boolean mRepeatable;
@@ -92,11 +105,15 @@ public class Key {
private final Keyboard mKeyboard;
/** The current pressed state of this key */
- public boolean mPressed;
- /** If this is a sticky key, is it on? */
- public boolean mOn;
+ private boolean mPressed;
+ /** If this is a sticky key, is its highlight on? */
+ private boolean mHighlightOn;
/** Key is enabled and responds on press */
- public boolean mEnabled = true;
+ private boolean mEnabled = true;
+
+ // keyWidth constants
+ private static final int KEYWIDTH_FILL_RIGHT = 0;
+ private static final int KEYWIDTH_FILL_BOTH = -1;
private final static int[] KEY_STATE_NORMAL_ON = {
android.R.attr.state_checkable,
@@ -144,13 +161,12 @@ public class Key {
mKeyboard = keyboard;
mHeight = height - keyboard.getVerticalGap();
mGap = keyboard.getHorizontalGap();
+ mVisualInsetsLeft = mVisualInsetsRight = 0;
mWidth = width - mGap;
mEdgeFlags = edgeFlags;
- mHintIcon = null;
- mManualTemporaryUpperCaseHintIcon = null;
- mManualTemporaryUpperCaseCode = Keyboard.CODE_DUMMY;
+ mHintLabel = null;
mLabelOption = 0;
- mModifier = false;
+ mFunctional = false;
mSticky = false;
mRepeatable = false;
mPopupCharacters = null;
@@ -159,7 +175,7 @@ public class Key {
mLabel = PopupCharactersParser.getLabel(popupSpecification);
mOutputText = PopupCharactersParser.getOutputText(popupSpecification);
mCode = PopupCharactersParser.getCode(res, popupSpecification);
- mIcon = PopupCharactersParser.getIcon(res, popupSpecification);
+ mIcon = keyboard.mIconsSet.getIcon(PopupCharactersParser.getIconId(popupSpecification));
// Horizontal gap is divided equally to both sides of the key.
mX = x + mGap / 2;
mY = y;
@@ -216,17 +232,17 @@ public class Key {
if (keyXPos < 0) {
// If keyXPos is negative, the actual x-coordinate will be k + keyXPos.
keyXPos += keyboardWidth;
+ if (keyXPos < x) {
+ // keyXPos shouldn't be less than x because drawable area for this key starts
+ // at x. Or, this key will overlaps the adjacent key on its left hand side.
+ keyXPos = x;
+ }
}
- if (keyXPos < x) {
- // keyXPos shouldn't be less than x because drawable area for this key starts
- // at x. Or, this key will overlaps the adjacent key on its left hand side.
- keyXPos = x;
- }
- if (keyWidth == 0) {
+ if (keyWidth == KEYWIDTH_FILL_RIGHT) {
// If keyWidth is zero, the actual key width will be determined to fill out the
// area up to the right edge of the keyboard.
keyWidth = keyboardWidth - keyXPos;
- } else if (keyWidth < 0) {
+ } else if (keyWidth <= KEYWIDTH_FILL_BOTH) {
// If keyWidth is negative, 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.
@@ -251,26 +267,29 @@ public class Key {
mKeyboard.getMaxPopupKeyboardColumn());
mRepeatable = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable, false);
- mModifier = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isModifier, false);
+ mFunctional = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isFunctional, false);
mSticky = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_isSticky, false);
mEnabled = style.getBoolean(keyAttr, R.styleable.Keyboard_Key_enabled, true);
mEdgeFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyEdgeFlags, 0)
| row.mRowEdgeFlags;
- mPreviewIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_iconPreview);
+ final KeyboardIconsSet iconsSet = mKeyboard.mIconsSet;
+ mVisualInsetsLeft = KeyboardParser.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_visualInsetsLeft, keyboardWidth, 0);
+ mVisualInsetsRight = KeyboardParser.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_visualInsetsRight, keyboardWidth, 0);
+ mPreviewIcon = iconsSet.getIcon(style.getInt(
+ keyAttr, R.styleable.Keyboard_Key_keyIconPreview,
+ KeyboardIconsSet.ICON_UNDEFINED));
Keyboard.setDefaultBounds(mPreviewIcon);
- mIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_keyIcon);
+ mIcon = iconsSet.getIcon(style.getInt(
+ keyAttr, R.styleable.Keyboard_Key_keyIcon,
+ KeyboardIconsSet.ICON_UNDEFINED));
Keyboard.setDefaultBounds(mIcon);
- mHintIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_keyHintIcon);
- Keyboard.setDefaultBounds(mHintIcon);
- mManualTemporaryUpperCaseHintIcon = style.getDrawable(keyAttr,
- R.styleable.Keyboard_Key_manualTemporaryUpperCaseHintIcon);
- Keyboard.setDefaultBounds(mManualTemporaryUpperCaseHintIcon);
+ 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);
- mManualTemporaryUpperCaseCode = style.getInt(keyAttr,
- R.styleable.Keyboard_Key_manualTemporaryUpperCaseCode, Keyboard.CODE_DUMMY);
mOutputText = style.getText(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
// Choose the first letter of the label as primary code if not
// specified.
@@ -284,8 +303,9 @@ public class Key {
mCode = Keyboard.CODE_DUMMY;
}
- final Drawable shiftedIcon = style.getDrawable(keyAttr,
- R.styleable.Keyboard_Key_shiftedIcon);
+ final Drawable shiftedIcon = iconsSet.getIcon(style.getInt(
+ keyAttr, R.styleable.Keyboard_Key_keyIconShifted,
+ KeyboardIconsSet.ICON_UNDEFINED));
if (shiftedIcon != null)
mKeyboard.getShiftedIcons().put(this, shiftedIcon);
} finally {
@@ -293,6 +313,47 @@ public class Key {
}
}
+ public CharSequence getCaseAdjustedLabel() {
+ return mKeyboard.adjustLabelCase(mLabel);
+ }
+
+ public Typeface selectTypeface(Typeface defaultTypeface) {
+ // TODO: Handle "bold" here too?
+ if ((mLabelOption & LABEL_OPTION_FONT_NORMAL) != 0) {
+ return Typeface.DEFAULT;
+ } else if ((mLabelOption & LABEL_OPTION_FONT_MONO_SPACE) != 0) {
+ return Typeface.MONOSPACE;
+ } else {
+ return defaultTypeface;
+ }
+ }
+
+ 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) {
+ return label;
+ } else if ((mLabelOption & LABEL_OPTION_FOLLOW_KEY_HINT_LABEL_RATIO) != 0) {
+ return hintLabel;
+ } else if ((mLabelOption & LABEL_OPTION_LARGE_LETTER) != 0) {
+ return largeLetter;
+ } else {
+ return letter;
+ }
+ }
+
+ public boolean hasPopupHint() {
+ return (mLabelOption & LABEL_OPTION_HAS_POPUP_HINT) != 0;
+ }
+
+ public boolean hasUppercaseLetter() {
+ return (mLabelOption & LABEL_OPTION_HAS_UPPERCASE_LETTER) != 0;
+ }
+
+ public boolean hasHintLabel() {
+ return (mLabelOption & LABEL_OPTION_HAS_HINT_LABEL) != 0;
+ }
+
private static boolean isDigitPopupCharacter(CharSequence label) {
return label != null && label.length() == 1 && Character.isDigit(label.charAt(0));
}
@@ -342,26 +403,31 @@ public class Key {
/**
* Informs the key that it has been pressed, in case it needs to change its appearance or
* state.
- * @see #onReleased(boolean)
+ * @see #onReleased()
*/
public void onPressed() {
- mPressed = !mPressed;
+ mPressed = true;
}
/**
- * Changes the pressed state of the key. If it is a sticky key, it will also change the
- * toggled state of the key if the finger was release inside.
- * @param inside whether the finger was released inside the key
+ * Informs the key that it has been released, in case it needs to change its appearance or
+ * state.
* @see #onPressed()
*/
- public void onReleased(boolean inside) {
- mPressed = !mPressed;
- if (mSticky && !mKeyboard.isShiftLockEnabled(this))
- mOn = !mOn;
+ public void onReleased() {
+ mPressed = false;
+ }
+
+ public void setHighlightOn(boolean highlightOn) {
+ mHighlightOn = highlightOn;
}
- public boolean isInside(int x, int y) {
- return mKeyboard.isInside(this, x, y);
+ public boolean isEnabled() {
+ return mEnabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ mEnabled = enabled;
}
/**
@@ -404,20 +470,14 @@ public class Key {
return dx * dx + dy * dy;
}
- // sticky is used for shift key. If a key is not sticky and is modifier,
- // the key will be treated as functional.
- private boolean isFunctionalKey() {
- return !mSticky && mModifier;
- }
-
/**
* Returns the drawable state for the key, based on the current state and type of the key.
* @return the drawable state of the key.
* @see android.graphics.drawable.StateListDrawable#setState(int[])
*/
public int[] getCurrentDrawableState() {
- final boolean pressed = mEnabled && mPressed;
- if (isFunctionalKey()) {
+ final boolean pressed = mPressed;
+ if (!mSticky && mFunctional) {
if (pressed) {
return KEY_STATE_FUNCTIONAL_PRESSED;
} else {
@@ -427,7 +487,7 @@ public class Key {
int[] states = KEY_STATE_NORMAL;
- if (mOn) {
+ if (mHighlightOn) {
if (pressed) {
states = KEY_STATE_PRESSED_ON;
} else {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index a8346c581..6d25025c5 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -16,36 +16,53 @@
package com.android.inputmethod.keyboard;
+import android.util.Log;
+
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-public abstract class KeyDetector {
- public static final int NOT_A_KEY = -1;
- public static final int NOT_A_CODE = -1;
-
- protected Keyboard mKeyboard;
+public class KeyDetector {
+ private static final String TAG = KeyDetector.class.getSimpleName();
+ private static final boolean DEBUG = false;
- private Key[] mKeys;
+ public static final int NOT_A_CODE = -1;
+ public static final int NOT_A_KEY = -1;
- protected int mCorrectionX;
+ private final int mKeyHysteresisDistanceSquared;
- protected int mCorrectionY;
+ private Keyboard mKeyboard;
+ private int mCorrectionX;
+ private int mCorrectionY;
+ private boolean mProximityCorrectOn;
+ private int mProximityThresholdSquare;
- protected boolean mProximityCorrectOn;
+ // 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];
- protected int mProximityThresholdSquare;
+ /**
+ * This class handles key detection.
+ *
+ * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the
+ * movement will not been handled as meaningful movement. The unit is pixel.
+ */
+ public KeyDetector(float keyHysteresisDistance) {
+ mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
+ }
- public Key[] setKeyboard(Keyboard keyboard, float correctionX, float correctionY) {
+ public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) {
if (keyboard == null)
throw new NullPointerException();
mCorrectionX = (int)correctionX;
mCorrectionY = (int)correctionY;
mKeyboard = keyboard;
- List<Key> keys = mKeyboard.getKeys();
- Key[] array = keys.toArray(new Key[keys.size()]);
- mKeys = array;
- return array;
+ final int threshold = keyboard.getMostCommonKeyWidth();
+ mProximityThresholdSquare = threshold * threshold;
+ }
+
+ public int getKeyHysteresisDistanceSquared() {
+ return mKeyHysteresisDistanceSquared;
}
protected int getTouchX(int x) {
@@ -56,11 +73,10 @@ public abstract class KeyDetector {
return y + mCorrectionY;
}
- protected Key[] getKeys() {
- if (mKeys == null)
+ public Keyboard getKeyboard() {
+ if (mKeyboard == null)
throw new IllegalStateException("keyboard isn't set");
- // mKeyboard is guaranteed not to be null at setKeybaord() method if mKeys is not null
- return mKeys;
+ return mKeyboard;
}
public void setProximityCorrectionEnabled(boolean enabled) {
@@ -76,6 +92,17 @@ public abstract class KeyDetector {
}
/**
+ * Computes 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 indices returned
+ * by {@link #getKeyIndexAndNearbyCodes}.
+ */
+ protected int getMaxNearbyKeys() {
+ return MAX_NEARBY_KEYS;
+ }
+
+ /**
* Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes}
* method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}.
*
@@ -89,14 +116,64 @@ public abstract class KeyDetector {
return codes;
}
+ private void initializeNearbyKeys() {
+ Arrays.fill(mDistances, Integer.MAX_VALUE);
+ Arrays.fill(mIndices, NOT_A_KEY);
+ }
+
/**
- * Computes maximum size of the array that can contain all nearby key indices returned by
- * {@link #getKeyIndexAndNearbyCodes}.
+ * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance.
+ * If the distance of two keys are the same, the key which the point is on should be considered
+ * as a closer one.
*
- * @return Returns maximum size of the array that can contain all nearby key indices returned
- * by {@link #getKeyIndexAndNearbyCodes}.
+ * @param keyIndex index of the key.
+ * @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.
*/
- abstract protected int getMaxNearbyKeys();
+ private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) {
+ final int[] distances = mDistances;
+ final int[] indices = mIndices;
+ for (int insertPos = 0; insertPos < distances.length; insertPos++) {
+ final int comparingDistance = distances[insertPos];
+ if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) {
+ final int nextPos = insertPos + 1;
+ if (nextPos < distances.length) {
+ System.arraycopy(distances, insertPos, distances, nextPos,
+ distances.length - nextPos);
+ System.arraycopy(indices, insertPos, indices, nextPos,
+ indices.length - nextPos);
+ }
+ distances[insertPos] = distance;
+ indices[insertPos] = keyIndex;
+ return insertPos;
+ }
+ }
+ return distances.length;
+ }
+
+ private void getNearbyKeyCodes(final int[] allCodes) {
+ final List<Key> keys = getKeyboard().getKeys();
+ final int[] indices = mIndices;
+
+ // allCodes[0] should always have the key code even if it is a non-letter key.
+ if (indices[0] == NOT_A_KEY) {
+ 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)
+ break;
+ final int code = keys.get(index).mCode;
+ // filter out a non-letter key from nearby keys
+ if (code < Keyboard.CODE_SPACE)
+ continue;
+ allCodes[numCodes++] = code;
+ }
+ }
/**
* Finds all possible nearby key indices around a touch event point and returns the nearest key
@@ -109,32 +186,34 @@ public abstract class KeyDetector {
* @param allCodes All nearby key code except functional key are returned in this array
* @return The nearest key index
*/
- abstract public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes);
+ public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
+ final List<Key> keys = getKeyboard().getKeys();
+ 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);
+ 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;
+ }
+ }
- /**
- * Compute the most common key width in order to use it as proximity key detection threshold.
- *
- * @param keyboard The keyboard to compute the most common key width
- * @return The most common key width in the keyboard
- */
- public static int getMostCommonKeyWidth(final Keyboard keyboard) {
- if (keyboard == null) return 0;
- final List<Key> keys = keyboard.getKeys();
- if (keys == null || keys.size() == 0) return 0;
- final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
- int maxCount = 0;
- int mostCommonWidth = 0;
- for (final Key key : keys) {
- final Integer width = key.mWidth + key.mGap;
- Integer count = histogram.get(width);
- if (count == null)
- count = 0;
- histogram.put(width, ++count);
- if (count > maxCount) {
- maxCount = count;
- mostCommonWidth = width;
+ if (allCodes != null && allCodes.length > 0) {
+ getNearbyKeyCodes(allCodes);
+ if (DEBUG) {
+ Log.d(TAG, "x=" + x + " y=" + y
+ + " primary="
+ + (primaryIndex == NOT_A_KEY ? "none" : keys.get(primaryIndex).mCode)
+ + " codes=" + Arrays.toString(allCodes));
}
}
- return mostCommonWidth;
+
+ return primaryIndex;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 0b545d9c2..0b4fce417 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -16,15 +16,19 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.latin.R;
-
-import org.xmlpull.v1.XmlPullParserException;
-
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.internal.KeyboardParser;
+import com.android.inputmethod.keyboard.internal.KeyboardShiftState;
+import com.android.inputmethod.latin.R;
+
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -51,7 +55,7 @@ import java.util.Map;
* </pre>
*/
public class Keyboard {
- private static final String TAG = "Keyboard";
+ private static final String TAG = Keyboard.class.getSimpleName();
public static final int EDGE_LEFT = 0x01;
public static final int EDGE_RIGHT = 0x02;
@@ -63,24 +67,22 @@ public class Keyboard {
public static final int CODE_TAB = '\t';
public static final int CODE_SPACE = ' ';
public static final int CODE_PERIOD = '.';
+ public static final int CODE_DASH = '-';
+ public static final int CODE_SINGLE_QUOTE = '\'';
+ public static final int CODE_DOUBLE_QUOTE = '"';
/** Special keys code. These should be aligned with values/keycodes.xml */
public static final int CODE_DUMMY = 0;
public static final int CODE_SHIFT = -1;
public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
- public static final int CODE_CANCEL = -3;
- public static final int CODE_DONE = -4;
+ 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_ALT = -6;
+ public static final int CODE_SETTINGS = -6;
+ public static final int CODE_SETTINGS_LONGPRESS = -7;
+ public static final int CODE_SHORTCUT = -8;
// Code value representing the code is not specified.
public static final int CODE_UNSPECIFIED = -99;
- public static final int CODE_SETTINGS = -100;
- public static final int CODE_SETTINGS_LONGPRESS = -101;
- // TODO: remove this once LatinIME stops referring to this.
- public static final int CODE_VOICE = -102;
- public static final int CODE_CAPSLOCK = -103;
- public static final int CODE_NEXT_LANGUAGE = -104;
- public static final int CODE_PREV_LANGUAGE = -105;
/** Horizontal gap default for all rows */
private int mDefaultHorizontalGap;
@@ -128,21 +130,17 @@ public class Keyboard {
/** Height of keyboard */
private int mKeyboardHeight;
+ private int mMostCommonKeyWidth = 0;
+
public final KeyboardId mId;
+ public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
+
// Variables for pre-computing nearest keys.
// TODO: Change GRID_WIDTH and GRID_HEIGHT to private.
public final int GRID_WIDTH;
public final int GRID_HEIGHT;
- private final int GRID_SIZE;
- private int mCellWidth;
- private int mCellHeight;
- private int[][] mGridNeighbors;
- private int mProximityThreshold;
- private static int[] EMPTY_INT_ARRAY = new int[0];
- /** Number of key widths from current touch point to search for nearest keys. */
- private static float SEARCH_DISTANCE = 1.2f;
private final ProximityInfo mProximityInfo;
@@ -151,22 +149,19 @@ public class Keyboard {
* @param context the application or service context
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
* @param id keyboard identifier
+ * @param width keyboard width
*/
- public Keyboard(Context context, int xmlLayoutResId, KeyboardId id) {
- this(context, xmlLayoutResId, id,
- context.getResources().getDisplayMetrics().widthPixels,
- context.getResources().getDisplayMetrics().heightPixels);
- }
- private Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width,
- int height) {
- Resources res = context.getResources();
+ public Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width) {
+ final Resources res = context.getResources();
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
- GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
- mDisplayWidth = width;
- mDisplayHeight = height;
+ final int horizontalEdgesPadding = (int)res.getDimension(
+ R.dimen.keyboard_horizontal_edges_padding);
+ mDisplayWidth = width - horizontalEdgesPadding * 2;
+ // TODO: Adjust the height by referring to the height of area available for drawing as well.
+ mDisplayHeight = res.getDisplayMetrics().heightPixels;
mDefaultHorizontalGap = 0;
setKeyWidth(mDisplayWidth / 10);
@@ -174,11 +169,12 @@ public class Keyboard {
mDefaultHeight = mDefaultWidth;
mId = id;
loadKeyboard(context, xmlLayoutResId);
- mProximityInfo = new ProximityInfo(GRID_WIDTH, GRID_HEIGHT);
+ mProximityInfo = new ProximityInfo(
+ GRID_WIDTH, GRID_HEIGHT, getMinWidth(), getHeight(), getKeyWidth(), mKeys);
}
public int getProximityInfo() {
- return mProximityInfo.getNativeProximityInfo(this);
+ return mProximityInfo.getNativeProximityInfo();
}
public List<Key> getKeys() {
@@ -215,8 +211,6 @@ public class Keyboard {
public void setKeyWidth(int width) {
mDefaultWidth = width;
- final int threshold = (int) (width * SEARCH_DISTANCE);
- mProximityThreshold = threshold * threshold;
}
/**
@@ -293,7 +287,7 @@ public class Keyboard {
public boolean setShiftLocked(boolean newShiftLockState) {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
- key.mOn = newShiftLockState;
+ key.setHighlightOn(newShiftLockState);
key.setIcon(newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key));
}
mShiftState.setShiftLocked(newShiftLockState);
@@ -342,47 +336,23 @@ public class Keyboard {
}
public boolean isAlphaKeyboard() {
- return mId != null && mId.isAlphabetKeyboard();
+ return mId.isAlphabetKeyboard();
}
public boolean isPhoneKeyboard() {
- return mId != null && mId.isPhoneKeyboard();
+ return mId.isPhoneKeyboard();
}
public boolean isNumberKeyboard() {
- return mId != null && mId.isNumberKeyboard();
- }
-
- // TODO: Move this function to ProximityInfo and make this private.
- public void computeNearestNeighbors() {
- // Round-up so we don't have any pixels outside the grid
- mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH;
- mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT;
- mGridNeighbors = new int[GRID_SIZE][];
- final int[] indices = new int[mKeys.size()];
- final int gridWidth = GRID_WIDTH * mCellWidth;
- final int gridHeight = GRID_HEIGHT * mCellHeight;
- final int threshold = mProximityThreshold;
- for (int x = 0; x < gridWidth; x += mCellWidth) {
- for (int y = 0; y < gridHeight; y += mCellHeight) {
- final int centerX = x + mCellWidth / 2;
- final int centerY = y + mCellHeight / 2;
- int count = 0;
- for (int i = 0; i < mKeys.size(); i++) {
- final Key key = mKeys.get(i);
- if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
- indices[count++] = i;
- }
- final int[] cell = new int[count];
- System.arraycopy(indices, 0, cell, 0, count);
- mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell;
- }
- }
- mProximityInfo.setProximityInfo(mGridNeighbors, getMinWidth(), getHeight(), mKeys);
+ return mId.isNumberKeyboard();
}
- public boolean isInside(Key key, int x, int y) {
- return key.isOnKey(x, y);
+ public CharSequence adjustLabelCase(CharSequence label) {
+ if (isShiftedOrShiftLocked() && !TextUtils.isEmpty(label) && label.length() < 3
+ && Character.isLowerCase(label.charAt(0))) {
+ return label.toString().toUpperCase(mId.mLocale);
+ }
+ return label;
}
/**
@@ -393,19 +363,47 @@ public class Keyboard {
* point is out of range, then an array of size zero is returned.
*/
public int[] getNearestKeys(int x, int y) {
- if (mGridNeighbors == null) computeNearestNeighbors();
- if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) {
- int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth);
- if (index < GRID_SIZE) {
- return mGridNeighbors[index];
+ return mProximityInfo.getNearestKeys(x, y);
+ }
+
+ /**
+ * Compute the most common key width in order to use it as proximity key detection threshold.
+ *
+ * @return The most common key width in the keyboard
+ */
+ public int getMostCommonKeyWidth() {
+ if (mMostCommonKeyWidth == 0) {
+ final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
+ int maxCount = 0;
+ int mostCommonWidth = 0;
+ for (final Key key : mKeys) {
+ final Integer width = key.mWidth + key.mGap;
+ Integer count = histogram.get(width);
+ if (count == null)
+ count = 0;
+ histogram.put(width, ++count);
+ if (count > maxCount) {
+ maxCount = count;
+ mostCommonWidth = width;
+ }
}
+ mMostCommonKeyWidth = mostCommonWidth;
}
- return EMPTY_INT_ARRAY;
+ return mMostCommonKeyWidth;
+ }
+
+ /**
+ * Return true if spacebar needs showing preview even when "popup on keypress" is off.
+ * @param keyIndex index of the pressing key
+ * @return true if spacebar needs showing preview
+ */
+ public boolean needSpacebarPreview(int keyIndex) {
+ return false;
}
private void loadKeyboard(Context context, int xmlLayoutResId) {
try {
- KeyboardParser parser = new KeyboardParser(this, context.getResources());
+ KeyboardParser parser = new KeyboardParser(this, context);
parser.parseKeyboard(xmlLayoutResId);
// mMinWidth is the width of this keyboard which is maximum width of row.
mMinWidth = parser.getMaxRowWidth();
@@ -419,7 +417,7 @@ public class Keyboard {
}
}
- protected static void setDefaultBounds(Drawable drawable) {
+ public static void setDefaultBounds(Drawable drawable) {
if (drawable != null)
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 7e67d6f6b..905f779c0 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -70,9 +70,4 @@ public interface KeyboardActionListener {
* Called when user released a finger outside any key.
*/
public void onCancelInput();
-
- /**
- * Called when the user quickly moves the finger from up to down.
- */
- public void onSwipeDown();
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index b256a89c1..b2600dd3b 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -16,11 +16,12 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Utils;
-
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;
@@ -41,12 +42,14 @@ public class KeyboardId {
public static final int F2KEY_MODE_SHORTCUT_IME = 2;
public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
+ private static final int MINI_KEYBOARD_ID_MARKER = -1;
+
public final Locale mLocale;
public final int mOrientation;
+ public final int mWidth;
public final int mMode;
public final int mXmlId;
- public final int mColorScheme;
- public final boolean mWebInput;
+ public final boolean mNavigateAction;
public final boolean mPasswordInput;
// TODO: Clean up these booleans and modes.
public final boolean mHasSettingsKey;
@@ -56,11 +59,13 @@ public class KeyboardId {
public final boolean mHasVoiceKey;
public final int mImeAction;
public final boolean mEnableShiftLock;
+
public final String mXmlName;
+ public final EditorInfo mAttribute;
private final int mHashCode;
- public KeyboardId(String xmlName, int xmlId, int colorScheme, Locale locale, int orientation,
+ public KeyboardId(String xmlName, int xmlId, Locale locale, int orientation, int width,
int mode, EditorInfo attribute, boolean hasSettingsKey, int f2KeyMode,
boolean clobberSettingsKey, boolean voiceKeyEnabled, boolean hasVoiceKey,
boolean enableShiftLock) {
@@ -68,12 +73,15 @@ public class KeyboardId {
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
this.mLocale = locale;
this.mOrientation = orientation;
+ this.mWidth = width;
this.mMode = mode;
this.mXmlId = xmlId;
- this.mColorScheme = colorScheme;
- this.mWebInput = Utils.isWebInputType(inputType);
- this.mPasswordInput = Utils.isPasswordInputType(inputType)
- || Utils.isVisiblePasswordInputType(inputType);
+ // 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.mClobberSettingsKey = clobberSettingsKey;
@@ -84,15 +92,17 @@ public class KeyboardId {
this.mImeAction = imeOptions & (
EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
this.mEnableShiftLock = enableShiftLock;
+
this.mXmlName = xmlName;
+ this.mAttribute = attribute;
this.mHashCode = Arrays.hashCode(new Object[] {
locale,
orientation,
+ width,
mode,
xmlId,
- colorScheme,
- mWebInput,
+ mNavigateAction,
mPasswordInput,
hasSettingsKey,
f2KeyMode,
@@ -104,22 +114,49 @@ public class KeyboardId {
});
}
+ public KeyboardId cloneAsMiniKeyboard() {
+ return new KeyboardId("mini popup keyboard", MINI_KEYBOARD_ID_MARKER, mLocale, mOrientation,
+ mWidth, mMode, mAttribute, false, F2KEY_MODE_NONE, false, false, false, false);
+ }
+
+ public KeyboardId cloneWithNewLayout(String xmlName, int xmlId) {
+ return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mAttribute,
+ mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey,
+ mEnableShiftLock);
+ }
+
+ public KeyboardId cloneWithNewGeometry(int width) {
+ if (mWidth == width)
+ return this;
+ return new KeyboardId(mXmlName, mXmlId, mLocale, mOrientation, width, mMode, mAttribute,
+ mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey,
+ mEnableShiftLock);
+ }
+
public int getXmlId() {
return mXmlId;
}
+ public boolean isMiniKeyboard() {
+ return mXmlId == MINI_KEYBOARD_ID_MARKER;
+ }
+
public boolean isAlphabetKeyboard() {
return mXmlId == R.xml.kbd_qwerty;
}
public boolean isSymbolsKeyboard() {
- return mXmlId == R.xml.kbd_symbols;
+ return mXmlId == R.xml.kbd_symbols || mXmlId == R.xml.kbd_symbols_shift;
}
public boolean isPhoneKeyboard() {
return mMode == MODE_PHONE;
}
+ public boolean isPhoneSymbolsKeyboard() {
+ return mXmlId == R.xml.kbd_phone_symbols;
+ }
+
public boolean isNumberKeyboard() {
return mMode == MODE_NUMBER;
}
@@ -132,10 +169,10 @@ public class KeyboardId {
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.mColorScheme == this.mColorScheme
- && other.mWebInput == this.mWebInput
+ && other.mNavigateAction == this.mNavigateAction
&& other.mPasswordInput == this.mPasswordInput
&& other.mHasSettingsKey == this.mHasSettingsKey
&& other.mF2KeyMode == this.mF2KeyMode
@@ -153,16 +190,15 @@ public class KeyboardId {
@Override
public String toString() {
- return String.format("[%s.xml %s %s %s %s %s %s%s%s%s%s%s%s%s]",
+ return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s%s]",
mXmlName,
mLocale,
- (mOrientation == 1 ? "port" : "land"),
+ (mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode),
- imeOptionsName(mImeAction),
- colorSchemeName(mColorScheme),
+ EditorInfoCompatUtils.imeOptionsName(mImeAction),
f2KeyModeName(mF2KeyMode),
(mClobberSettingsKey ? " clobberSettingsKey" : ""),
- (mWebInput ? " webInput" : ""),
+ (mNavigateAction ? " navigateAction" : ""),
(mPasswordInput ? " passwordInput" : ""),
(mHasSettingsKey ? " hasSettingsKey" : ""),
(mVoiceKeyEnabled ? " voiceKeyEnabled" : ""),
@@ -179,37 +215,7 @@ public class KeyboardId {
case MODE_IM: return "im";
case MODE_PHONE: return "phone";
case MODE_NUMBER: return "number";
- }
- return null;
- }
-
- public static String colorSchemeName(int colorScheme) {
- switch (colorScheme) {
- case KeyboardView.COLOR_SCHEME_WHITE: return "white";
- case KeyboardView.COLOR_SCHEME_BLACK: return "black";
- }
- return null;
- }
-
- public static String imeOptionsName(int imeOptions) {
- if (imeOptions == -1) return null;
- final int actionNo = imeOptions & EditorInfo.IME_MASK_ACTION;
- final String action;
- switch (actionNo) {
- 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_DONE: action = "actionDone"; break;
- case EditorInfo.IME_ACTION_NEXT: action = "actionNext"; break;
- case EditorInfo.IME_ACTION_PREVIOUS: action = "actionPrevious"; break;
- default: action = "actionUnknown(" + actionNo + ")"; break;
- }
- if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
- return "flagNoEnterAction|" + action;
- } else {
- return action;
+ default: return null;
}
}
@@ -219,8 +225,7 @@ public class KeyboardId {
case F2KEY_MODE_SETTINGS: return "settings";
case F2KEY_MODE_SHORTCUT_IME: return "shortcutIme";
case F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS: return "shortcutImeOrSettings";
+ default: return null;
}
- return null;
}
}
-
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 5d3ec526a..bb21d7a63 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -16,20 +16,26 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.latin.LatinIME;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Settings;
-import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.Utils;
-
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.util.Log;
+import android.view.ContextThemeWrapper;
import android.view.InflateException;
+import android.view.LayoutInflater;
+import android.view.View;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
+
+import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.keyboard.internal.ModifierKeyState;
+import com.android.inputmethod.keyboard.internal.ShiftKeyState;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.Utils;
import java.lang.ref.SoftReference;
import java.util.HashMap;
@@ -37,26 +43,27 @@ import java.util.Locale;
public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
- private static final boolean DEBUG = LatinImeLogger.sDBG;
+ private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG;
public static final boolean DEBUG_STATE = false;
- private static String sConfigDefaultKeyboardThemeId;
public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20100902";
private static final int[] KEYBOARD_THEMES = {
- R.layout.input_basic,
- R.layout.input_basic_highcontrast,
- R.layout.input_stone_normal,
- R.layout.input_stone_bold,
- R.layout.input_gingerbread,
- R.layout.input_honeycomb,
+ R.style.KeyboardTheme,
+ R.style.KeyboardTheme_HighContrast,
+ R.style.KeyboardTheme_Stone,
+ R.style.KeyboardTheme_Stone_Bold,
+ R.style.KeyboardTheme_Gingerbread,
+ R.style.KeyboardTheme_IceCreamSandwich,
};
private SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs;
- private LatinKeyboardView mInputView;
+ private View mCurrentInputView;
+ private LatinKeyboardView mKeyboardView;
private LatinIME mInputMethodService;
+ // TODO: Combine these key state objects with auto mode switch state.
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
@@ -75,13 +82,17 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private boolean mVoiceKeyEnabled;
private boolean mVoiceButtonOnPrimary;
- private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0;
- private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1;
- private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2;
+ // 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 AUTO_MODE_SWITCH_STATE_MOMENTARY = 3;
- private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4;
- private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ 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;
// Indicates whether or not we have the settings key in option of settings
private boolean mSettingsKeyEnabledInSettings;
@@ -93,7 +104,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// Default is SETTINGS_KEY_MODE_AUTO.
private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO;
- private int mLayoutId;
+ private int mThemeIndex = -1;
+ private Context mThemeContext;
+ private int mKeyboardWidth;
private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
@@ -109,24 +122,38 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
sInstance.mInputMethodService = ims;
sInstance.mPrefs = prefs;
sInstance.mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ sInstance.setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs));
+ prefs.registerOnSharedPreferenceChangeListener(sInstance);
+ }
+ private static int getKeyboardThemeIndex(Context context, SharedPreferences prefs) {
+ final String defaultThemeId = context.getString(R.string.config_default_keyboard_theme_id);
+ final String themeId = prefs.getString(PREF_KEYBOARD_LAYOUT, defaultThemeId);
try {
- sConfigDefaultKeyboardThemeId = ims.getString(
- R.string.config_default_keyboard_theme_id);
- sInstance.mLayoutId = Integer.valueOf(
- prefs.getString(PREF_KEYBOARD_LAYOUT, sConfigDefaultKeyboardThemeId));
+ final int themeIndex = Integer.valueOf(themeId);
+ if (themeIndex >= 0 && themeIndex < KEYBOARD_THEMES.length)
+ return themeIndex;
} catch (NumberFormatException e) {
- sConfigDefaultKeyboardThemeId = "0";
- sInstance.mLayoutId = 0;
+ // Format error, keyboard theme is default to 0.
+ }
+ Log.w(TAG, "Illegal keyboard theme in preference: " + themeId + ", default to 0");
+ return 0;
+ }
+
+ private void setContextThemeWrapper(Context context, int themeIndex) {
+ if (mThemeIndex != themeIndex) {
+ mThemeIndex = themeIndex;
+ mThemeContext = new ContextThemeWrapper(context, KEYBOARD_THEMES[themeIndex]);
+ mKeyboardCache.clear();
}
- prefs.registerOnSharedPreferenceChangeListener(sInstance);
}
public void loadKeyboard(EditorInfo attribute, boolean voiceKeyEnabled,
boolean voiceButtonOnPrimary) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mSwitchState = SWITCH_STATE_ALPHA;
try {
- loadKeyboardInternal(attribute, voiceKeyEnabled, voiceButtonOnPrimary, false);
+ final boolean isSymbols = (mCurrentId != null) ? mCurrentId.isSymbolsKeyboard() : false;
+ loadKeyboardInternal(attribute, voiceKeyEnabled, voiceButtonOnPrimary, isSymbols);
} catch (RuntimeException e) {
// Get KeyboardId to record which keyboard has been failed to load.
final KeyboardId id = getKeyboardId(attribute, false);
@@ -137,7 +164,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void loadKeyboardInternal(EditorInfo attribute, boolean voiceButtonEnabled,
boolean voiceButtonOnPrimary, boolean isSymbols) {
- if (mInputView == null) return;
+ if (mKeyboardView == null) return;
mAttribute = attribute;
mVoiceKeyEnabled = voiceButtonEnabled;
@@ -147,19 +174,38 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService);
final KeyboardId id = getKeyboardId(attribute, isSymbols);
- final Keyboard oldKeyboard = mInputView.getKeyboard();
- if (oldKeyboard != null && oldKeyboard.mId.equals(id))
- return;
+ // Note: This comment is only applied for phone number keyboard layout.
+ // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch
+ // between "phone keyboard" and "phone symbols keyboard". But on xlarge device,
+ // "@integer/key_shift" key code is used for that purpose in order to properly display
+ // "more" and "locked more" key labels. To achieve these behavior, we should initialize
+ // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard"
+ // respectively here for xlarge device's layout switching.
+ mSymbolsId = makeSiblingKeyboardId(id, R.xml.kbd_symbols, R.xml.kbd_phone);
+ mSymbolsShiftedId = makeSiblingKeyboardId(
+ id, R.xml.kbd_symbols_shift, R.xml.kbd_phone_symbols);
- makeSymbolsKeyboardIds(id.mMode, attribute);
- mCurrentId = id;
- mInputView.setPreviewEnabled(mInputMethodService.getPopupOn());
setKeyboard(getKeyboard(id));
}
+ public void onSizeChanged() {
+ final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth();
+ if (width == 0 || mCurrentId == null)
+ return;
+ mKeyboardWidth = width;
+ // Set keyboard with new width.
+ final KeyboardId newId = mCurrentId.cloneWithNewGeometry(width);
+ setKeyboard(getKeyboard(newId));
+ }
+
private void setKeyboard(final Keyboard newKeyboard) {
- final Keyboard oldKeyboard = mInputView.getKeyboard();
- mInputView.setKeyboard(newKeyboard);
+ final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
+ mKeyboardView.setKeyboard(newKeyboard);
+ mCurrentId = newKeyboard.mId;
+ final Resources res = mInputMethodService.getResources();
+ mKeyboardView.setKeyPreviewPopupEnabled(
+ Settings.Values.isKeyPreviewPopupEnabled(mPrefs, res),
+ Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, res));
final boolean localeChanged = (oldKeyboard == null)
|| !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
@@ -169,22 +215,23 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id);
LatinKeyboard keyboard = (ref == null) ? null : ref.get();
if (keyboard == null) {
- final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(
+ final Resources res = mInputMethodService.getResources();
+ final Locale savedLocale = Utils.setSystemLocale(res,
mSubtypeSwitcher.getInputLocale());
- keyboard = new LatinKeyboard(mInputMethodService, id);
+ keyboard = new LatinKeyboard(mThemeContext, id, id.mWidth);
if (id.mEnableShiftLock) {
keyboard.enableShiftLock();
}
mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
- if (DEBUG)
+ if (DEBUG_CACHE)
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
- mSubtypeSwitcher.changeSystemLocale(savedLocale);
- } else if (DEBUG) {
+ Utils.setSystemLocale(res, savedLocale);
+ } else if (DEBUG_CACHE) {
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
}
@@ -195,6 +242,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// we should reset the text fade factor. It is also applicable to shortcut key.
keyboard.setSpacebarTextFadeFactor(0.0f, null);
keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady(), null);
+ keyboard.setSpacebarSlidingLanguageSwitchDiff(0);
return keyboard;
}
@@ -211,7 +259,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private KeyboardId getKeyboardId(EditorInfo attribute, boolean isSymbols) {
final int mode = Utils.getKeyboardMode(attribute);
final boolean hasVoiceKey = hasVoiceKey(isSymbols);
- final int charColorId = getColorScheme();
final int xmlId;
final boolean enableShiftLock;
@@ -244,40 +291,19 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
attribute);
final Resources res = mInputMethodService.getResources();
final int orientation = res.getConfiguration().orientation;
+ if (mKeyboardWidth == 0)
+ mKeyboardWidth = res.getDisplayMetrics().widthPixels;
final Locale locale = mSubtypeSwitcher.getInputLocale();
return new KeyboardId(
- res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation, mode,
- attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled,
+ res.getResourceEntryName(xmlId), xmlId, locale, orientation, mKeyboardWidth,
+ mode, attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled,
hasVoiceKey, enableShiftLock);
}
- private void makeSymbolsKeyboardIds(final int mode, EditorInfo attribute) {
- final Locale locale = mSubtypeSwitcher.getInputLocale();
- final Resources res = mInputMethodService.getResources();
- final int orientation = res.getConfiguration().orientation;
- final int colorScheme = getColorScheme();
- final boolean hasVoiceKey = mVoiceKeyEnabled && !mVoiceButtonOnPrimary;
- final boolean hasSettingsKey = hasSettingsKey(attribute);
- final int f2KeyMode = getF2KeyMode(mPrefs, mInputMethodService, attribute);
- final boolean clobberSettingsKey = Utils.inPrivateImeOptions(
- mInputMethodService.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY,
- attribute);
- // Note: This comment is only applied for phone number keyboard layout.
- // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch
- // between "phone keyboard" and "phone symbols keyboard". But on xlarge device,
- // "@integer/key_shift" key code is used for that purpose in order to properly display
- // "more" and "locked more" key labels. To achieve these behavior, we should initialize
- // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard"
- // respectively here for xlarge device's layout switching.
- int xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols;
- final String xmlName = res.getResourceEntryName(xmlId);
- mSymbolsId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode,
- attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled,
- hasVoiceKey, true);
- xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift;
- mSymbolsShiftedId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode,
- attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled,
- hasVoiceKey, true);
+ private KeyboardId makeSiblingKeyboardId(KeyboardId base, int alphabet, int phone) {
+ final int xmlId = base.mMode == KeyboardId.MODE_PHONE ? phone : alphabet;
+ final String xmlName = mInputMethodService.getResources().getResourceEntryName(xmlId);
+ return base.cloneWithNewLayout(xmlName, xmlId);
}
public int getKeyboardMode() {
@@ -289,30 +315,24 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public boolean isInputViewShown() {
- return mInputView != null && mInputView.isShown();
+ return mCurrentInputView != null && mCurrentInputView.isShown();
}
public boolean isKeyboardAvailable() {
- if (mInputView != null)
- return mInputView.getKeyboard() != null;
+ if (mKeyboardView != null)
+ return mKeyboardView.getKeyboard() != null;
return false;
}
public LatinKeyboard getLatinKeyboard() {
- if (mInputView != null) {
- final Keyboard keyboard = mInputView.getKeyboard();
+ if (mKeyboardView != null) {
+ final Keyboard keyboard = mKeyboardView.getKeyboard();
if (keyboard instanceof LatinKeyboard)
return (LatinKeyboard)keyboard;
}
return null;
}
- public void keyReleased() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- latinKeyboard.keyReleased();
- }
-
public boolean isShiftedOrShiftLocked() {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null)
@@ -355,12 +375,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// 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() || isAccessibilityEnabled())
- && !shifted && latinKeyboard.isShiftLocked()) {
+ if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) {
latinKeyboard.setShiftLocked(false);
}
if (latinKeyboard.setShifted(shifted)) {
- mInputView.invalidateAllKeys();
+ mKeyboardView.invalidateAllKeys();
}
}
}
@@ -368,7 +387,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void setShiftLocked(boolean shiftLocked) {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null && latinKeyboard.setShiftLocked(shiftLocked)) {
- mInputView.invalidateAllKeys();
+ mKeyboardView.invalidateAllKeys();
}
}
@@ -410,7 +429,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null) {
latinKeyboard.setAutomaticTemporaryUpperCase();
- mInputView.invalidateAllKeys();
+ mKeyboardView.invalidateAllKeys();
}
}
@@ -454,9 +473,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
public void onPressShift(boolean withSliding) {
if (!isKeyboardAvailable())
return;
- // If accessibility is enabled, disable momentary shift lock.
- if (isAccessibilityEnabled())
- return;
ShiftKeyState shiftKeyState = mShiftKeyState;
if (DEBUG_STATE)
Log.d(TAG, "onPressShift:"
@@ -486,15 +502,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// In symbol mode, just toggle symbol and symbol more keyboard.
shiftKeyState.onPress();
toggleShift();
+ mSwitchState = SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
}
}
public void onReleaseShift(boolean withSliding) {
if (!isKeyboardAvailable())
return;
- // If accessibility is enabled, disable momentary shift lock.
- if (isAccessibilityEnabled())
- return;
ShiftKeyState shiftKeyState = mShiftKeyState;
if (DEBUG_STATE)
Log.d(TAG, "onReleaseShift:"
@@ -510,7 +524,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// 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.
- mInputView.startIgnoringDoubleTap();
+ mKeyboardView.startIgnoringDoubleTap();
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()
&& !withSliding) {
// Shift has been pressed without chording while shifted state.
@@ -521,42 +535,40 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// 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 accessibility is enabled, disable momentary symbol lock.
- if (isAccessibilityEnabled())
- return;
if (DEBUG_STATE)
Log.d(TAG, "onPressSymbol:"
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
+ " symbolKeyState=" + mSymbolKeyState);
changeKeyboardMode();
mSymbolKeyState.onPress();
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
}
public void onReleaseSymbol() {
- // If accessibility is enabled, disable momentary symbol lock.
- if (isAccessibilityEnabled())
- return;
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
- // other key, then released the mode change key.
- if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING)
+ // another key, then releases the mode change key.
+ if (mSwitchState == SWITCH_STATE_CHORDING_ALPHA) {
changeKeyboardMode();
+ }
mSymbolKeyState.onRelease();
}
public void onOtherKeyPressed() {
- // If accessibility is enabled, disable momentary mode locking.
- if (isAccessibilityEnabled())
- return;
if (DEBUG_STATE)
Log.d(TAG, "onOtherKeyPressed:"
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
@@ -568,8 +580,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
public void onCancelInput() {
// Snap back to the previous keyboard mode if the user cancels sliding input.
- if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY && getPointerCount() == 1)
- changeKeyboardMode();
+ if (getPointerCount() == 1) {
+ if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) {
+ changeKeyboardMode();
+ } else if (mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE) {
+ toggleShift();
+ }
+ }
}
private void toggleShiftInSymbol() {
@@ -577,74 +594,91 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
return;
final LatinKeyboard keyboard;
if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) {
- mCurrentId = mSymbolsShiftedId;
- keyboard = getKeyboard(mCurrentId);
+ keyboard = getKeyboard(mSymbolsShiftedId);
// Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To
- // enable the indicator, we need to call enableShiftLock() and setShiftLocked(true).
- // Thus we can keep the ALT key's Key.on value true while LatinKey.onRelease() is
- // called.
+ // enable the indicator, we need to call setShiftLocked(true).
keyboard.setShiftLocked(true);
} else {
- mCurrentId = mSymbolsId;
- keyboard = getKeyboard(mCurrentId);
+ keyboard = getKeyboard(mSymbolsId);
// Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the
- // indicator, we need to call enableShiftLock() and setShiftLocked(false).
- keyboard.setShifted(false);
+ // indicator, we need to call setShiftLocked(false).
+ keyboard.setShiftLocked(false);
}
setKeyboard(keyboard);
}
- public boolean isInMomentaryAutoModeSwitchState() {
- return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ public boolean isInMomentarySwitchState() {
+ return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL
+ || mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
}
public boolean isVibrateAndSoundFeedbackRequired() {
- return mInputView == null || !mInputView.isInSlidingKeyInput();
+ return mKeyboardView == null || !mKeyboardView.isInSlidingKeyInput();
}
private int getPointerCount() {
- return mInputView == null ? 0 : mInputView.getPointerCount();
+ return mKeyboardView == null ? 0 : mKeyboardView.getPointerCount();
}
private void toggleKeyboardMode() {
loadKeyboardInternal(mAttribute, mVoiceKeyEnabled, mVoiceButtonOnPrimary, !mIsSymbols);
if (mIsSymbols) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
} else {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mSwitchState = SWITCH_STATE_ALPHA;
}
}
- public boolean isAccessibilityEnabled() {
- return mInputView != null && mInputView.isAccessibilityEnabled();
- }
-
public boolean hasDistinctMultitouch() {
- return mInputView != null && mInputView.hasDistinctMultitouch();
+ return mKeyboardView != null && mKeyboardView.hasDistinctMultitouch();
+ }
+
+ private static boolean isSpaceCharacter(int c) {
+ return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER;
+ }
+
+ private static boolean isQuoteCharacter(int c) {
+ // Apostrophe, quotation mark.
+ if (c == Keyboard.CODE_SINGLE_QUOTE || c == Keyboard.CODE_DOUBLE_QUOTE)
+ return true;
+ // \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
+ if (c >= '\u2018' && c <= '\u201f')
+ return true;
+ // \u00ab: Left-pointing double angle quotation mark
+ // \u00bb: Right-pointing double angle quotation mark
+ if (c == '\u00ab' || c == '\u00bb')
+ return true;
+ return false;
}
/**
* Updates state machine to figure out when to automatically snap back to the previous mode.
*/
- public void onKey(int key) {
+ public void onKey(int code) {
if (DEBUG_STATE)
- Log.d(TAG, "onKey: code=" + key + " autoModeSwitchState=" + mAutoModeSwitchState
+ Log.d(TAG, "onKey: code=" + code + " switchState=" + mSwitchState
+ " pointers=" + getPointerCount());
- switch (mAutoModeSwitchState) {
- case AUTO_MODE_SWITCH_STATE_MOMENTARY:
+ 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 #mAutoModeSwitchState} starts
- // from {@link #AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN}, or
- // {@link #AUTO_MODE_SWITCH_STATE_ALPHA}, not from
- // {@link #AUTO_MODE_SWITCH_STATE_MOMENTARY}.
- if (key == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ // {@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 (mIsSymbols) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
} else {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
+ mSwitchState = SWITCH_STATE_ALPHA;
}
} else if (getPointerCount() == 1) {
// Snap back to the previous keyboard mode if the user pressed the mode change key
@@ -655,71 +689,96 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
} 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.
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING;
+ mSwitchState = SWITCH_STATE_CHORDING_ALPHA;
}
break;
- case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN:
- if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key >= 0) {
- mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL;
+ 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 AUTO_MODE_SWITCH_STATE_SYMBOL:
+ 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 (isQuoteCharacter(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.
- if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) {
+ // characters followed by a space/enter or a quote character.
+ if (isSpaceCharacter(code) || isQuoteCharacter(code)) {
changeKeyboardMode();
}
break;
}
}
- public LatinKeyboardView getInputView() {
- return mInputView;
+ public LatinKeyboardView getKeyboardView() {
+ return mKeyboardView;
}
- public LatinKeyboardView onCreateInputView() {
- createInputViewInternal(mLayoutId, true);
- return mInputView;
+ public View onCreateInputView() {
+ return createInputView(mThemeIndex, true);
}
- private void createInputViewInternal(int newLayout, boolean forceReset) {
- int layoutId = newLayout;
- if (mLayoutId != layoutId || mInputView == null || forceReset) {
- if (mInputView != null) {
- mInputView.closing();
- }
- if (KEYBOARD_THEMES.length <= layoutId) {
- layoutId = Integer.valueOf(sConfigDefaultKeyboardThemeId);
- }
+ private View createInputView(final int newThemeIndex, final boolean forceRecreate) {
+ if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate)
+ return mCurrentInputView;
- Utils.GCUtils.getInstance().reset();
- boolean tryGC = true;
- for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
- try {
- mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater(
- ).inflate(KEYBOARD_THEMES[layoutId], null);
- tryGC = false;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "load keyboard failed: " + e);
- tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
- mLayoutId + "," + layoutId, e);
- } catch (InflateException e) {
- Log.w(TAG, "load keyboard failed: " + e);
- tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
- mLayoutId + "," + layoutId, e);
- }
+ if (mKeyboardView != null) {
+ mKeyboardView.closing();
+ }
+
+ final int oldThemeIndex = mThemeIndex;
+ Utils.GCUtils.getInstance().reset();
+ boolean tryGC = true;
+ for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+ try {
+ setContextThemeWrapper(mInputMethodService, newThemeIndex);
+ mCurrentInputView = LayoutInflater.from(mThemeContext).inflate(
+ R.layout.input_view, null);
+ tryGC = false;
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "load keyboard failed: " + e);
+ tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
+ oldThemeIndex + "," + newThemeIndex, e);
+ } catch (InflateException e) {
+ Log.w(TAG, "load keyboard failed: " + e);
+ tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
+ oldThemeIndex + "," + newThemeIndex, e);
}
- mInputView.setOnKeyboardActionListener(mInputMethodService);
- mLayoutId = layoutId;
}
+
+ mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
+ mKeyboardView.setKeyboardActionListener(mInputMethodService);
+
+ // This always needs to be set since the accessibility state can
+ // potentially change without the input view being re-created.
+ AccessibleKeyboardViewProxy.setView(mKeyboardView);
+
+ return mCurrentInputView;
}
- private void postSetInputView() {
+ private void postSetInputView(final View newInputView) {
mInputMethodService.mHandler.post(new Runnable() {
@Override
public void run() {
- if (mInputView != null) {
- mInputMethodService.setInputView(mInputView);
+ if (newInputView != null) {
+ mInputMethodService.setInputView(newInputView);
}
mInputMethodService.updateInputViewShown();
}
@@ -729,29 +788,25 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (PREF_KEYBOARD_LAYOUT.equals(key)) {
- final int layoutId = Integer.valueOf(
- sharedPreferences.getString(key, sConfigDefaultKeyboardThemeId));
- createInputViewInternal(layoutId, false);
- postSetInputView();
+ final int layoutId = getKeyboardThemeIndex(mInputMethodService, sharedPreferences);
+ postSetInputView(createInputView(layoutId, false));
} else if (Settings.PREF_SETTINGS_KEY.equals(key)) {
mSettingsKeyEnabledInSettings = getSettingsKeyMode(sharedPreferences,
mInputMethodService);
- createInputViewInternal(mLayoutId, true);
- postSetInputView();
+ postSetInputView(createInputView(mThemeIndex, true));
}
}
- private int getColorScheme() {
- return (mInputView != null)
- ? mInputView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE;
- }
-
public void onAutoCorrectionStateChanged(boolean isAutoCorrection) {
- if (isAutoCorrection != mIsAutoCorrectionActive) {
- LatinKeyboardView keyboardView = getInputView();
+ if (mIsAutoCorrectionActive != isAutoCorrection) {
mIsAutoCorrectionActive = isAutoCorrection;
- keyboardView.invalidateKey(((LatinKeyboard) keyboardView.getKeyboard())
- .onAutoCorrectionStateChanged(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);
+ }
}
}
@@ -767,8 +822,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))
|| (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_AUTO))
&& Utils.hasMultipleEnabledIMEsOrSubtypes(
- ((InputMethodManager) context.getSystemService(
- Context.INPUT_METHOD_SERVICE))))) {
+ (InputMethodManagerCompatWrapper.getInstance(context))))) {
return true;
}
return false;
@@ -779,8 +833,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private static int getF2KeyMode(SharedPreferences prefs, Context context,
EditorInfo attribute) {
- final boolean clobberSettingsKey = Utils.inPrivateImeOptions(context.getPackageName(),
- LatinIME.IME_OPTION_NO_SETTINGS_KEY, attribute);
+ final boolean clobberSettingsKey = Utils.inPrivateImeOptions(
+ context.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY, attribute);
final Resources res = context.getResources();
final String settingsKeyMode = prefs.getString(Settings.PREF_SETTINGS_KEY,
res.getString(DEFAULT_SETTINGS_KEY_MODE));
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index ac094e029..e31aa8478 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.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -30,132 +29,72 @@ import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
-import android.os.Handler;
import android.os.Message;
-import android.os.SystemClock;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.TypedValue;
-import android.view.GestureDetector;
-import android.view.Gravity;
import android.view.LayoutInflater;
-import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
-import android.widget.PopupWindow;
+import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.inputmethod.compat.FrameLayoutCompatUtils;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.WeakHashMap;
/**
- * A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key
- * presses and touch movements.
+ * A view that renders a virtual {@link Keyboard}.
*
+ * @attr ref R.styleable#KeyboardView_backgroundDimAmount
* @attr ref R.styleable#KeyboardView_keyBackground
+ * @attr ref R.styleable#KeyboardView_keyLetterRatio
+ * @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_keyHintLabelRatio
+ * @attr ref R.styleable#KeyboardView_keyLabelHorizontalPadding
+ * @attr ref R.styleable#KeyboardView_keyHintLetterPadding
+ * @attr ref R.styleable#KeyboardView_keyUppercaseLetterPadding
+ * @attr ref R.styleable#KeyboardView_keyTextStyle
* @attr ref R.styleable#KeyboardView_keyPreviewLayout
+ * @attr ref R.styleable#KeyboardView_keyPreviewTextRatio
* @attr ref R.styleable#KeyboardView_keyPreviewOffset
- * @attr ref R.styleable#KeyboardView_labelTextSize
- * @attr ref R.styleable#KeyboardView_keyTextSize
+ * @attr ref R.styleable#KeyboardView_keyPreviewHeight
* @attr ref R.styleable#KeyboardView_keyTextColor
- * @attr ref R.styleable#KeyboardView_verticalCorrection
- * @attr ref R.styleable#KeyboardView_popupLayout
+ * @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_shadowColor
+ * @attr ref R.styleable#KeyboardView_shadowRadius
*/
-public class KeyboardView extends View implements PointerTracker.UIProxy {
- private static final String TAG = KeyboardView.class.getSimpleName();
- private static final boolean DEBUG_SHOW_ALIGN = false;
+public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private static final boolean DEBUG_KEYBOARD_GRID = false;
- private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = true;
- private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
-
- public static final int COLOR_SCHEME_WHITE = 0;
- public static final int COLOR_SCHEME_BLACK = 1;
-
- // Timing constants
- private final int mKeyRepeatInterval;
-
// Miscellaneous constants
private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable };
- private static final int HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL = -1;
// XML attribute
- private int mKeyLetterSize;
- private int mKeyTextColor;
- private int mKeyTextColorDisabled;
- private Typeface mKeyLetterStyle = Typeface.DEFAULT;
- private int mLabelTextSize;
- private int mColorScheme = COLOR_SCHEME_WHITE;
- private int mShadowColor;
- private float mShadowRadius;
- private Drawable mKeyBackground;
- private float mBackgroundDimAmount;
- private float mKeyHysteresisDistance;
- private float mVerticalCorrection;
- private int mPreviewOffset;
- private int mPreviewHeight;
- private int mPopupLayout;
+ private final float mBackgroundDimAmount;
+
+ // HORIZONTAL ELLIPSIS "...", character for popup hint.
+ private static final String POPUP_HINT_CHAR = "\u2026";
// Main keyboard
private Keyboard mKeyboard;
- private Key[] mKeys;
-
- // Key preview popup
- private boolean mInForeground;
- private TextView mPreviewText;
- private PopupWindow mPreviewPopup;
- private int mPreviewTextSizeLarge;
- private int[] mOffsetInWindow;
- private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY;
- private boolean mShowPreview = true;
- private int mPopupPreviewOffsetX;
- private int mPopupPreviewOffsetY;
- private int mWindowY;
- private int mPopupPreviewDisplayedY;
- private final int mDelayBeforePreview;
- private final int mDelayAfterPreview;
-
- // Popup mini keyboard
- private PopupWindow mMiniKeyboardPopup;
- private KeyboardView mMiniKeyboardView;
- private View mMiniKeyboardParent;
- private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>();
- private int mMiniKeyboardOriginX;
- private int mMiniKeyboardOriginY;
- private long mMiniKeyboardPopupTime;
- private int[] mWindowOffset;
- private final float mMiniKeyboardSlideAllowance;
- private int mMiniKeyboardTrackerId;
- private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
-
- /** Listener for {@link KeyboardActionListener}. */
- private KeyboardActionListener mKeyboardActionListener;
-
- private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>();
-
- // TODO: Let the PointerTracker class manage this pointer queue
- private final PointerTrackerQueue mPointerQueue = new PointerTrackerQueue();
+ private final KeyDrawParams mKeyDrawParams;
- private final boolean mHasDistinctMultitouch;
- private int mOldPointerCount = 1;
-
- // Accessibility
- private boolean mIsAccessibilityEnabled;
-
- protected KeyDetector mKeyDetector = new ProximityKeyDetector();
-
- // Swipe gesture detector
- private GestureDetector mGestureDetector;
- private final SwipeTracker mSwipeTracker = new SwipeTracker();
- private final int mSwipeThreshold;
- private final boolean mDisambiguateSwipe;
+ // Key preview
+ private final KeyPreviewDrawParams mKeyPreviewDrawParams;
+ private final TextView mPreviewText;
+ private boolean mShowKeyPreviewPopup = true;
+ private final int mDelayBeforePreview;
+ private int mDelayAfterPreview;
+ private ViewGroup mPreviewPlacer;
// Drawing
/** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/
@@ -172,136 +111,204 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private Bitmap mBuffer;
/** The canvas for the above mutable keyboard bitmap */
private Canvas mCanvas;
- private final Paint mPaint;
- private final Rect mPadding;
+ private final Paint mPaint = new Paint();
// This map caches key label text height in pixel as value and key label text size as map key.
- private final HashMap<Integer, Integer> mTextHeightCache = new HashMap<Integer, Integer>();
- // Distance from horizontal center of the key, proportional to key label text height and width.
- private final float KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER = 0.45f;
- private final float KEY_LABEL_VERTICAL_PADDING_FACTOR = 1.60f;
- private final String KEY_LABEL_REFERENCE_CHAR = "H";
- private final int KEY_LABEL_OPTION_ALIGN_LEFT = 1;
- private final int KEY_LABEL_OPTION_ALIGN_RIGHT = 2;
- private final int KEY_LABEL_OPTION_ALIGN_BOTTOM = 8;
- private final int KEY_LABEL_OPTION_FONT_NORMAL = 16;
- private final int mKeyLabelHorizontalPadding;
-
- private final UIHandler mHandler = new UIHandler();
-
- class UIHandler extends Handler {
- private static final int MSG_POPUP_PREVIEW = 1;
- private static final int MSG_DISMISS_PREVIEW = 2;
- private static final int MSG_REPEAT_KEY = 3;
- private static final int MSG_LONGPRESS_KEY = 4;
- private static final int MSG_LONGPRESS_SHIFT_KEY = 5;
- private static final int MSG_IGNORE_DOUBLE_TAP = 6;
-
- private boolean mInKeyRepeat;
+ private static final HashMap<Integer, Float> sTextHeightCache =
+ new HashMap<Integer, Float>();
+ // This map caches key label text width in pixel as value and key label text size as map key.
+ private static final HashMap<Integer, Float> sTextWidthCache =
+ new HashMap<Integer, Float>();
+ private static final String KEY_LABEL_REFERENCE_CHAR = "M";
+
+ private static final int MEASURESPEC_UNSPECIFIED = MeasureSpec.makeMeasureSpec(
+ 0, MeasureSpec.UNSPECIFIED);
+
+ 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;
+
+ public DrawingHandler(KeyboardView outerInstance) {
+ super(outerInstance);
+ }
@Override
public void handleMessage(Message msg) {
+ final KeyboardView keyboardView = getOuterInstance();
+ final PointerTracker tracker = (PointerTracker) msg.obj;
switch (msg.what) {
- case MSG_POPUP_PREVIEW:
- showKey(msg.arg1, (PointerTracker)msg.obj);
- break;
- case MSG_DISMISS_PREVIEW:
- mPreviewPopup.dismiss();
- break;
- case MSG_REPEAT_KEY: {
- final PointerTracker tracker = (PointerTracker)msg.obj;
- tracker.repeatKey(msg.arg1);
- startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker);
- break;
- }
- case MSG_LONGPRESS_KEY: {
- final PointerTracker tracker = (PointerTracker)msg.obj;
- openPopupIfRequired(msg.arg1, tracker);
- break;
- }
- case MSG_LONGPRESS_SHIFT_KEY: {
- final PointerTracker tracker = (PointerTracker)msg.obj;
- onLongPressShiftKey(tracker);
- break;
- }
+ case MSG_SHOW_KEY_PREVIEW:
+ keyboardView.showKey(msg.arg1, tracker);
+ break;
+ case MSG_DISMISS_KEY_PREVIEW:
+ keyboardView.mPreviewText.setVisibility(View.INVISIBLE);
+ break;
}
}
- public void popupPreview(long delay, int keyIndex, PointerTracker tracker) {
- removeMessages(MSG_POPUP_PREVIEW);
- if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
+ public void showKeyPreview(long delay, int keyIndex, PointerTracker tracker) {
+ final KeyboardView keyboardView = getOuterInstance();
+ removeMessages(MSG_SHOW_KEY_PREVIEW);
+ if (keyboardView.mPreviewText.getVisibility() == VISIBLE || delay == 0) {
// Show right away, if it's already visible and finger is moving around
- showKey(keyIndex, tracker);
+ keyboardView.showKey(keyIndex, tracker);
} else {
- sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker),
- delay);
- }
- }
-
- public void cancelPopupPreview() {
- removeMessages(MSG_POPUP_PREVIEW);
- }
-
- public void dismissPreview(long delay) {
- if (mPreviewPopup.isShowing()) {
- sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay);
+ sendMessageDelayed(
+ obtainMessage(MSG_SHOW_KEY_PREVIEW, keyIndex, 0, tracker), delay);
}
}
- public void cancelDismissPreview() {
- removeMessages(MSG_DISMISS_PREVIEW);
- }
-
- public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
- mInKeyRepeat = true;
- sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
- }
-
- public void cancelKeyRepeatTimer() {
- mInKeyRepeat = false;
- removeMessages(MSG_REPEAT_KEY);
- }
-
- public boolean isInKeyRepeat() {
- return mInKeyRepeat;
- }
-
- public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
- cancelLongPressTimers();
- sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
- }
-
- public void startLongPressShiftTimer(long delay, int keyIndex, PointerTracker tracker) {
- cancelLongPressTimers();
- if (ENABLE_CAPSLOCK_BY_LONGPRESS) {
- sendMessageDelayed(
- obtainMessage(MSG_LONGPRESS_SHIFT_KEY, keyIndex, 0, tracker), delay);
- }
+ public void cancelShowKeyPreview(PointerTracker tracker) {
+ removeMessages(MSG_SHOW_KEY_PREVIEW, tracker);
}
- public void cancelLongPressTimers() {
- removeMessages(MSG_LONGPRESS_KEY);
- removeMessages(MSG_LONGPRESS_SHIFT_KEY);
+ public void cancelAllShowKeyPreviews() {
+ removeMessages(MSG_SHOW_KEY_PREVIEW);
}
- public void cancelKeyTimers() {
- cancelKeyRepeatTimer();
- cancelLongPressTimers();
- removeMessages(MSG_IGNORE_DOUBLE_TAP);
+ public void dismissKeyPreview(long delay, PointerTracker tracker) {
+ sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay);
}
- public void startIgnoringDoubleTap() {
- sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
- ViewConfiguration.getDoubleTapTimeout());
+ public void cancelDismissKeyPreview(PointerTracker tracker) {
+ removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker);
}
- public boolean isIgnoringDoubleTap() {
- return hasMessages(MSG_IGNORE_DOUBLE_TAP);
+ public void cancelAllDismissKeyPreviews() {
+ removeMessages(MSG_DISMISS_KEY_PREVIEW);
}
public void cancelAllMessages() {
- cancelKeyTimers();
- cancelPopupPreview();
- cancelDismissPreview();
+ cancelAllShowKeyPreviews();
+ cancelAllDismissKeyPreviews();
+ }
+ }
+
+ private static class KeyDrawParams {
+ // XML attributes
+ public final int mKeyTextColor;
+ public final int mKeyTextInactivatedColor;
+ public final Typeface mKeyTextStyle;
+ public final float mKeyLabelHorizontalPadding;
+ public final float mKeyHintLetterPadding;
+ public final float mKeyUppercaseLetterPadding;
+ 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;
+
+ private final float mKeyLetterRatio;
+ private final float mKeyLargeLetterRatio;
+ private final float mKeyLabelRatio;
+ private final float mKeyHintLetterRatio;
+ private final float mKeyUppercaseLetterRatio;
+ private final float mKeyHintLabelRatio;
+
+ public final Rect mPadding = new Rect();
+ public int mKeyLetterSize;
+ public int mKeyLargeLetterSize;
+ public int mKeyLabelSize;
+ public int mKeyHintLetterSize;
+ public int mKeyUppercaseLetterSize;
+ public int mKeyHintLabelSize;
+
+ public KeyDrawParams(TypedArray a) {
+ mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground);
+ mKeyLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLetterRatio);
+ mKeyLargeLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLargeLetterRatio);
+ mKeyLabelRatio = getRatio(a, R.styleable.KeyboardView_keyLabelRatio);
+ mKeyHintLetterRatio = getRatio(a, R.styleable.KeyboardView_keyHintLetterRatio);
+ mKeyUppercaseLetterRatio = getRatio(a,
+ R.styleable.KeyboardView_keyUppercaseLetterRatio);
+ mKeyHintLabelRatio = getRatio(a, R.styleable.KeyboardView_keyHintLabelRatio);
+ mKeyLabelHorizontalPadding = a.getDimension(
+ R.styleable.KeyboardView_keyLabelHorizontalPadding, 0);
+ mKeyHintLetterPadding = a.getDimension(
+ R.styleable.KeyboardView_keyHintLetterPadding, 0);
+ mKeyUppercaseLetterPadding = a.getDimension(
+ R.styleable.KeyboardView_keyUppercaseLetterPadding, 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);
+ mKeyTextStyle = Typeface.defaultFromStyle(
+ a.getInt(R.styleable.KeyboardView_keyTextStyle, Typeface.NORMAL));
+ mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
+ mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f);
+
+ mKeyBackground.getPadding(mPadding);
+ }
+
+ public void updateKeyHeight(int keyHeight) {
+ mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
+ mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio);
+ mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio);
+ mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio);
+ mKeyUppercaseLetterSize = (int)(keyHeight * mKeyUppercaseLetterRatio);
+ mKeyHintLabelSize = (int)(keyHeight * mKeyHintLabelRatio);
+ }
+ }
+
+ private static class KeyPreviewDrawParams {
+ // XML attributes.
+ public final Drawable mPreviewBackground;
+ public final Drawable mPreviewLeftBackground;
+ public final Drawable mPreviewRightBackground;
+ public final Drawable mPreviewSpacebarBackground;
+ public final int mPreviewTextColor;
+ public final int mPreviewOffset;
+ public final int mPreviewHeight;
+ public final Typeface mKeyTextStyle;
+
+ private final float mPreviewTextRatio;
+ private final float mKeyLetterRatio;
+
+ public int mPreviewTextSize;
+ public int mKeyLetterSize;
+ public final int[] mCoordinates = new int[2];
+
+ private static final int PREVIEW_ALPHA = 240;
+
+ public KeyPreviewDrawParams(TypedArray a, KeyDrawParams keyDrawParams) {
+ mPreviewBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewBackground);
+ mPreviewLeftBackground = a.getDrawable(
+ R.styleable.KeyboardView_keyPreviewLeftBackground);
+ mPreviewRightBackground = a.getDrawable(
+ R.styleable.KeyboardView_keyPreviewRightBackground);
+ mPreviewSpacebarBackground = a.getDrawable(
+ R.styleable.KeyboardView_keyPreviewSpacebarBackground);
+ setAlpha(mPreviewBackground, PREVIEW_ALPHA);
+ setAlpha(mPreviewLeftBackground, PREVIEW_ALPHA);
+ setAlpha(mPreviewRightBackground, PREVIEW_ALPHA);
+ mPreviewOffset = a.getDimensionPixelOffset(
+ R.styleable.KeyboardView_keyPreviewOffset, 0);
+ mPreviewHeight = a.getDimensionPixelSize(
+ R.styleable.KeyboardView_keyPreviewHeight, 80);
+ mPreviewTextRatio = getRatio(a, R.styleable.KeyboardView_keyPreviewTextRatio);
+ mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
+
+ mKeyLetterRatio = keyDrawParams.mKeyLetterRatio;
+ mKeyTextStyle = keyDrawParams.mKeyTextStyle;
+ }
+
+ public void updateKeyHeight(int keyHeight) {
+ mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
+ mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
+ }
+
+ private static void setAlpha(Drawable drawable, int alpha) {
+ if (drawable == null)
+ return;
+ drawable.setAlpha(alpha);
}
}
@@ -314,199 +321,32 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
- int previewLayout = 0;
- int keyTextSize = 0;
- int n = a.getIndexCount();
-
- for (int i = 0; i < n; i++) {
- int attr = a.getIndex(i);
-
- switch (attr) {
- case R.styleable.KeyboardView_keyBackground:
- mKeyBackground = a.getDrawable(attr);
- break;
- case R.styleable.KeyboardView_keyHysteresisDistance:
- mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0);
- break;
- case R.styleable.KeyboardView_verticalCorrection:
- mVerticalCorrection = a.getDimensionPixelOffset(attr, 0);
- break;
- case R.styleable.KeyboardView_keyPreviewLayout:
- previewLayout = a.getResourceId(attr, 0);
- break;
- case R.styleable.KeyboardView_keyPreviewOffset:
- mPreviewOffset = a.getDimensionPixelOffset(attr, 0);
- break;
- case R.styleable.KeyboardView_keyPreviewHeight:
- mPreviewHeight = a.getDimensionPixelSize(attr, 80);
- break;
- case R.styleable.KeyboardView_keyLetterSize:
- mKeyLetterSize = a.getDimensionPixelSize(attr, 18);
- break;
- case R.styleable.KeyboardView_keyTextColor:
- mKeyTextColor = a.getColor(attr, 0xFF000000);
- break;
- case R.styleable.KeyboardView_keyTextColorDisabled:
- mKeyTextColorDisabled = a.getColor(attr, 0xFF000000);
- break;
- case R.styleable.KeyboardView_labelTextSize:
- mLabelTextSize = a.getDimensionPixelSize(attr, 14);
- break;
- case R.styleable.KeyboardView_popupLayout:
- mPopupLayout = a.getResourceId(attr, 0);
- break;
- case R.styleable.KeyboardView_shadowColor:
- mShadowColor = a.getColor(attr, 0);
- break;
- case R.styleable.KeyboardView_shadowRadius:
- mShadowRadius = a.getFloat(attr, 0f);
- break;
- // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
- case R.styleable.KeyboardView_backgroundDimAmount:
- mBackgroundDimAmount = a.getFloat(attr, 0.5f);
- break;
- case R.styleable.KeyboardView_keyLetterStyle:
- mKeyLetterStyle = Typeface.defaultFromStyle(a.getInt(attr, Typeface.NORMAL));
- break;
- case R.styleable.KeyboardView_colorScheme:
- mColorScheme = a.getInt(attr, COLOR_SCHEME_WHITE);
- break;
- }
- }
-
- final Resources res = getResources();
-
- mPreviewPopup = new PopupWindow(context);
+ mKeyDrawParams = new KeyDrawParams(a);
+ mKeyPreviewDrawParams = new KeyPreviewDrawParams(a, mKeyDrawParams);
+ final int previewLayout = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
if (previewLayout != 0) {
mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null);
- mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large);
- mPreviewPopup.setContentView(mPreviewText);
- mPreviewPopup.setBackgroundDrawable(null);
} else {
- mShowPreview = false;
+ mPreviewText = null;
+ mShowKeyPreviewPopup = false;
}
- mPreviewPopup.setTouchable(false);
- mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
+ 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);
- mKeyLabelHorizontalPadding = (int)res.getDimension(
- R.dimen.key_label_horizontal_alignment_padding);
- mMiniKeyboardParent = this;
- mMiniKeyboardPopup = new PopupWindow(context);
- mMiniKeyboardPopup.setBackgroundDrawable(null);
- mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation);
- // Allow popup window to be drawn off the screen.
- mMiniKeyboardPopup.setClippingEnabled(false);
-
- mPaint = new Paint();
mPaint.setAntiAlias(true);
- mPaint.setTextSize(keyTextSize);
mPaint.setTextAlign(Align.CENTER);
mPaint.setAlpha(255);
-
- mPadding = new Rect(0, 0, 0, 0);
- mKeyBackground.getPadding(mPadding);
-
- mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density);
- // TODO: Refer frameworks/base/core/res/res/values/config.xml
- mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation);
- mMiniKeyboardSlideAllowance = res.getDimension(R.dimen.mini_keyboard_slide_allowance);
- mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean(
- R.bool.config_show_mini_keyboard_at_touched_point);
-
- GestureDetector.SimpleOnGestureListener listener =
- new GestureDetector.SimpleOnGestureListener() {
- private boolean mProcessingShiftDoubleTapEvent = false;
-
- @Override
- public boolean onFling(MotionEvent me1, MotionEvent me2, float velocityX,
- float velocityY) {
- final float absX = Math.abs(velocityX);
- final float absY = Math.abs(velocityY);
- float deltaY = me2.getY() - me1.getY();
- int travelY = getHeight() / 2; // Half the keyboard height
- mSwipeTracker.computeCurrentVelocity(1000);
- final float endingVelocityY = mSwipeTracker.getYVelocity();
- if (velocityY > mSwipeThreshold && absX < absY / 2 && deltaY > travelY) {
- if (mDisambiguateSwipe && endingVelocityY >= velocityY / 4) {
- onSwipeDown();
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent firstDown) {
- if (ENABLE_CAPSLOCK_BY_DOUBLETAP && mKeyboard instanceof LatinKeyboard
- && ((LatinKeyboard) mKeyboard).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;
- }
-
- @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} .
- final boolean ignoringDoubleTap = mHandler.isIgnoringDoubleTap();
- if (!ignoringDoubleTap)
- onDoubleTapShiftKey(tracker);
- return true;
- }
- // Otherwise these events should not be handled as double tap.
- mProcessingShiftDoubleTapEvent = false;
- }
- return mProcessingShiftDoubleTapEvent;
- }
- };
-
- final boolean ignoreMultitouch = true;
- mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch);
- mGestureDetector.setIsLongpressEnabled(false);
-
- mHasDistinctMultitouch = context.getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
- mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
}
- public void startIgnoringDoubleTap() {
- if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
- mHandler.startIgnoringDoubleTap();
- }
-
- public void setOnKeyboardActionListener(KeyboardActionListener listener) {
- mKeyboardActionListener = listener;
- for (PointerTracker tracker : mPointerTrackers) {
- tracker.setOnKeyboardActionListener(listener);
- }
- }
-
- /**
- * Returns the {@link KeyboardActionListener} object.
- * @return the listener attached to this keyboard
- */
- protected KeyboardActionListener getOnKeyboardActionListener() {
- return mKeyboardActionListener;
+ // Read fraction value in TypedArray as float.
+ private static float getRatio(TypedArray a, int index) {
+ return a.getFraction(index, 1000, 1000, 1) / 1000.0f;
}
/**
@@ -517,24 +357,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
* @param keyboard the keyboard to display in this view
*/
public void setKeyboard(Keyboard keyboard) {
- if (mKeyboard != null) {
- dismissKeyPreview();
- }
// Remove any pending messages, except dismissing preview
- mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
+ mDrawingHandler.cancelAllShowKeyPreviews();
mKeyboard = keyboard;
LatinImeLogger.onSetKeyboard(keyboard);
- mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
- -getPaddingTop() + mVerticalCorrection);
- for (PointerTracker tracker : mPointerTrackers) {
- tracker.setKeyboard(keyboard, mKeys, mKeyHysteresisDistance);
- }
requestLayout();
mKeyboardChanged = true;
invalidateAllKeys();
- mKeyDetector.setProximityThreshold(KeyDetector.getMostCommonKeyWidth(keyboard));
- mMiniKeyboardCache.clear();
+ final int keyHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
+ mKeyDrawParams.updateKeyHeight(keyHeight);
+ mKeyPreviewDrawParams.updateKeyHeight(keyHeight);
}
/**
@@ -547,88 +379,24 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
/**
- * Returns whether the device has distinct multi-touch panel.
- * @return true if the device has distinct multi-touch panel.
- */
- @Override
- public boolean hasDistinctMultitouch() {
- return mHasDistinctMultitouch;
- }
-
- /**
- * Enables or disables accessibility.
- * @param accessibilityEnabled whether or not to enable accessibility
- */
- public void setAccessibilityEnabled(boolean accessibilityEnabled) {
- mIsAccessibilityEnabled = accessibilityEnabled;
-
- // Propagate this change to all existing pointer trackers.
- for (PointerTracker tracker : mPointerTrackers) {
- tracker.setAccessibilityEnabled(accessibilityEnabled);
- }
- }
-
- /**
- * Returns whether the device has accessibility enabled.
- * @return true if the device has accessibility enabled.
- */
- @Override
- public boolean isAccessibilityEnabled() {
- return mIsAccessibilityEnabled;
- }
-
- /**
* Enables or disables the key feedback popup. This is a popup that shows a magnified
* version of the depressed key. By default the preview is enabled.
- * @param previewEnabled whether or not to enable the key feedback popup
- * @see #isPreviewEnabled()
+ * @param previewEnabled whether or not to enable the key feedback preview
+ * @param delay the delay after which the preview is dismissed
+ * @see #isKeyPreviewPopupEnabled()
*/
- public void setPreviewEnabled(boolean previewEnabled) {
- mShowPreview = previewEnabled;
+ public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ mShowKeyPreviewPopup = previewEnabled;
+ mDelayAfterPreview = delay;
}
/**
- * Returns the enabled state of the key feedback popup.
- * @return whether or not the key feedback popup is enabled
- * @see #setPreviewEnabled(boolean)
+ * Returns the enabled state of the key feedback preview
+ * @return whether or not the key feedback preview is enabled
+ * @see #setKeyPreviewPopupEnabled(boolean, int)
*/
- public boolean isPreviewEnabled() {
- return mShowPreview;
- }
-
- public int getColorScheme() {
- return mColorScheme;
- }
-
- public void setPopupOffset(int x, int y) {
- mPopupPreviewOffsetX = x;
- mPopupPreviewOffsetY = y;
- mPreviewPopup.dismiss();
- }
-
- /**
- * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
- * codes for adjacent keys. When disabled, only the primary key code will be
- * reported.
- * @param enabled whether or not the proximity correction is enabled
- */
- public void setProximityCorrectionEnabled(boolean enabled) {
- mKeyDetector.setProximityCorrectionEnabled(enabled);
- }
-
- /**
- * Returns true if proximity correction is enabled.
- */
- public boolean isProximityCorrectionEnabled() {
- return mKeyDetector.isProximityCorrectionEnabled();
- }
-
- protected CharSequence adjustCase(CharSequence label) {
- if (mKeyboard.isShiftedOrShiftLocked() && label != null && label.length() < 3
- && Character.isLowerCase(label.charAt(0))) {
- return label.toString().toUpperCase();
- }
- return label;
+ public boolean isKeyPreviewPopupEnabled() {
+ return mShowKeyPreviewPopup;
}
@Override
@@ -666,157 +434,54 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mDirtyRect.union(0, 0, width, height);
}
if (mBuffer == null || mBuffer.getWidth() != width || mBuffer.getHeight() != height) {
+ if (mBuffer != null)
+ mBuffer.recycle();
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mCanvas = new Canvas(mBuffer);
+ if (mCanvas != null) {
+ mCanvas.setBitmap(mBuffer);
+ } else {
+ mCanvas = new Canvas(mBuffer);
+ }
}
final Canvas canvas = mCanvas;
canvas.clipRect(mDirtyRect, Op.REPLACE);
+ canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
if (mKeyboard == null) return;
- final Paint paint = mPaint;
- final Drawable keyBackground = mKeyBackground;
- final Rect padding = mPadding;
- final int kbdPaddingLeft = getPaddingLeft();
- final int kbdPaddingTop = getPaddingTop();
- final Key[] keys = mKeys;
final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
- final boolean drawSingleKey = (mInvalidatedKey != null
- && mInvalidatedKeyRect.contains(mDirtyRect));
-
- canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
- final int keyCount = keys.length;
- for (int i = 0; i < keyCount; i++) {
- final Key key = keys[i];
- if (drawSingleKey && key != mInvalidatedKey) {
- continue;
- }
- int[] drawableState = key.getCurrentDrawableState();
- keyBackground.setState(drawableState);
-
- // Switch the character to uppercase if shift is pressed
- String label = key.mLabel == null? null : adjustCase(key.mLabel).toString();
-
- final Rect bounds = keyBackground.getBounds();
- if (key.mWidth != bounds.right || key.mHeight != bounds.bottom) {
- keyBackground.setBounds(0, 0, key.mWidth, key.mHeight);
- }
- canvas.translate(key.mX + kbdPaddingLeft, key.mY + kbdPaddingTop);
- keyBackground.draw(canvas);
-
- final int rowHeight = padding.top + key.mHeight;
- // Draw key label
- if (label != null) {
- // For characters, use large font. For labels like "Done", use small font.
- final int labelSize = getLabelSizeAndSetPaint(label, key.mLabelOption, paint);
- final int labelCharHeight = getLabelCharHeight(labelSize, paint);
-
- // Vertical label text alignment.
- final float baseline;
- if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) {
- baseline = key.mHeight -
- + labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR;
- if (DEBUG_SHOW_ALIGN)
- drawHorizontalLine(canvas, (int)baseline, key.mWidth, 0xc0008000,
- new Paint());
- } else { // Align center
- final float centerY = (key.mHeight + padding.top - padding.bottom) / 2;
- baseline = centerY
- + labelCharHeight * KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER;
- if (DEBUG_SHOW_ALIGN)
- drawHorizontalLine(canvas, (int)baseline, key.mWidth, 0xc0008000,
- new Paint());
- }
- // Horizontal label text alignment
- final int positionX;
- if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
- positionX = mKeyLabelHorizontalPadding + padding.left;
- paint.setTextAlign(Align.LEFT);
- if (DEBUG_SHOW_ALIGN)
- drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint());
- } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
- positionX = key.mWidth - mKeyLabelHorizontalPadding - padding.right;
- paint.setTextAlign(Align.RIGHT);
- if (DEBUG_SHOW_ALIGN)
- drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint());
- } else {
- positionX = (key.mWidth + padding.left - padding.right) / 2;
- paint.setTextAlign(Align.CENTER);
- if (DEBUG_SHOW_ALIGN) {
- if (label.length() > 1)
- drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint());
- }
- }
- if (key.mManualTemporaryUpperCaseHintIcon != null && isManualTemporaryUpperCase) {
- paint.setColor(mKeyTextColorDisabled);
- } else {
- paint.setColor(mKeyTextColor);
- }
- if (key.mEnabled) {
- // Set a drop shadow for the text
- paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor);
- } else {
- // Make label invisible
- paint.setColor(Color.TRANSPARENT);
- }
- canvas.drawText(label, positionX, baseline, paint);
- // Turn off drop shadow
- paint.setShadowLayer(0, 0, 0, 0);
- }
- // Draw key icon
- final Drawable icon = key.getIcon();
- if (key.mLabel == null && icon != null) {
- final int drawableWidth = icon.getIntrinsicWidth();
- final int drawableHeight = icon.getIntrinsicHeight();
- final int drawableX;
- final int drawableY = (
- key.mHeight + padding.top - padding.bottom - drawableHeight) / 2;
- if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) {
- drawableX = padding.left + mKeyLabelHorizontalPadding;
- if (DEBUG_SHOW_ALIGN)
- drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint());
- } else if ((key.mLabelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) {
- drawableX = key.mWidth - padding.right - mKeyLabelHorizontalPadding
- - drawableWidth;
- if (DEBUG_SHOW_ALIGN)
- drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight,
- 0xc0808000, new Paint());
- } else { // Align center
- drawableX = (key.mWidth + padding.left - padding.right - drawableWidth) / 2;
- if (DEBUG_SHOW_ALIGN)
- drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight,
- 0xc0008080, new Paint());
- }
- drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
- if (DEBUG_SHOW_ALIGN)
- drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
- 0x80c00000, new Paint());
- }
- if (key.mHintIcon != null) {
- final int drawableWidth = key.mWidth;
- final int drawableHeight = key.mHeight;
- final int drawableX = 0;
- final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL;
- Drawable hintIcon = (isManualTemporaryUpperCase
- && key.mManualTemporaryUpperCaseHintIcon != null)
- ? key.mManualTemporaryUpperCaseHintIcon : key.mHintIcon;
- drawIcon(canvas, hintIcon, drawableX, drawableY, drawableWidth, drawableHeight);
- if (DEBUG_SHOW_ALIGN)
- drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
- 0x80c0c000, new Paint());
+ final KeyDrawParams params = mKeyDrawParams;
+ if (mInvalidatedKey != null && mInvalidatedKeyRect.contains(mDirtyRect)) {
+ // Draw a single key.
+ final int keyDrawX = mInvalidatedKey.mX + mInvalidatedKey.mVisualInsetsLeft
+ + getPaddingLeft();
+ final int keyDrawY = mInvalidatedKey.mY + getPaddingTop();
+ canvas.translate(keyDrawX, keyDrawY);
+ onBufferDrawKey(mInvalidatedKey, canvas, mPaint, params, isManualTemporaryUpperCase);
+ canvas.translate(-keyDrawX, -keyDrawY);
+ } else {
+ // Draw all keys.
+ for (final Key key : mKeyboard.getKeys()) {
+ final int keyDrawX = key.mX + key.mVisualInsetsLeft + getPaddingLeft();
+ final int keyDrawY = key.mY + getPaddingTop();
+ canvas.translate(keyDrawX, keyDrawY);
+ onBufferDrawKey(key, canvas, mPaint, params, isManualTemporaryUpperCase);
+ canvas.translate(-keyDrawX, -keyDrawY);
}
- canvas.translate(-key.mX - kbdPaddingLeft, -key.mY - kbdPaddingTop);
}
- // TODO: Move this function to ProximityInfo for getting rid of public declarations for
+ // TODO: Move this function to ProximityInfo for getting rid of
+ // public declarations for
// GRID_WIDTH and GRID_HEIGHT
if (DEBUG_KEYBOARD_GRID) {
Paint p = new Paint();
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(1.0f);
p.setColor(0x800000c0);
- int cw = (mKeyboard.getMinWidth() + mKeyboard.GRID_WIDTH - 1) / mKeyboard.GRID_WIDTH;
- int ch = (mKeyboard.getHeight() + mKeyboard.GRID_HEIGHT - 1) / mKeyboard.GRID_HEIGHT;
+ int cw = (mKeyboard.getMinWidth() + mKeyboard.GRID_WIDTH - 1)
+ / mKeyboard.GRID_WIDTH;
+ int ch = (mKeyboard.getHeight() + mKeyboard.GRID_HEIGHT - 1)
+ / mKeyboard.GRID_HEIGHT;
for (int i = 0; i <= mKeyboard.GRID_WIDTH; i++)
canvas.drawLine(i * cw, 0, i * cw, ch * mKeyboard.GRID_HEIGHT, p);
for (int i = 0; i <= mKeyboard.GRID_HEIGHT; i++)
@@ -824,9 +489,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
// Overlay a dark rectangle to dim the keyboard
- if (mMiniKeyboardView != null) {
- paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
- canvas.drawRect(0, 0, width, height, paint);
+ if (needsToDimKeyboard()) {
+ mPaint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
+ canvas.drawRect(0, 0, width, height, mPaint);
}
mInvalidatedKey = null;
@@ -834,38 +499,231 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mDirtyRect.setEmpty();
}
- public int getLabelSizeAndSetPaint(CharSequence label, int keyLabelOption, Paint paint) {
- // For characters, use large font. For labels like "Done", use small font.
- final int labelSize;
- final Typeface labelStyle;
- if (label.length() > 1) {
- labelSize = mLabelTextSize;
- if ((keyLabelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) {
- labelStyle = Typeface.DEFAULT;
+ protected boolean needsToDimKeyboard() {
+ return false;
+ }
+
+ private static void onBufferDrawKey(final Key key, final Canvas canvas, Paint paint,
+ KeyDrawParams params, boolean isManualTemporaryUpperCase) {
+ final boolean debugShowAlign = LatinImeLogger.sVISUALDEBUG;
+ // Draw key background.
+ 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);
+
+ // Draw key top visuals.
+ final int keyWidth = key.mWidth;
+ final int keyHeight = key.mHeight;
+ final float centerX = keyWidth * 0.5f;
+ final float centerY = keyHeight * 0.5f;
+
+ if (debugShowAlign) {
+ drawRectangle(canvas, 0, 0, keyWidth, keyHeight, 0x800000c0, new Paint());
+ }
+
+ // Draw key label.
+ float positionX = centerX;
+ if (key.mLabel != null) {
+ // Switch the character to uppercase if shift is pressed
+ final CharSequence label = key.getCaseAdjustedLabel();
+ // 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,
+ params.mKeyLargeLetterSize, params.mKeyLabelSize, params.mKeyHintLabelSize);
+ paint.setTextSize(labelSize);
+ final float labelCharHeight = getCharHeight(paint);
+ final float labelCharWidth = getCharWidth(paint);
+
+ // Vertical label text alignment.
+ final float baseline = centerY + labelCharHeight / 2;
+
+ // Horizontal label text alignment
+ if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT) != 0) {
+ positionX = (int)params.mKeyLabelHorizontalPadding;
+ paint.setTextAlign(Align.LEFT);
+ } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_RIGHT) != 0) {
+ positionX = keyWidth - (int)params.mKeyLabelHorizontalPadding;
+ paint.setTextAlign(Align.RIGHT);
+ } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT_OF_CENTER) != 0) {
+ // TODO: Parameterise this?
+ positionX = centerX - labelCharWidth * 7 / 4;
+ paint.setTextAlign(Align.LEFT);
} else {
- labelStyle = Typeface.DEFAULT_BOLD;
+ positionX = centerX;
+ paint.setTextAlign(Align.CENTER);
+ }
+
+ if (key.hasUppercaseLetter() && isManualTemporaryUpperCase) {
+ paint.setColor(params.mKeyTextInactivatedColor);
+ } else {
+ paint.setColor(params.mKeyTextColor);
+ }
+ if (key.isEnabled()) {
+ // Set a drop shadow for the text
+ paint.setShadowLayer(params.mShadowRadius, 0, 0, params.mShadowColor);
+ } else {
+ // Make label invisible
+ paint.setColor(Color.TRANSPARENT);
+ }
+ canvas.drawText(label, 0, label.length(), positionX, baseline, paint);
+ // Turn off drop shadow
+ paint.setShadowLayer(0, 0, 0, 0);
+
+ if (debugShowAlign) {
+ final Paint line = new Paint();
+ drawHorizontalLine(canvas, baseline, keyWidth, 0xc0008000, line);
+ drawVerticalLine(canvas, positionX, keyHeight, 0xc0800080, line);
}
- } else {
- labelSize = mKeyLetterSize;
- labelStyle = mKeyLetterStyle;
}
+
+ // Draw hint label.
+ if (key.mHintLabel != null) {
+ final CharSequence 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 { // key.hasHintLetter()
+ hintColor = params.mKeyHintLetterColor;
+ hintSize = params.mKeyHintLetterSize;
+ }
+ paint.setColor(hintColor);
+ paint.setTextSize(hintSize);
+ final float hintCharWidth = getCharWidth(paint);
+ final float hintX, hintY;
+ if (key.hasHintLabel()) {
+ // TODO: Generalize the following calculations.
+ hintX = positionX + hintCharWidth * 2;
+ hintY = centerY + getCharHeight(paint) / 2;
+ paint.setTextAlign(Align.LEFT);
+ } else if (key.hasUppercaseLetter()) {
+ hintX = keyWidth - params.mKeyUppercaseLetterPadding - hintCharWidth / 2;
+ hintY = -paint.ascent() + params.mKeyUppercaseLetterPadding;
+ paint.setTextAlign(Align.CENTER);
+ } else { // key.hasHintLetter()
+ hintX = keyWidth - params.mKeyHintLetterPadding - hintCharWidth / 2;
+ hintY = -paint.ascent() + params.mKeyHintLetterPadding;
+ paint.setTextAlign(Align.CENTER);
+ }
+ canvas.drawText(hint, 0, hint.length(), hintX, hintY, paint);
+
+ if (debugShowAlign) {
+ final Paint line = new Paint();
+ drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
+ drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
+ }
+ }
+
+ // Draw key icon.
+ final Drawable icon = key.getIcon();
+ if (key.mLabel == null && icon != null) {
+ final int iconWidth = icon.getIntrinsicWidth();
+ final int iconHeight = icon.getIntrinsicHeight();
+ final int iconX, alignX;
+ final int iconY = (keyHeight - iconHeight) / 2;
+ if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT) != 0) {
+ iconX = (int)params.mKeyLabelHorizontalPadding;
+ alignX = iconX;
+ } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_RIGHT) != 0) {
+ iconX = keyWidth - (int)params.mKeyLabelHorizontalPadding - iconWidth;
+ alignX = iconX + iconWidth;
+ } else { // Align center
+ iconX = (keyWidth - iconWidth) / 2;
+ alignX = iconX + iconWidth / 2;
+ }
+ drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
+
+ if (debugShowAlign) {
+ 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()) {
+ paint.setTextSize(params.mKeyHintLetterSize);
+ paint.setColor(params.mKeyHintLabelColor);
+ paint.setTextAlign(Align.CENTER);
+ final float hintX = keyWidth - params.mKeyHintLetterPadding - getCharWidth(paint) / 2;
+ final float hintY = keyHeight - params.mKeyHintLetterPadding;
+ 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);
+ }
+ }
+ }
+
+ // This method is currently being used only by MiniKeyboardBuilder
+ public int getDefaultLabelSizeAndSetPaint(Paint paint) {
+ // For characters, use large font. For labels like "Done", use small font.
+ final int labelSize = mKeyDrawParams.mKeyLabelSize;
paint.setTextSize(labelSize);
- paint.setTypeface(labelStyle);
+ paint.setTypeface(mKeyDrawParams.mKeyTextStyle);
return labelSize;
}
- private int getLabelCharHeight(int labelSize, Paint paint) {
- Integer labelHeightValue = mTextHeightCache.get(labelSize);
- final int labelCharHeight;
- if (labelHeightValue != null) {
- labelCharHeight = labelHeightValue;
+ private static final Rect sTextBounds = new Rect();
+
+ private static float getCharHeight(Paint paint) {
+ final int labelSize = (int)paint.getTextSize();
+ final Float cachedValue = sTextHeightCache.get(labelSize);
+ if (cachedValue != null)
+ return cachedValue;
+
+ paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, sTextBounds);
+ final float height = sTextBounds.height();
+ sTextHeightCache.put(labelSize, height);
+ return height;
+ }
+
+ private static float getCharWidth(Paint paint) {
+ final int labelSize = (int)paint.getTextSize();
+ final Typeface face = paint.getTypeface();
+ final Integer key;
+ if (face == Typeface.DEFAULT) {
+ key = labelSize;
+ } else if (face == Typeface.DEFAULT_BOLD) {
+ key = labelSize + 1000;
+ } else if (face == Typeface.MONOSPACE) {
+ key = labelSize + 2000;
} else {
- Rect textBounds = new Rect();
- paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, textBounds);
- labelCharHeight = textBounds.height();
- mTextHeightCache.put(labelSize, labelCharHeight);
+ key = labelSize;
}
- return labelCharHeight;
+
+ final Float cached = sTextWidthCache.get(key);
+ if (cached != null)
+ return cached;
+
+ paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, sTextBounds);
+ final float width = sTextBounds.width();
+ sTextWidthCache.put(key, width);
+ return width;
}
private static void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width,
@@ -876,21 +734,21 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
canvas.translate(-x, -y);
}
- private static void drawHorizontalLine(Canvas canvas, int y, int w, int color, Paint paint) {
+ private static void drawHorizontalLine(Canvas canvas, float y, float w, int color, Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
paint.setColor(color);
canvas.drawLine(0, y, w, y, paint);
}
- private static void drawVerticalLine(Canvas canvas, int x, int h, int color, Paint paint) {
+ private static void drawVerticalLine(Canvas canvas, float x, float h, int color, Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
paint.setColor(color);
canvas.drawLine(x, 0, x, h, paint);
}
- private static void drawRectangle(Canvas canvas, int x, int y, int w, int h, int color,
+ private static void drawRectangle(Canvas canvas, float x, float y, float w, float h, int color,
Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
@@ -900,123 +758,113 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
canvas.translate(-x, -y);
}
- public void setForeground(boolean foreground) {
- mInForeground = foreground;
+ public void cancelAllMessages() {
+ mDrawingHandler.cancelAllMessages();
}
- // TODO: clean up this method.
- private void dismissKeyPreview() {
- for (PointerTracker tracker : mPointerTrackers)
- tracker.releaseKey();
- showPreview(KeyDetector.NOT_A_KEY, null);
+ @Override
+ public void showKeyPreview(int keyIndex, PointerTracker tracker) {
+ if (mShowKeyPreviewPopup) {
+ mDrawingHandler.showKeyPreview(mDelayBeforePreview, keyIndex, tracker);
+ } else if (mKeyboard.needSpacebarPreview(keyIndex)) {
+ // Show key preview (in this case, slide language switcher) without any delay.
+ showKey(keyIndex, tracker);
+ }
}
@Override
- public void showPreview(int keyIndex, PointerTracker tracker) {
- int oldKeyIndex = mOldPreviewKeyIndex;
- mOldPreviewKeyIndex = keyIndex;
- // We should re-draw popup preview when 1) we need to hide the preview, 2) we will show
- // the space key preview and 3) pointer moves off the space key to other letter key, we
- // should hide the preview of the previous key.
- final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null)
- || (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
- && SubtypeSwitcher.getInstance().needsToDisplayLanguage()
- && (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex)));
- // If key changed and preview is on or the key is space (language switch is enabled)
- if (oldKeyIndex != keyIndex && (mShowPreview || (hidePreviewOrShowSpaceKeyPreview))) {
- if (keyIndex == KeyDetector.NOT_A_KEY) {
- mHandler.cancelPopupPreview();
- mHandler.dismissPreview(mDelayAfterPreview);
- } else if (tracker != null) {
- mHandler.popupPreview(mDelayBeforePreview, keyIndex, tracker);
- }
+ public void cancelShowKeyPreview(PointerTracker tracker) {
+ mDrawingHandler.cancelShowKeyPreview(tracker);
+ }
+
+ @Override
+ public void dismissKeyPreview(PointerTracker tracker) {
+ if (mShowKeyPreviewPopup) {
+ mDrawingHandler.cancelShowKeyPreview(tracker);
+ mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
+ } else if (mKeyboard.needSpacebarPreview(KeyDetector.NOT_A_KEY)) {
+ // Dismiss key preview (in this case, slide language switcher) without any delay.
+ mPreviewText.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ private void addKeyPreview(TextView keyPreview) {
+ if (mPreviewPlacer == null) {
+ mPreviewPlacer = FrameLayoutCompatUtils.getPlacer(
+ (ViewGroup)getRootView().findViewById(android.R.id.content));
}
+ final ViewGroup placer = mPreviewPlacer;
+ placer.addView(keyPreview, FrameLayoutCompatUtils.newLayoutParam(placer, 0, 0));
}
- // TODO Must fix popup preview on xlarge layout
+ // TODO: Introduce minimum duration for displaying key previews
+ // TODO: Display up to two key previews when the user presses two keys at the same time
private void showKey(final int keyIndex, PointerTracker tracker) {
- Key key = tracker.getKey(keyIndex);
+ final TextView previewText = mPreviewText;
+ // If the key preview has no parent view yet, add it to the ViewGroup which can place
+ // key preview absolutely in SoftInputWindow.
+ if (previewText.getParent() == null) {
+ addKeyPreview(previewText);
+ }
+
+ final Key key = tracker.getKey(keyIndex);
// If keyIndex is invalid or IME is already closed, we must not show key preview.
- // Trying to show preview PopupWindow while root window is closed causes
+ // Trying to show key preview while root window is closed causes
// WindowManager.BadTokenException.
- if (key == null || !mInForeground)
+ if (key == null)
return;
+
+ mDrawingHandler.cancelAllDismissKeyPreviews();
+ final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
+ final int keyDrawX = key.mX + key.mVisualInsetsLeft;
+ final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
// What we show as preview should match what we show on key top in onBufferDraw().
if (key.mLabel != null) {
// TODO Should take care of temporaryShiftLabel here.
- mPreviewText.setCompoundDrawables(null, null, null, null);
- mPreviewText.setText(adjustCase(tracker.getPreviewText(key)));
+ previewText.setCompoundDrawables(null, null, null, null);
if (key.mLabel.length() > 1) {
- mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
- mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mKeyLetterSize);
+ previewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
- mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
- mPreviewText.setTypeface(mKeyLetterStyle);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mPreviewTextSize);
+ previewText.setTypeface(params.mKeyTextStyle);
}
+ previewText.setText(key.getCaseAdjustedLabel());
} else {
final Drawable previewIcon = key.getPreviewIcon();
- mPreviewText.setCompoundDrawables(null, null, null,
+ previewText.setCompoundDrawables(null, null, null,
previewIcon != null ? previewIcon : key.getIcon());
- mPreviewText.setText(null);
+ previewText.setText(null);
}
- mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.mWidth
- + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
- final int popupHeight = mPreviewHeight;
- LayoutParams lp = mPreviewText.getLayoutParams();
- if (lp != null) {
- lp.width = popupWidth;
- lp.height = popupHeight;
+ if (key.mCode == Keyboard.CODE_SPACE) {
+ previewText.setBackgroundDrawable(params.mPreviewSpacebarBackground);
+ } else {
+ previewText.setBackgroundDrawable(params.mPreviewBackground);
}
- int popupPreviewX = key.mX - (popupWidth - key.mWidth) / 2;
- int popupPreviewY = key.mY - popupHeight + mPreviewOffset;
-
- mHandler.cancelDismissPreview();
- if (mOffsetInWindow == null) {
- mOffsetInWindow = new int[2];
- getLocationInWindow(mOffsetInWindow);
- mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero
- mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero
- int[] windowLocation = new int[2];
- getLocationOnScreen(windowLocation);
- mWindowY = windowLocation[1];
+ previewText.measure(MEASURESPEC_UNSPECIFIED, MEASURESPEC_UNSPECIFIED);
+ final int previewWidth = Math.max(previewText.getMeasuredWidth(), keyDrawWidth
+ + previewText.getPaddingLeft() + previewText.getPaddingRight());
+ final int previewHeight = params.mPreviewHeight;
+ getLocationInWindow(params.mCoordinates);
+ 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);
+ previewX = 0;
+ } else if (previewX + previewWidth > getWidth() && params.mPreviewRightBackground != null) {
+ previewText.setBackgroundDrawable(params.mPreviewRightBackground);
+ previewX = getWidth() - previewWidth;
}
+
// Set the preview background state
- mPreviewText.getBackground().setState(
+ previewText.getBackground().setState(
key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
- popupPreviewX += mOffsetInWindow[0];
- popupPreviewY += mOffsetInWindow[1];
-
- // If the popup cannot be shown above the key, put it on the side
- if (popupPreviewY + mWindowY < 0) {
- // If the key you're pressing is on the left side of the keyboard, show the popup on
- // the right, offset by enough to see at least one key to the left/right.
- if (key.mX + key.mWidth <= getWidth() / 2) {
- popupPreviewX += (int) (key.mWidth * 2.5);
- } else {
- popupPreviewX -= (int) (key.mWidth * 2.5);
- }
- popupPreviewY += popupHeight;
- }
-
- try {
- if (mPreviewPopup.isShowing()) {
- mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight);
- } else {
- mPreviewPopup.setWidth(popupWidth);
- mPreviewPopup.setHeight(popupHeight);
- mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY,
- popupPreviewX, popupPreviewY);
- }
- } catch (WindowManager.BadTokenException e) {
- // Swallow the exception which will be happened when IME is already closed.
- Log.w(TAG, "LatinIME is already closed when tried showing key preview.");
- }
- // Record popup preview position to display mini-keyboard later at the same positon
- mPopupPreviewDisplayedY = popupPreviewY;
- mPreviewText.setVisibility(VISIBLE);
+ previewText.setTextColor(params.mPreviewTextColor);
+ FrameLayoutCompatUtils.placeViewAt(
+ previewText, previewX, previewY, previewWidth, previewHeight);
+ previewText.setVisibility(VISIBLE);
}
/**
@@ -1043,321 +891,19 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
if (key == null)
return;
mInvalidatedKey = key;
- mInvalidatedKeyRect.set(0, 0, key.mWidth, key.mHeight);
- mInvalidatedKeyRect.offset(key.mX + getPaddingLeft(), key.mY + getPaddingTop());
+ final int x = key.mX + getPaddingLeft();
+ final int y = key.mY + getPaddingTop();
+ mInvalidatedKeyRect.set(x, y, x + key.mWidth, y + key.mHeight);
mDirtyRect.union(mInvalidatedKeyRect);
onBufferDraw();
invalidate(mInvalidatedKeyRect);
}
- private boolean openPopupIfRequired(int keyIndex, PointerTracker tracker) {
- // Check if we have a popup layout specified first.
- if (mPopupLayout == 0) {
- return false;
- }
-
- Key popupKey = tracker.getKey(keyIndex);
- if (popupKey == null)
- return false;
- boolean result = onLongPress(popupKey, tracker);
- if (result) {
- dismissKeyPreview();
- mMiniKeyboardTrackerId = tracker.mPointerId;
- // Mark this tracker "already processed" and remove it from the pointer queue
- tracker.setAlreadyProcessed();
- mPointerQueue.remove(tracker);
- }
- return result;
- }
-
- private void onLongPressShiftKey(PointerTracker tracker) {
- tracker.setAlreadyProcessed();
- mPointerQueue.remove(tracker);
- mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
- }
-
- private void onDoubleTapShiftKey(PointerTracker tracker) {
- // 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 mPointerQueueueue.
- mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
- }
-
- private View inflateMiniKeyboardContainer(Key popupKey) {
- final View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null);
- if (container == null)
- throw new NullPointerException();
-
- final KeyboardView miniKeyboardView =
- (KeyboardView)container.findViewById(R.id.KeyboardView);
- miniKeyboardView.setOnKeyboardActionListener(new KeyboardActionListener() {
- @Override
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
- mKeyboardActionListener.onCodeInput(primaryCode, keyCodes, x, y);
- dismissPopupKeyboard();
- }
-
- @Override
- public void onTextInput(CharSequence text) {
- mKeyboardActionListener.onTextInput(text);
- dismissPopupKeyboard();
- }
-
- @Override
- public void onCancelInput() {
- mKeyboardActionListener.onCancelInput();
- dismissPopupKeyboard();
- }
-
- @Override
- public void onSwipeDown() {
- // Nothing to do.
- }
- @Override
- public void onPress(int primaryCode, boolean withSliding) {
- mKeyboardActionListener.onPress(primaryCode, withSliding);
- }
- @Override
- public void onRelease(int primaryCode, boolean withSliding) {
- mKeyboardActionListener.onRelease(primaryCode, withSliding);
- }
- });
- // Override default ProximityKeyDetector.
- miniKeyboardView.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance);
- // Remove gesture detector on mini-keyboard
- miniKeyboardView.mGestureDetector = null;
-
- final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(),
- popupKey, mKeyboard).build();
- miniKeyboardView.setKeyboard(keyboard);
- miniKeyboardView.mMiniKeyboardParent = this;
-
- container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
- MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
-
- return container;
- }
-
- /**
- * Called when a key is long pressed. By default this will open any popup keyboard associated
- * with this key through the attributes popupLayout and popupCharacters.
- * @param popupKey the key that was long pressed
- * @return true if the long press is handled, false otherwise. Subclasses should call the
- * method on the base class if the subclass doesn't wish to handle the call.
- */
- protected boolean onLongPress(Key popupKey, PointerTracker tracker) {
- if (popupKey.mPopupCharacters == null)
- return false;
-
- View container = mMiniKeyboardCache.get(popupKey);
- if (container == null) {
- container = inflateMiniKeyboardContainer(popupKey);
- mMiniKeyboardCache.put(popupKey, container);
- }
- mMiniKeyboardView = (KeyboardView)container.findViewById(R.id.KeyboardView);
- final MiniKeyboard miniKeyboard = (MiniKeyboard)mMiniKeyboardView.getKeyboard();
-
- if (mWindowOffset == null) {
- mWindowOffset = new int[2];
- getLocationInWindow(mWindowOffset);
- }
- final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX()
- : popupKey.mX + popupKey.mWidth / 2;
- final int keyboardLeft = pointX - miniKeyboard.getDefaultCoordX() + getPaddingLeft();
- final int popupX = Math.max(0, Math.min(keyboardLeft,
- mMiniKeyboardParent.getWidth() - miniKeyboard.getMinWidth()))
- - container.getPaddingLeft() + mWindowOffset[0];
- final int popupY = popupKey.mY - mKeyboard.getVerticalGap() + getPaddingTop()
- - (container.getMeasuredHeight() - container.getPaddingBottom()) + mWindowOffset[1];
- final int x = popupX;
- final int y = mShowPreview && miniKeyboard.isOneRowKeys()
- ? mPopupPreviewDisplayedY : popupY;
-
- mMiniKeyboardOriginX = x + container.getPaddingLeft() - mWindowOffset[0];
- mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1];
- mMiniKeyboardView.setPopupOffset(x, y);
- if (miniKeyboard.setShifted(
- mKeyboard == null ? false : mKeyboard.isShiftedOrShiftLocked())) {
- mMiniKeyboardView.invalidateAllKeys();
- }
- // Mini keyboard needs no pop-up key preview displayed.
- mMiniKeyboardView.setPreviewEnabled(false);
- mMiniKeyboardPopup.setContentView(container);
- mMiniKeyboardPopup.setWidth(container.getMeasuredWidth());
- mMiniKeyboardPopup.setHeight(container.getMeasuredHeight());
- mMiniKeyboardPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y);
-
- // Inject down event on the key to mini keyboard.
- final long eventTime = SystemClock.uptimeMillis();
- mMiniKeyboardPopupTime = eventTime;
- final MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN,
- pointX, popupKey.mY + popupKey.mHeight / 2, eventTime);
- mMiniKeyboardView.onTouchEvent(downEvent);
- downEvent.recycle();
-
- invalidateAllKeys();
- return true;
- }
-
- private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) {
- return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action,
- x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0);
- }
-
- private PointerTracker getPointerTracker(final int id) {
- final ArrayList<PointerTracker> pointers = mPointerTrackers;
- final Key[] keys = mKeys;
- final KeyboardActionListener listener = mKeyboardActionListener;
-
- // Create pointer trackers until we can get 'id+1'-th tracker, if needed.
- for (int i = pointers.size(); i <= id; i++) {
- final PointerTracker tracker =
- new PointerTracker(i, mHandler, mKeyDetector, this, getResources());
- if (keys != null)
- tracker.setKeyboard(mKeyboard, keys, mKeyHysteresisDistance);
- if (listener != null)
- tracker.setOnKeyboardActionListener(listener);
- pointers.add(tracker);
- }
-
- return pointers.get(id);
- }
-
- public boolean isInSlidingKeyInput() {
- if (mMiniKeyboardView != null) {
- return mMiniKeyboardView.isInSlidingKeyInput();
- } else {
- return mPointerQueue.isInSlidingKeyInput();
- }
- }
-
- public int getPointerCount() {
- return mOldPointerCount;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent me) {
- final int action = me.getActionMasked();
- final int pointerCount = me.getPointerCount();
- final int oldPointerCount = mOldPointerCount;
- mOldPointerCount = pointerCount;
-
- // TODO: cleanup this code into a multi-touch to single-touch event converter class?
- // If the device does not have distinct multi-touch support panel, ignore all multi-touch
- // events except a transition from/to single-touch.
- if ((!mHasDistinctMultitouch || mIsAccessibilityEnabled)
- && pointerCount > 1 && oldPointerCount > 1) {
- return true;
- }
-
- // Track the last few movements to look for spurious swipes.
- mSwipeTracker.addMovement(me);
-
- // Gesture detector must be enabled only when mini-keyboard is not on the screen and
- // accessibility is not enabled.
- // TODO: Reconcile gesture detection and accessibility features.
- if (mMiniKeyboardView == null && !mIsAccessibilityEnabled
- && mGestureDetector != null && mGestureDetector.onTouchEvent(me)) {
- dismissKeyPreview();
- mHandler.cancelKeyTimers();
- return true;
- }
-
- final long eventTime = me.getEventTime();
- final int index = me.getActionIndex();
- final int id = me.getPointerId(index);
- final int x = (int)me.getX(index);
- final int y = (int)me.getY(index);
-
- // Needs to be called after the gesture detector gets a turn, as it may have
- // displayed the mini keyboard
- if (mMiniKeyboardView != null) {
- final int miniKeyboardPointerIndex = me.findPointerIndex(mMiniKeyboardTrackerId);
- if (miniKeyboardPointerIndex >= 0 && miniKeyboardPointerIndex < pointerCount) {
- final int miniKeyboardX = (int)me.getX(miniKeyboardPointerIndex);
- final int miniKeyboardY = (int)me.getY(miniKeyboardPointerIndex);
- MotionEvent translated = generateMiniKeyboardMotionEvent(action,
- miniKeyboardX, miniKeyboardY, eventTime);
- mMiniKeyboardView.onTouchEvent(translated);
- translated.recycle();
- }
- return true;
- }
-
- if (mHandler.isInKeyRepeat()) {
- // It will keep being in the key repeating mode while the key is being pressed.
- if (action == MotionEvent.ACTION_MOVE) {
- return true;
- }
- final PointerTracker tracker = getPointerTracker(id);
- // 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()) {
- mHandler.cancelKeyRepeatTimer();
- }
- // Up event will pass through.
- }
-
- // TODO: cleanup this code into a multi-touch to single-touch event converter class?
- // Translate mutli-touch event to single-touch events on the device that has no distinct
- // multi-touch panel.
- if (!mHasDistinctMultitouch || mIsAccessibilityEnabled) {
- // Use only main (id=0) pointer tracker.
- PointerTracker tracker = getPointerTracker(0);
- if (pointerCount == 1 && oldPointerCount == 2) {
- // Multi-touch to single touch transition.
- // Send a down event for the latest pointer.
- tracker.onDownEvent(x, y, eventTime, null);
- } else if (pointerCount == 2 && oldPointerCount == 1) {
- // Single-touch to multi-touch transition.
- // Send an up event for the last pointer.
- tracker.onUpEvent(tracker.getLastX(), tracker.getLastY(), eventTime, null);
- } else if (pointerCount == 1 && oldPointerCount == 1) {
- tracker.onTouchEvent(action, x, y, eventTime, null);
- } else {
- Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
- + " (old " + oldPointerCount + ")");
- }
- return true;
- }
-
- final PointerTrackerQueue queue = mPointerQueue;
- if (action == MotionEvent.ACTION_MOVE) {
- for (int i = 0; i < pointerCount; i++) {
- final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
- tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime, queue);
- }
- } else {
- final PointerTracker tracker = getPointerTracker(id);
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_POINTER_DOWN:
- tracker.onDownEvent(x, y, eventTime, queue);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_POINTER_UP:
- tracker.onUpEvent(x, y, eventTime, queue);
- break;
- case MotionEvent.ACTION_CANCEL:
- tracker.onCancelEvent(x, y, eventTime, queue);
- break;
- }
- }
-
- return true;
- }
-
- protected void onSwipeDown() {
- mKeyboardActionListener.onSwipeDown();
- }
-
public void closing() {
- mPreviewPopup.dismiss();
- mHandler.cancelAllMessages();
+ mPreviewText.setVisibility(View.GONE);
+ cancelAllMessages();
- dismissPopupKeyboard();
mDirtyRect.union(0, 0, getWidth(), getHeight());
- mMiniKeyboardCache.clear();
requestLayout();
}
@@ -1371,22 +917,4 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
super.onDetachedFromWindow();
closing();
}
-
- private void dismissPopupKeyboard() {
- if (mMiniKeyboardPopup.isShowing()) {
- mMiniKeyboardPopup.dismiss();
- mMiniKeyboardView = null;
- mMiniKeyboardOriginX = 0;
- mMiniKeyboardOriginY = 0;
- invalidateAllKeys();
- }
- }
-
- public boolean handleBack() {
- if (mMiniKeyboardPopup.isShowing()) {
- dismissPopupKeyboard();
- return true;
- }
- return false;
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 5820049bb..d925b8c33 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -16,9 +16,6 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
-
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -32,42 +29,60 @@ 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.keyboard.internal.SlidingLocaleDrawable;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import java.lang.ref.SoftReference;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
// TODO: We should remove this class
public class LatinKeyboard extends Keyboard {
- public static final int OPACITY_FULLY_OPAQUE = 255;
private static final int SPACE_LED_LENGTH_PERCENT = 80;
- private final Context mContext;
+ public static final int CODE_NEXT_LANGUAGE = -100;
+ public static final int CODE_PREV_LANGUAGE = -101;
+
+ 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 Drawable mSpacePreviewIcon;
- private final int[] mSpaceKeyIndexArray;
- private final Drawable mSpaceAutoCorrectionIndicator;
- private final Drawable mButtonArrowLeftIcon;
- private final Drawable mButtonArrowRightIcon;
+ private final int mSpaceKeyIndex;
+ private final boolean mAutoCorrectionSpacebarLedEnabled;
+ private final Drawable mAutoCorrectionSpacebarLedIcon;
private final int mSpacebarTextColor;
private final int mSpacebarTextShadowColor;
- private final int mSpacebarVerticalCorrection;
private float mSpacebarTextFadeFactor = 0.0f;
- private int mSpaceDragStartX;
- private int mSpaceDragLastDiff;
- private boolean mCurrentlyInSpace;
- private SlidingLocaleDrawable mSlidingLocaleIcon;
+ private final int mSpacebarLanguageSwitchThreshold;
+ private int mSpacebarSlidingLanguageSwitchDiff;
+ private final SlidingLocaleDrawable mSlidingLocaleIcon;
+ private final HashMap<Integer, SoftReference<BitmapDrawable>> mSpaceDrawableCache =
+ new HashMap<Integer, SoftReference<BitmapDrawable>>();
/* Shortcut key and its icons if available */
private final Key mShortcutKey;
private final Drawable mEnabledShortcutIcon;
private final Drawable mDisabledShortcutIcon;
- private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
- // Minimum width of space key preview (proportional to keyboard width)
- private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f;
+ // BLACK LEFT-POINTING TRIANGLE and two spaces.
+ public static final String ARROW_LEFT = "\u25C0 ";
+ // Two spaces and BLACK RIGHT-POINTING TRIANGLE.
+ public static final String ARROW_RIGHT = " \u25B6";
+
+ // Minimum width of spacebar dragging to trigger the language switch (represented by the number
+ // of the most common key width of this keyboard).
+ private static final int SPACEBAR_DRAG_WIDTH = 3;
+ // Minimum width of space key preview (proportional to keyboard width).
+ private static final float SPACEBAR_POPUP_MIN_RATIO = 0.5f;
// 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,
@@ -77,10 +92,10 @@ public class LatinKeyboard extends Keyboard {
private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small";
private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium";
- public LatinKeyboard(Context context, KeyboardId id) {
- super(context, id.getXmlId(), id);
- final Resources res = context.getResources();
- mContext = context;
+ public LatinKeyboard(Context context, KeyboardId id, int width) {
+ super(context, id.getXmlId(), id, width);
+ mRes = context.getResources();
+ mTheme = context.getTheme();
final List<Key> keys = getKeys();
int spaceKeyIndex = -1;
@@ -92,7 +107,7 @@ public class LatinKeyboard extends Keyboard {
case CODE_SPACE:
spaceKeyIndex = index;
break;
- case CODE_VOICE:
+ case CODE_SHORTCUT:
shortcutKeyIndex = index;
break;
}
@@ -102,26 +117,36 @@ public class LatinKeyboard extends Keyboard {
mSpaceKey = (spaceKeyIndex >= 0) ? keys.get(spaceKeyIndex) : null;
mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null;
mSpacePreviewIcon = (mSpaceKey != null) ? mSpaceKey.getPreviewIcon() : null;
- mSpaceKeyIndexArray = new int[] { spaceKeyIndex };
+ mSpaceKeyIndex = spaceKeyIndex;
mShortcutKey = (shortcutKeyIndex >= 0) ? keys.get(shortcutKeyIndex) : null;
mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null;
- mSpacebarTextColor = res.getColor(R.color.latinkeyboard_bar_language_text);
- if (id.mColorScheme == KeyboardView.COLOR_SCHEME_BLACK) {
- mSpacebarTextShadowColor = res.getColor(
- R.color.latinkeyboard_bar_language_shadow_black);
- mDisabledShortcutIcon = res.getDrawable(R.drawable.sym_bkeyboard_voice_off);
- } else { // default color scheme is KeyboardView.COLOR_SCHEME_WHITE
- mSpacebarTextShadowColor = res.getColor(
- R.color.latinkeyboard_bar_language_shadow_white);
- mDisabledShortcutIcon = res.getDrawable(R.drawable.sym_keyboard_voice_off_holo);
+ 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();
+
+ // The threshold is "key width" x 1.25
+ mSpacebarLanguageSwitchThreshold = (getMostCommonKeyWidth() * 5) / 4;
+
+ if (mSpaceKey != null && mSpacePreviewIcon != null) {
+ final int slidingIconWidth = Math.max(mSpaceKey.mWidth,
+ (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO));
+ final int spaceKeyheight = mSpacePreviewIcon.getIntrinsicHeight();
+ mSlidingLocaleIcon = new SlidingLocaleDrawable(
+ context, mSpacePreviewIcon, slidingIconWidth, spaceKeyheight);
+ mSlidingLocaleIcon.setBounds(0, 0, slidingIconWidth, spaceKeyheight);
+ } else {
+ mSlidingLocaleIcon = null;
}
- mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led);
- mButtonArrowLeftIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_left);
- mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right);
- mSpacebarVerticalCorrection = res.getDimensionPixelOffset(
- R.dimen.spacebar_vertical_correction);
}
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) {
@@ -140,12 +165,16 @@ public class LatinKeyboard extends Keyboard {
public void updateShortcutKey(boolean available, LatinKeyboardView view) {
if (mShortcutKey == null)
return;
- mShortcutKey.mEnabled = available;
+ 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.
*/
@@ -154,22 +183,26 @@ public class LatinKeyboard extends Keyboard {
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 Resources res = mContext.getResources();
// If application locales are explicitly selected.
- if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) {
- mSpaceKey.setIcon(new BitmapDrawable(res,
- drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
+ if (mSubtypeSwitcher.needsToDisplayLanguage()) {
+ mSpaceKey.setIcon(getSpaceDrawable(
+ mSubtypeSwitcher.getInputLocale(), isAutoCorrection));
+ } else if (isAutoCorrection) {
+ mSpaceKey.setIcon(getSpaceDrawable(null, true));
} else {
- // sym_keyboard_space_led can be shared with Black and White symbol themes.
- if (isAutoCorrection) {
- mSpaceKey.setIcon(new BitmapDrawable(res,
- drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
- } else {
- mSpaceKey.setIcon(mSpaceIcon);
- }
+ mSpaceKey.setIcon(mSpaceIcon);
}
}
@@ -181,61 +214,68 @@ public class LatinKeyboard extends Keyboard {
}
// Layout local language name and left and right arrow on spacebar.
- private static String layoutSpacebar(Paint paint, Locale locale, Drawable lArrow,
- Drawable rArrow, int width, int height, float origTextSize,
- boolean allowVariableTextSize) {
- final float arrowWidth = lArrow.getIntrinsicWidth();
- final float arrowHeight = lArrow.getIntrinsicHeight();
- final float maxTextWidth = width - (arrowWidth + arrowWidth);
+ 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 = SubtypeSwitcher.getFullDisplayName(locale, true);
+ String language = ARROW_LEFT + SubtypeSwitcher.getFullDisplayName(locale, true)
+ + ARROW_RIGHT;
int textWidth = getTextWidth(paint, language, origTextSize, bounds);
// Assuming text width and text size are proportional to each other.
- float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
+ 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 (allowVariableTextSize) {
- textWidth = getTextWidth(paint, language, textSize, bounds);
- // If text size goes too small or text does not fit, use short name
- useShortName = textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME
- || textWidth > maxTextWidth;
+ if (useMiddleName) {
+ language = ARROW_LEFT + SubtypeSwitcher.getMiddleDisplayLanguage(locale) + ARROW_RIGHT;
+ 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 = textWidth > maxTextWidth;
- textSize = origTextSize;
+ useShortName = false;
}
+
if (useShortName) {
- language = SubtypeSwitcher.getShortDisplayLanguage(locale);
+ language = ARROW_LEFT + SubtypeSwitcher.getShortDisplayLanguage(locale) + ARROW_RIGHT;
textWidth = getTextWidth(paint, language, origTextSize, bounds);
- textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
+ textSize = origTextSize * Math.min(width / textWidth, 1.0f);
}
paint.setTextSize(textSize);
- // Place left and right arrow just before and after language text.
- final float baseline = height * SPACEBAR_LANGUAGE_BASELINE;
- final int top = (int)(baseline - arrowHeight);
- final float remains = (width - textWidth) / 2;
- lArrow.setBounds((int)(remains - arrowWidth), top, (int)remains, (int)baseline);
- rArrow.setBounds((int)(remains + textWidth), top, (int)(remains + textWidth + arrowWidth),
- (int)baseline);
-
return language;
}
- private Bitmap drawSpacebar(int opacity, boolean isAutoCorrection) {
+ private BitmapDrawable getSpaceDrawable(Locale locale, boolean isAutoCorrection) {
+ final Integer hashCode = Arrays.hashCode(
+ new Object[] { locale, isAutoCorrection, mSpacebarTextFadeFactor });
+ final SoftReference<BitmapDrawable> ref = mSpaceDrawableCache.get(hashCode);
+ BitmapDrawable drawable = (ref == null) ? null : ref.get();
+ if (drawable == null) {
+ drawable = new BitmapDrawable(mRes, drawSpacebar(
+ locale, isAutoCorrection, mSpacebarTextFadeFactor));
+ mSpaceDrawableCache.put(hashCode, new SoftReference<BitmapDrawable>(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 = mContext.getResources();
- canvas.drawColor(res.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR);
+ final Resources res = mRes;
+ canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
- SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance();
// If application locales are explicitly selected.
- if (subtypeSwitcher.needsToDisplayLanguage()) {
+ if (inputLocale != null) {
final Paint paint = new Paint();
- paint.setAlpha(opacity);
paint.setAntiAlias(true);
paint.setTextAlign(Align.CENTER);
@@ -252,11 +292,8 @@ public class LatinKeyboard extends Keyboard {
defaultTextSize = 14;
}
- final boolean allowVariableTextSize = true;
- final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(),
- mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
- getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize),
- allowVariableTextSize);
+ 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
@@ -265,27 +302,20 @@ public class LatinKeyboard extends Keyboard {
final float textHeight = -paint.ascent() + descent;
final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE
: height / 2 + textHeight / 2;
- paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor));
+ paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor));
canvas.drawText(language, width / 2, baseline - descent - 1, paint);
- paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor));
+ paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor));
canvas.drawText(language, width / 2, baseline - descent, paint);
-
- // Put arrows that are already layed out on either side of the text
- if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
- && subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
- mButtonArrowLeftIcon.draw(canvas);
- mButtonArrowRightIcon.draw(canvas);
- }
}
// Draw the spacebar icon at the bottom
if (isAutoCorrection) {
final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100;
- final int iconHeight = mSpaceAutoCorrectionIndicator.getIntrinsicHeight();
+ final int iconHeight = mAutoCorrectionSpacebarLedIcon.getIntrinsicHeight();
int x = (width - iconWidth) / 2;
int y = height - iconHeight;
- mSpaceAutoCorrectionIndicator.setBounds(x, y, x + iconWidth, y + iconHeight);
- mSpaceAutoCorrectionIndicator.draw(canvas);
+ 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();
@@ -297,16 +327,16 @@ public class LatinKeyboard extends Keyboard {
return buffer;
}
- private void updateLocaleDrag(int diff) {
- if (mSlidingLocaleIcon == null) {
- final int width = Math.max(mSpaceKey.mWidth,
- (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO));
- final int height = mSpacePreviewIcon.getIntrinsicHeight();
- mSlidingLocaleIcon =
- new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height);
- mSlidingLocaleIcon.setBounds(0, 0, width, height);
- mSpaceKey.setPreviewIcon(mSlidingLocaleIcon);
- }
+ public void setSpacebarSlidingLanguageSwitchDiff(int diff) {
+ mSpacebarSlidingLanguageSwitchDiff = diff;
+ }
+
+ public void updateSpacebarPreviewIcon(int diff) {
+ if (mSpacebarSlidingLanguageSwitchDiff == diff)
+ return;
+ mSpacebarSlidingLanguageSwitchDiff = diff;
+ if (mSlidingLocaleIcon == null)
+ return;
mSlidingLocaleIcon.setDiff(diff);
if (Math.abs(diff) == Integer.MAX_VALUE) {
mSpaceKey.setPreviewIcon(mSpacePreviewIcon);
@@ -316,72 +346,52 @@ public class LatinKeyboard extends Keyboard {
mSpaceKey.getPreviewIcon().invalidateSelf();
}
- public int getLanguageChangeDirection() {
- if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1
- || Math.abs(mSpaceDragLastDiff) < mSpaceKey.mWidth * SPACEBAR_DRAG_THRESHOLD) {
- return 0; // No change
- }
- return mSpaceDragLastDiff > 0 ? 1 : -1;
- }
-
- public void keyReleased() {
- mCurrentlyInSpace = false;
- mSpaceDragLastDiff = 0;
- if (mSpaceKey != null) {
- updateLocaleDrag(Integer.MAX_VALUE);
- }
+ public boolean shouldTriggerSpacebarSlidingLanguageSwitch(int diff) {
+ // On phone and number layouts, sliding language switch is disabled.
+ // TODO: Sort out how to enable language switch on these layouts.
+ if (isPhoneKeyboard() || isNumberKeyboard())
+ return false;
+ return Math.abs(diff) > mSpacebarLanguageSwitchThreshold;
}
/**
- * Does the magic of locking the touch gesture into the spacebar when
- * switching input languages.
+ * Return true if spacebar needs showing preview even when "popup on keypress" is off.
+ * @param keyIndex index of the pressing key
+ * @return true if spacebar needs showing preview
*/
@Override
- public boolean isInside(Key key, int pointX, int pointY) {
- int x = pointX;
- int y = pointY;
- final int code = key.mCode;
- if (code == CODE_SPACE) {
- y += mSpacebarVerticalCorrection;
- if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
- && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) {
- if (mCurrentlyInSpace) {
- int diff = x - mSpaceDragStartX;
- if (Math.abs(diff - mSpaceDragLastDiff) > 0) {
- updateLocaleDrag(diff);
- }
- mSpaceDragLastDiff = diff;
- return true;
- } else {
- boolean isOnSpace = key.isOnKey(x, y);
- if (isOnSpace) {
- mCurrentlyInSpace = true;
- mSpaceDragStartX = x;
- updateLocaleDrag(0);
- }
- return isOnSpace;
- }
- }
- }
-
- // Lock into the spacebar
- if (mCurrentlyInSpace) return false;
+ public boolean needSpacebarPreview(int keyIndex) {
+ // This method is called when "popup on keypress" is off.
+ if (!mSubtypeSwitcher.useSpacebarLanguageSwitcher())
+ return false;
+ // Dismiss key preview.
+ if (keyIndex == KeyDetector.NOT_A_KEY)
+ return true;
+ // Key is not a spacebar.
+ if (keyIndex != mSpaceKeyIndex)
+ return false;
+ // The language switcher will be displayed only when the dragging distance is greater
+ // than the threshold.
+ return shouldTriggerSpacebarSlidingLanguageSwitch(mSpacebarSlidingLanguageSwitchDiff);
+ }
- return key.isOnKey(x, y);
+ public int getLanguageChangeDirection() {
+ if (mSpaceKey == null || mSubtypeSwitcher.getEnabledKeyboardLocaleCount() <= 1
+ || Math.abs(mSpacebarSlidingLanguageSwitchDiff)
+ < getMostCommonKeyWidth() * SPACEBAR_DRAG_WIDTH) {
+ return 0; // No change
+ }
+ return mSpacebarSlidingLanguageSwitchDiff > 0 ? 1 : -1;
}
@Override
public int[] getNearestKeys(int x, int y) {
- if (mCurrentlyInSpace) {
- return mSpaceKeyIndexArray;
- } else {
- // Avoid dead pixels at edges of the keyboard
- return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)),
- Math.max(0, Math.min(y, getHeight() - 1)));
- }
+ // Avoid dead pixels at edges of the keyboard
+ return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)),
+ Math.max(0, Math.min(y, getHeight() - 1)));
}
- private static int getTextSizeFromTheme(Theme theme, int style, int defValue) {
+ public static int getTextSizeFromTheme(Theme theme, int style, int defValue) {
TypedArray array = theme.obtainStyledAttributes(
style, new int[] { android.R.attr.textSize });
int textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue);
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
new file mode 100644
index 000000000..b807dd325
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
@@ -0,0 +1,621 @@
+/*
+ * 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.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.PopupWindow;
+
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
+import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+
+import java.util.WeakHashMap;
+
+/**
+ * A view that is responsible for detecting key presses and touch movements.
+ *
+ * @attr ref R.styleable#KeyboardView_keyHysteresisDistance
+ * @attr ref R.styleable#KeyboardView_verticalCorrection
+ * @attr ref R.styleable#KeyboardView_popupLayout
+ */
+public class LatinKeyboardBaseView extends KeyboardView implements PointerTracker.KeyEventHandler {
+ private static final String TAG = LatinKeyboardBaseView.class.getSimpleName();
+
+ private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = true;
+ private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
+
+ // Timing constants
+ private final int mKeyRepeatInterval;
+
+ // XML attribute
+ private final float mVerticalCorrection;
+ private final int mPopupLayout;
+
+ // Mini keyboard
+ private PopupWindow mPopupWindow;
+ private PopupPanel mPopupPanel;
+ private int mPopupPanelPointerTrackerId;
+ private final WeakHashMap<Key, PopupPanel> mPopupPanelCache =
+ new WeakHashMap<Key, PopupPanel>();
+
+ /** Listener for {@link KeyboardActionListener}. */
+ private KeyboardActionListener mKeyboardActionListener;
+
+ private final boolean mHasDistinctMultitouch;
+ private int mOldPointerCount = 1;
+ private int mOldKeyIndex;
+
+ protected KeyDetector mKeyDetector;
+
+ // To detect double tap.
+ protected GestureDetector mGestureDetector;
+
+ private final KeyTimerHandler mKeyTimerHandler = new KeyTimerHandler(this);
+
+ private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardBaseView>
+ implements TimerProxy {
+ private static final int MSG_REPEAT_KEY = 1;
+ private static final int MSG_LONGPRESS_KEY = 2;
+ private static final int MSG_LONGPRESS_SHIFT_KEY = 3;
+ private static final int MSG_IGNORE_DOUBLE_TAP = 4;
+
+ private boolean mInKeyRepeat;
+
+ public KeyTimerHandler(LatinKeyboardBaseView outerInstance) {
+ super(outerInstance);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ final LatinKeyboardBaseView keyboardView = getOuterInstance();
+ final PointerTracker tracker = (PointerTracker) msg.obj;
+ switch (msg.what) {
+ case MSG_REPEAT_KEY:
+ tracker.onRepeatKey(msg.arg1);
+ startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, msg.arg1, tracker);
+ break;
+ case MSG_LONGPRESS_KEY:
+ keyboardView.openMiniKeyboardIfRequired(msg.arg1, tracker);
+ break;
+ case MSG_LONGPRESS_SHIFT_KEY:
+ keyboardView.onLongPressShiftKey(tracker);
+ break;
+ }
+ }
+
+ @Override
+ public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
+ mInKeyRepeat = true;
+ sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
+ }
+
+ public void cancelKeyRepeatTimer() {
+ mInKeyRepeat = false;
+ removeMessages(MSG_REPEAT_KEY);
+ }
+
+ public boolean isInKeyRepeat() {
+ return mInKeyRepeat;
+ }
+
+ @Override
+ public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
+ cancelLongPressTimers();
+ sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
+ }
+
+ @Override
+ public void startLongPressShiftTimer(long delay, int keyIndex, PointerTracker tracker) {
+ cancelLongPressTimers();
+ if (ENABLE_CAPSLOCK_BY_LONGPRESS) {
+ sendMessageDelayed(
+ obtainMessage(MSG_LONGPRESS_SHIFT_KEY, keyIndex, 0, tracker), delay);
+ }
+ }
+
+ @Override
+ public void cancelLongPressTimers() {
+ removeMessages(MSG_LONGPRESS_KEY);
+ removeMessages(MSG_LONGPRESS_SHIFT_KEY);
+ }
+
+ @Override
+ public void cancelKeyTimers() {
+ cancelKeyRepeatTimer();
+ cancelLongPressTimers();
+ removeMessages(MSG_IGNORE_DOUBLE_TAP);
+ }
+
+ public void startIgnoringDoubleTap() {
+ sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
+ ViewConfiguration.getDoubleTapTimeout());
+ }
+
+ public boolean isIgnoringDoubleTap() {
+ return hasMessages(MSG_IGNORE_DOUBLE_TAP);
+ }
+
+ public void cancelAllMessages() {
+ cancelKeyTimers();
+ }
+ }
+
+ private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
+ private boolean mProcessingShiftDoubleTapEvent = false;
+
+ @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;
+ }
+
+ @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} .
+ final boolean ignoringDoubleTap = mKeyTimerHandler.isIgnoringDoubleTap();
+ if (!ignoringDoubleTap)
+ onDoubleTapShiftKey(tracker);
+ return true;
+ }
+ // Otherwise these events should not be handled as double tap.
+ mProcessingShiftDoubleTapEvent = false;
+ }
+ return mProcessingShiftDoubleTapEvent;
+ }
+ }
+
+ public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.keyboardViewStyle);
+ }
+
+ public LatinKeyboardBaseView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+ mVerticalCorrection = a.getDimensionPixelOffset(
+ R.styleable.KeyboardView_verticalCorrection, 0);
+ mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0);
+ a.recycle();
+
+ final Resources res = getResources();
+ 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());
+ }
+
+ public void startIgnoringDoubleTap() {
+ if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
+ mKeyTimerHandler.startIgnoringDoubleTap();
+ }
+
+ public void setKeyboardActionListener(KeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ PointerTracker.setKeyboardActionListener(listener);
+ }
+
+ /**
+ * Returns the {@link KeyboardActionListener} object.
+ * @return the listener attached to this keyboard
+ */
+ @Override
+ public KeyboardActionListener getKeyboardActionListener() {
+ return mKeyboardActionListener;
+ }
+
+ @Override
+ public KeyDetector getKeyDetector() {
+ return mKeyDetector;
+ }
+
+ @Override
+ public DrawingProxy getDrawingProxy() {
+ return this;
+ }
+
+ @Override
+ public TimerProxy getTimerProxy() {
+ return mKeyTimerHandler;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ // TODO: Should notify InputMethodService instead?
+ KeyboardSwitcher.getInstance().onSizeChanged();
+ }
+
+ /**
+ * 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.
+ * @see Keyboard
+ * @see #getKeyboard()
+ * @param keyboard the keyboard to display in this view
+ */
+ @Override
+ public void setKeyboard(Keyboard keyboard) {
+ if (getKeyboard() != null) {
+ PointerTracker.dismissAllKeyPreviews();
+ }
+ // Remove any pending messages, except dismissing preview
+ mKeyTimerHandler.cancelKeyTimers();
+ super.setKeyboard(keyboard);
+ mKeyDetector.setKeyboard(
+ keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
+ mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
+ PointerTracker.setKeyDetector(mKeyDetector);
+ mPopupPanelCache.clear();
+ }
+
+ /**
+ * Returns whether the device has distinct multi-touch panel.
+ * @return true if the device has distinct multi-touch panel.
+ */
+ public boolean hasDistinctMultitouch() {
+ return mHasDistinctMultitouch;
+ }
+
+ /**
+ * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
+ * codes for adjacent keys. When disabled, only the primary key code will be
+ * reported.
+ * @param enabled whether or not the proximity correction is enabled
+ */
+ public void setProximityCorrectionEnabled(boolean enabled) {
+ mKeyDetector.setProximityCorrectionEnabled(enabled);
+ }
+
+ /**
+ * Returns true if proximity correction is enabled.
+ */
+ public boolean isProximityCorrectionEnabled() {
+ return mKeyDetector.isProximityCorrectionEnabled();
+ }
+
+ @Override
+ public void cancelAllMessages() {
+ mKeyTimerHandler.cancelAllMessages();
+ super.cancelAllMessages();
+ }
+
+ private boolean openMiniKeyboardIfRequired(int keyIndex, PointerTracker tracker) {
+ // Check if we have a popup layout specified first.
+ if (mPopupLayout == 0) {
+ return false;
+ }
+
+ // Check if we are already displaying popup panel.
+ if (mPopupPanel != null)
+ return false;
+ final Key parentKey = tracker.getKey(keyIndex);
+ if (parentKey == null)
+ return false;
+ return onLongPress(parentKey, tracker);
+ }
+
+ private void onLongPressShiftKey(PointerTracker tracker) {
+ tracker.onLongPressed();
+ mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
+ }
+
+ private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) {
+ // 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.
+ mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
+ }
+
+ // This default implementation returns a popup mini keyboard panel.
+ // A derived class may return a language switcher popup panel, for instance.
+ protected PopupPanel onCreatePopupPanel(Key parentKey) {
+ if (parentKey.mPopupCharacters == null)
+ return null;
+
+ final View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null);
+ if (container == null)
+ throw new NullPointerException();
+
+ final PopupMiniKeyboardView miniKeyboardView =
+ (PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
+ final Keyboard parentKeyboard = getKeyboard();
+ final Keyboard miniKeyboard = new MiniKeyboardBuilder(
+ this, parentKeyboard.getPopupKeyboardResId(), parentKey, parentKeyboard).build();
+ miniKeyboardView.setKeyboard(miniKeyboard);
+
+ container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+
+ return miniKeyboardView;
+ }
+
+ @Override
+ protected boolean needsToDimKeyboard() {
+ return mPopupPanel != null;
+ }
+
+ /**
+ * Called when a key is long pressed. By default this will open mini keyboard associated
+ * with this key.
+ * @param parentKey the key that was long pressed
+ * @param tracker the pointer tracker which pressed the parent key
+ * @return true if the long press is handled, false otherwise. Subclasses should call the
+ * method on the base class if the subclass doesn't wish to handle the call.
+ */
+ protected boolean onLongPress(Key parentKey, PointerTracker tracker) {
+ PopupPanel popupPanel = mPopupPanelCache.get(parentKey);
+ if (popupPanel == null) {
+ popupPanel = onCreatePopupPanel(parentKey);
+ if (popupPanel == null)
+ return false;
+ mPopupPanelCache.put(parentKey, popupPanel);
+ }
+ if (mPopupWindow == null) {
+ mPopupWindow = new PopupWindow(getContext());
+ mPopupWindow.setBackgroundDrawable(null);
+ mPopupWindow.setAnimationStyle(R.style.PopupMiniKeyboardAnimation);
+ // Allow popup window to be drawn off the screen.
+ mPopupWindow.setClippingEnabled(false);
+ }
+ mPopupPanel = popupPanel;
+ mPopupPanelPointerTrackerId = tracker.mPointerId;
+
+ tracker.onLongPressed();
+ popupPanel.showPanel(this, parentKey, tracker, mPopupWindow);
+ final int translatedX = popupPanel.translateX(tracker.getLastX());
+ final int translatedY = popupPanel.translateY(tracker.getLastY());
+ tracker.onDownEvent(translatedX, translatedY, SystemClock.uptimeMillis(), popupPanel);
+
+ invalidateAllKeys();
+ return true;
+ }
+
+ private PointerTracker getPointerTracker(final int id) {
+ return PointerTracker.getPointerTracker(id, this);
+ }
+
+ public boolean isInSlidingKeyInput() {
+ if (mPopupPanel != null) {
+ return true;
+ } else {
+ return PointerTracker.isAnyInSlidingKeyInput();
+ }
+ }
+
+ public int getPointerCount() {
+ return mOldPointerCount;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent me) {
+ final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
+ final int action = me.getActionMasked();
+ final int pointerCount = me.getPointerCount();
+ final int oldPointerCount = mOldPointerCount;
+ mOldPointerCount = pointerCount;
+
+ // TODO: cleanup this code into a multi-touch to single-touch event converter class?
+ // If the device does not have distinct multi-touch support panel, ignore all multi-touch
+ // events except a transition from/to single-touch.
+ if (nonDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
+ return true;
+ }
+
+ // Gesture detector must be enabled only when mini-keyboard is not on the screen.
+ if (mPopupPanel == 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);
+ final int x, y;
+ if (mPopupPanel != null && id == mPopupPanelPointerTrackerId) {
+ x = mPopupPanel.translateX((int)me.getX(index));
+ y = mPopupPanel.translateY((int)me.getY(index));
+ } else {
+ x = (int)me.getX(index);
+ y = (int)me.getY(index);
+ }
+
+ if (mKeyTimerHandler.isInKeyRepeat()) {
+ final PointerTracker tracker = getPointerTracker(id);
+ // 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()) {
+ mKeyTimerHandler.cancelKeyRepeatTimer();
+ }
+ // Up event will pass through.
+ }
+
+ // TODO: cleanup this code into a multi-touch to single-touch event converter class?
+ // Translate mutli-touch event to single-touch events on the device that has no distinct
+ // multi-touch panel.
+ if (nonDistinctMultitouch) {
+ // Use only main (id=0) pointer tracker.
+ PointerTracker tracker = getPointerTracker(0);
+ 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) {
+ tracker.onDownEvent(x, y, eventTime, this);
+ if (action == MotionEvent.ACTION_UP)
+ tracker.onUpEvent(x, y, eventTime);
+ }
+ } else if (pointerCount == 2 && oldPointerCount == 1) {
+ // Single-touch to multi-touch transition.
+ // Send an up event for the last pointer.
+ final int lastX = tracker.getLastX();
+ final int lastY = tracker.getLastY();
+ mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
+ tracker.onUpEvent(lastX, lastY, eventTime);
+ } else if (pointerCount == 1 && oldPointerCount == 1) {
+ processMotionEvent(tracker, action, x, y, eventTime, this);
+ } else {
+ Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
+ + " (old " + oldPointerCount + ")");
+ }
+ return true;
+ }
+
+ if (action == MotionEvent.ACTION_MOVE) {
+ for (int i = 0; i < pointerCount; i++) {
+ final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
+ final int px, py;
+ if (mPopupPanel != null && tracker.mPointerId == mPopupPanelPointerTrackerId) {
+ px = mPopupPanel.translateX((int)me.getX(i));
+ py = mPopupPanel.translateY((int)me.getY(i));
+ } else {
+ px = (int)me.getX(i);
+ py = (int)me.getY(i);
+ }
+ tracker.onMoveEvent(px, py, eventTime);
+ }
+ } else {
+ processMotionEvent(getPointerTracker(id), action, x, y, eventTime, this);
+ }
+
+ return true;
+ }
+
+ private static void processMotionEvent(PointerTracker tracker, int action, int x, int y,
+ long eventTime, PointerTracker.KeyEventHandler handler) {
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ tracker.onDownEvent(x, y, eventTime, handler);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ tracker.onUpEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ tracker.onMoveEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ tracker.onCancelEvent(x, y, eventTime);
+ break;
+ }
+ }
+
+ @Override
+ public void closing() {
+ super.closing();
+ dismissMiniKeyboard();
+ mPopupPanelCache.clear();
+ }
+
+ public boolean dismissMiniKeyboard() {
+ if (mPopupWindow != null && mPopupWindow.isShowing()) {
+ mPopupWindow.dismiss();
+ mPopupPanel = null;
+ mPopupPanelPointerTrackerId = -1;
+ invalidateAllKeys();
+ return true;
+ }
+ return false;
+ }
+
+ public boolean handleBack() {
+ return dismissMiniKeyboard();
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ return AccessibleKeyboardViewProxy.getInstance().dispatchTouchEvent(event)
+ || super.dispatchTouchEvent(event);
+ }
+
+ return super.dispatchTouchEvent(event);
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ final PointerTracker tracker = getPointerTracker(0);
+ return AccessibleKeyboardViewProxy.getInstance().dispatchPopulateAccessibilityEvent(
+ event, tracker) || super.dispatchPopulateAccessibilityEvent(event);
+ }
+
+ return super.dispatchPopulateAccessibilityEvent(event);
+ }
+
+ public boolean onHoverEvent(MotionEvent event) {
+ // Since reflection doesn't support calling superclass methods, this
+ // method checks for the existence of onHoverEvent() in the View class
+ // before returning a value.
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ final PointerTracker tracker = getPointerTracker(0);
+ return AccessibleKeyboardViewProxy.getInstance().onHoverEvent(event, tracker);
+ }
+
+ return false;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 77e9caecc..5f5475ce8 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -16,19 +16,18 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.Utils;
-import com.android.inputmethod.voice.VoiceIMEConnector;
-
import android.content.Context;
import android.graphics.Canvas;
-import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.Utils;
+
// TODO: We should remove this class
-public class LatinKeyboardView extends KeyboardView {
+public class LatinKeyboardView extends LatinKeyboardBaseView {
private static final String TAG = LatinKeyboardView.class.getSimpleName();
private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
@@ -47,7 +46,7 @@ public class LatinKeyboardView extends KeyboardView {
private int mLastY;
public LatinKeyboardView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ super(context, attrs);
}
public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
@@ -55,24 +54,19 @@ public class LatinKeyboardView extends KeyboardView {
}
@Override
- public void setPreviewEnabled(boolean previewEnabled) {
+ public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null
&& (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard())) {
// Phone and number keyboard never shows popup preview (except language switch).
- super.setPreviewEnabled(false);
+ super.setKeyPreviewPopupEnabled(false, delay);
} else {
- super.setPreviewEnabled(previewEnabled);
+ super.setKeyPreviewPopupEnabled(previewEnabled, delay);
}
}
@Override
public void setKeyboard(Keyboard newKeyboard) {
- final LatinKeyboard oldKeyboard = getLatinKeyboard();
- if (oldKeyboard != null) {
- // Reset old keyboard state before switching to new keyboard.
- oldKeyboard.keyReleased();
- }
super.setKeyboard(newKeyboard);
// One-seventh of the keyboard width seems like a reasonable threshold
mJumpThresholdSquare = newKeyboard.getMinWidth() / 7;
@@ -102,8 +96,10 @@ public class LatinKeyboardView extends KeyboardView {
protected boolean onLongPress(Key key, PointerTracker tracker) {
int primaryCode = key.mCode;
if (primaryCode == Keyboard.CODE_SETTINGS) {
+ tracker.onLongPressed();
return invokeOnKey(Keyboard.CODE_SETTINGS_LONGPRESS);
} else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) {
+ tracker.onLongPressed();
// Long pressing on 0 in phone number keypad gives you a '+'.
return invokeOnKey('+');
} else {
@@ -112,24 +108,12 @@ public class LatinKeyboardView extends KeyboardView {
}
private boolean invokeOnKey(int primaryCode) {
- getOnKeyboardActionListener().onCodeInput(primaryCode, null,
+ getKeyboardActionListener().onCodeInput(primaryCode, null,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
return true;
}
- @Override
- protected CharSequence adjustCase(CharSequence label) {
- LatinKeyboard keyboard = getLatinKeyboard();
- if (keyboard.isAlphaKeyboard()
- && keyboard.isShiftedOrShiftLocked()
- && !TextUtils.isEmpty(label) && label.length() < 3
- && Character.isLowerCase(label.charAt(0))) {
- return label.toString().toUpperCase();
- }
- return label;
- }
-
/**
* This function checks to see if we need to handle any sudden jumps in the pointer location
* that could be due to a multi-touch being treated as a move by the firmware or hardware.
@@ -145,10 +129,6 @@ public class LatinKeyboardView extends KeyboardView {
// If device has distinct multi touch panel, there is no need to check sudden jump.
if (hasDistinctMultitouch())
return false;
- // If accessibiliy is enabled, stop looking for sudden jumps because it interferes
- // with touch exploration of the keyboard.
- if (isAccessibilityEnabled())
- return false;
final int action = me.getAction();
final int x = (int) me.getX();
final int y = (int) me.getY();
@@ -182,7 +162,8 @@ public class LatinKeyboardView extends KeyboardView {
if (!mDroppingEvents) {
mDroppingEvents = true;
// Send an up event
- MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent translated = MotionEvent.obtain(
+ me.getEventTime(), me.getEventTime(),
MotionEvent.ACTION_UP,
mLastX, mLastY, me.getMetaState());
super.onTouchEvent(translated);
@@ -216,8 +197,7 @@ public class LatinKeyboardView extends KeyboardView {
@Override
public boolean onTouchEvent(MotionEvent me) {
- LatinKeyboard keyboard = getLatinKeyboard();
- if (keyboard == null) return true;
+ if (getLatinKeyboard() == null) return true;
// If there was a sudden jump, return without processing the actual motion event.
if (handleSuddenJump(me)) {
@@ -226,24 +206,6 @@ public class LatinKeyboardView extends KeyboardView {
return true;
}
- // Reset any bounding box controls in the keyboard
- if (me.getAction() == MotionEvent.ACTION_DOWN) {
- keyboard.keyReleased();
- }
-
- if (me.getAction() == MotionEvent.ACTION_UP) {
- int languageDirection = keyboard.getLanguageChangeDirection();
- if (languageDirection != 0) {
- getOnKeyboardActionListener().onCodeInput(
- languageDirection == 1
- ? Keyboard.CODE_NEXT_LANGUAGE : Keyboard.CODE_PREV_LANGUAGE,
- null, mLastX, mLastY);
- me.setAction(MotionEvent.ACTION_CANCEL);
- keyboard.keyReleased();
- return super.onTouchEvent(me);
- }
- }
-
return super.onTouchEvent(me);
}
@@ -264,6 +226,6 @@ public class LatinKeyboardView extends KeyboardView {
@Override
protected void onAttachedToWindow() {
// Token is available from here.
- VoiceIMEConnector.getInstance().onAttachedToWindow();
+ VoiceProxy.getInstance().onAttachedToWindow();
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index 8d243e0a7..44f9f195c 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -18,13 +18,22 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
-import java.util.List;
-
public class MiniKeyboard extends Keyboard {
private int mDefaultKeyCoordX;
- public MiniKeyboard(Context context, int xmlLayoutResId, KeyboardId id) {
- super(context, xmlLayoutResId, id);
+ public MiniKeyboard(Context context, int xmlLayoutResId, Keyboard parentKeyboard) {
+ super(context, xmlLayoutResId, parentKeyboard.mId.cloneAsMiniKeyboard(),
+ parentKeyboard.getMinWidth());
+ // HACK: Current mini keyboard design totally relies on the 9-patch padding about horizontal
+ // and vertical key spacing. To keep the visual of mini keyboard as is, these hacks are
+ // needed to keep having the same horizontal and vertical key spacing.
+ setHorizontalGap(0);
+ setVerticalGap(parentKeyboard.getVerticalGap() / 2);
+
+ // TODO: When we have correctly padded key background 9-patch drawables for mini keyboard,
+ // revert the above hacks and uncomment the following lines.
+ //setHorizontalGap(parentKeyboard.getHorizontalGap());
+ //setVerticalGap(parentKeyboard.getVerticalGap());
}
public void setDefaultCoordX(int pos) {
@@ -34,18 +43,4 @@ public class MiniKeyboard extends Keyboard {
public int getDefaultCoordX() {
return mDefaultKeyCoordX;
}
-
- public boolean isOneRowKeys() {
- final List<Key> keys = getKeys();
- if (keys.size() == 0) return false;
- final int edgeFlags = keys.get(0).mEdgeFlags;
- // HACK: The first key of mini keyboard which was inflated from xml and has multiple rows,
- // does not have both top and bottom edge flags on at the same time. On the other hand,
- // the first key of mini keyboard that was created with popupCharacters must have both top
- // and bottom edge flags on.
- // When you want to use one row mini-keyboard from xml file, make sure that the row has
- // both top and bottom edge flags set.
- return (edgeFlags & Keyboard.EDGE_TOP) != 0
- && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0;
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
index 1243f6f37..1ec0dda15 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
@@ -16,14 +16,14 @@
package com.android.inputmethod.keyboard;
-public class MiniKeyboardKeyDetector extends KeyDetector {
- private static final int MAX_NEARBY_KEYS = 1;
+import java.util.List;
+public class MiniKeyboardKeyDetector extends KeyDetector {
private final int mSlideAllowanceSquare;
private final int mSlideAllowanceSquareTop;
public MiniKeyboardKeyDetector(float slideAllowance) {
- super();
+ super(/* keyHysteresisDistance */0);
mSlideAllowanceSquare = (int)(slideAllowance * slideAllowance);
// Top slide allowance is slightly longer (sqrt(2) times) than other edges.
mSlideAllowanceSquareTop = mSlideAllowanceSquare * 2;
@@ -31,20 +31,21 @@ public class MiniKeyboardKeyDetector extends KeyDetector {
@Override
protected int getMaxNearbyKeys() {
- return MAX_NEARBY_KEYS;
+ // No nearby key will be returned.
+ return 1;
}
@Override
public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
- final Key[] keys = getKeys();
+ final List<Key> keys = getKeyboard().getKeys();
final int touchX = getTouchX(x);
final int touchY = getTouchY(y);
int nearestIndex = NOT_A_KEY;
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
- final int keyCount = keys.length;
+ final int keyCount = keys.size();
for (int index = 0; index < keyCount; index++) {
- final int dist = keys[index].squaredDistanceToEdge(touchX, touchY);
+ final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY);
if (dist < nearestDist) {
nearestIndex = index;
nearestDist = dist;
@@ -52,7 +53,7 @@ public class MiniKeyboardKeyDetector extends KeyDetector {
}
if (allCodes != null && nearestIndex != NOT_A_KEY)
- allCodes[0] = keys[nearestIndex].mCode;
+ allCodes[0] = keys.get(nearestIndex).mCode;
return nearestIndex;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 4b3fe8b8b..aa2f3af48 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -16,61 +16,104 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.keyboard.KeyboardView.UIHandler;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.R;
-
+import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
-import android.view.MotionEvent;
+import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
public class PointerTracker {
private static final String TAG = PointerTracker.class.getSimpleName();
- private static final boolean ENABLE_ASSERTION = false;
private static final boolean DEBUG_EVENT = false;
private static final boolean DEBUG_MOVE_EVENT = false;
private static final boolean DEBUG_LISTENER = false;
private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
- public interface UIProxy {
+ public interface KeyEventHandler {
+ /**
+ * Get KeyDetector object that is used for this PointerTracker.
+ * @return the KeyDetector object that is used for this PointerTracker
+ */
+ public KeyDetector getKeyDetector();
+
+ /**
+ * Get KeyboardActionListener object that is used to register key code and so on.
+ * @return the KeyboardActionListner for this PointerTracker
+ */
+ public KeyboardActionListener getKeyboardActionListener();
+
+ /**
+ * Get DrawingProxy object that is used for this PointerTracker.
+ * @return the DrawingProxy object that is used for this PointerTracker
+ */
+ public DrawingProxy getDrawingProxy();
+
+ /**
+ * Get TimerProxy object that handles key repeat and long press timer event for this
+ * PointerTracker.
+ * @return the TimerProxy object that handles key repeat and long press timer event.
+ */
+ public TimerProxy getTimerProxy();
+ }
+
+ public interface DrawingProxy {
public void invalidateKey(Key key);
- public void showPreview(int keyIndex, PointerTracker tracker);
- public boolean hasDistinctMultitouch();
- public boolean isAccessibilityEnabled();
+ public void showKeyPreview(int keyIndex, PointerTracker tracker);
+ public void cancelShowKeyPreview(PointerTracker tracker);
+ public void dismissKeyPreview(PointerTracker tracker);
}
- public final int mPointerId;
+ public interface TimerProxy {
+ public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker);
+ public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker);
+ public void startLongPressShiftTimer(long delay, int keyIndex, PointerTracker tracker);
+ public void cancelLongPressTimers();
+ public void cancelKeyTimers();
+ }
+ private static KeyboardSwitcher sKeyboardSwitcher;
+ private static boolean sConfigSlidingKeyInputEnabled;
// Timing constants
- private final int mDelayBeforeKeyRepeatStart;
- private final int mLongPressKeyTimeout;
- private final int mLongPressShiftKeyTimeout;
+ private static int sDelayBeforeKeyRepeatStart;
+ private static int sLongPressKeyTimeout;
+ private static int sLongPressShiftKeyTimeout;
+ private static int sTouchNoiseThresholdMillis;
+ private static int sTouchNoiseThresholdDistanceSquared;
- // Miscellaneous constants
- private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY;
+ private static final List<PointerTracker> sTrackers = new ArrayList<PointerTracker>();
+ private static PointerTrackerQueue sPointerTrackerQueue;
- private final UIProxy mProxy;
- private final UIHandler mHandler;
- private final KeyDetector mKeyDetector;
- private KeyboardActionListener mListener = EMPTY_LISTENER;
- private final KeyboardSwitcher mKeyboardSwitcher;
- private final boolean mHasDistinctMultitouch;
- private final boolean mConfigSlidingKeyInputEnabled;
+ public final int mPointerId;
- private final int mTouchNoiseThresholdMillis;
- private final int mTouchNoiseThresholdDistanceSquared;
+ private DrawingProxy mDrawingProxy;
+ private TimerProxy mTimerProxy;
+ private KeyDetector mKeyDetector;
+ private KeyboardActionListener mListener = EMPTY_LISTENER;
private Keyboard mKeyboard;
- private Key[] mKeys;
- private int mKeyHysteresisDistanceSquared = -1;
+ private List<Key> mKeys;
private int mKeyQuarterWidthSquared;
- private final PointerTrackerKeyState mKeyState;
+ // The position and time at which first down event occurred.
+ 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.
+ private int mKeyX;
+ private int mKeyY;
- // true if accessibility is enabled in the parent keyboard
- private boolean mIsAccessibilityEnabled;
+ // Last pointer position.
+ private int mLastX;
+ private int mLastY;
// true if keyboard layout has been changed.
private boolean mKeyboardLayoutHasBeenChanged;
@@ -82,13 +125,19 @@ public class PointerTracker {
private boolean mIsRepeatableKey;
// true if this pointer is in sliding key input
- private boolean mIsInSlidingKeyInput;
+ boolean mIsInSlidingKeyInput;
// true if sliding key is allowed.
private boolean mIsAllowedSlidingKeyInput;
- // pressed key
- private int mPreviousKey = NOT_A_KEY;
+ // ignore modifier key if true
+ private boolean mIgnoreModifierKey;
+
+ // TODO: Remove these hacking variables
+ // true if this pointer is in sliding language switch
+ private boolean mIsInSlidingLanguageSwitch;
+ private int mSpaceKeyIndex;
+ private static SubtypeSwitcher sSubtypeSwitcher;
// Empty {@link KeyboardActionListener}
private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener() {
@@ -102,46 +151,85 @@ public class PointerTracker {
public void onTextInput(CharSequence text) {}
@Override
public void onCancelInput() {}
- @Override
- public void onSwipeDown() {}
};
- public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy,
- Resources res) {
- if (proxy == null || handler == null || keyDetector == null)
- throw new NullPointerException();
- mPointerId = id;
- mProxy = proxy;
- mHandler = handler;
- mKeyDetector = keyDetector;
- mKeyboardSwitcher = KeyboardSwitcher.getInstance();
- mKeyState = new PointerTrackerKeyState(keyDetector);
- mIsAccessibilityEnabled = proxy.isAccessibilityEnabled();
- mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
- mConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
- mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
- mLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout);
- mLongPressShiftKeyTimeout = res.getInteger(R.integer.config_long_press_shift_key_timeout);
- mTouchNoiseThresholdMillis = res.getInteger(R.integer.config_touch_noise_threshold_millis);
+ public static void init(boolean hasDistinctMultitouch, Context context) {
+ 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);
+ sTouchNoiseThresholdMillis = res.getInteger(R.integer.config_touch_noise_threshold_millis);
final float touchNoiseThresholdDistance = res.getDimension(
R.dimen.config_touch_noise_threshold_distance);
- mTouchNoiseThresholdDistanceSquared = (int)(
+ sTouchNoiseThresholdDistanceSquared = (int)(
touchNoiseThresholdDistance * touchNoiseThresholdDistance);
+ sKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ sSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ }
+
+ public static PointerTracker getPointerTracker(final int id, KeyEventHandler handler) {
+ final List<PointerTracker> trackers = sTrackers;
+
+ // Create pointer trackers until we can get 'id+1'-th tracker, if needed.
+ for (int i = trackers.size(); i <= id; i++) {
+ final PointerTracker tracker = new PointerTracker(i, handler);
+ trackers.add(tracker);
+ }
+
+ return trackers.get(id);
+ }
+
+ public static boolean isAnyInSlidingKeyInput() {
+ return sPointerTrackerQueue != null ? sPointerTrackerQueue.isAnyInSlidingKeyInput() : false;
+ }
+
+ public static void setKeyboardActionListener(KeyboardActionListener listener) {
+ for (final PointerTracker tracker : sTrackers) {
+ tracker.mListener = listener;
+ }
+ }
+
+ public static void setKeyDetector(KeyDetector keyDetector) {
+ for (final PointerTracker tracker : sTrackers) {
+ tracker.setKeyDetectorInner(keyDetector);
+ // Mark that keyboard layout has been changed.
+ tracker.mKeyboardLayoutHasBeenChanged = true;
+ }
}
- public void setOnKeyboardActionListener(KeyboardActionListener listener) {
- mListener = listener;
+ public static void dismissAllKeyPreviews() {
+ for (final PointerTracker tracker : sTrackers) {
+ tracker.setReleasedKeyGraphics();
+ tracker.dismissKeyPreview();
+ }
}
- public void setAccessibilityEnabled(boolean accessibilityEnabled) {
- mIsAccessibilityEnabled = accessibilityEnabled;
+ public PointerTracker(int id, KeyEventHandler handler) {
+ if (handler == null)
+ throw new NullPointerException();
+ mPointerId = id;
+ setKeyDetectorInner(handler.getKeyDetector());
+ mListener = handler.getKeyboardActionListener();
+ mDrawingProxy = handler.getDrawingProxy();
+ mTimerProxy = handler.getTimerProxy();
}
// 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);
- if (key.mEnabled) {
+ Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding
+ + " ignoreModifier=" + ignoreModifierKey);
+ if (ignoreModifierKey)
+ return false;
+ if (key.isEnabled()) {
mListener.onPress(key.mCode, withSliding);
final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
mKeyboardLayoutHasBeenChanged = false;
@@ -153,26 +241,34 @@ 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);
- if (key.mEnabled)
+ + " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y
+ + " ignoreModifier=" + ignoreModifierKey);
+ 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.mEnabled)
+ if (key.isEnabled())
mListener.onTextInput(key.mOutputText);
}
// 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);
- if (key.mEnabled)
+ Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding="
+ + withSliding + " ignoreModifier=" + ignoreModifierKey);
+ if (ignoreModifierKey)
+ return;
+ if (key.isEnabled())
mListener.onRelease(primaryCode, withSliding);
}
@@ -182,16 +278,12 @@ public class PointerTracker {
mListener.onCancelInput();
}
- public void setKeyboard(Keyboard keyboard, Key[] keys, float keyHysteresisDistance) {
- if (keyboard == null || keys == null || keyHysteresisDistance < 0)
- throw new IllegalArgumentException();
- mKeyboard = keyboard;
- mKeys = keys;
- mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
- final int keyQuarterWidth = keyboard.getKeyWidth() / 4;
+ public void setKeyDetectorInner(KeyDetector keyDetector) {
+ mKeyDetector = keyDetector;
+ mKeyboard = keyDetector.getKeyboard();
+ mKeys = mKeyboard.getKeys();
+ final int keyQuarterWidth = mKeyboard.getKeyWidth() / 4;
mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
- // Mark that keyboard layout has been changed.
- mKeyboardLayoutHasBeenChanged = true;
}
public boolean isInSlidingKeyInput() {
@@ -199,11 +291,11 @@ public class PointerTracker {
}
private boolean isValidKeyIndex(int keyIndex) {
- return keyIndex >= 0 && keyIndex < mKeys.length;
+ return keyIndex >= 0 && keyIndex < mKeys.size();
}
public Key getKey(int keyIndex) {
- return isValidKeyIndex(keyIndex) ? mKeys[keyIndex] : null;
+ return isValidKeyIndex(keyIndex) ? mKeys.get(keyIndex) : null;
}
private static boolean isModifierCode(int primaryCode) {
@@ -217,7 +309,7 @@ public class PointerTracker {
}
public boolean isModifier() {
- return isModifierInternal(mKeyState.getKeyIndex());
+ return isModifierInternal(mKeyIndex);
}
private boolean isOnModifierKey(int x, int y) {
@@ -229,84 +321,99 @@ public class PointerTracker {
return key != null && key.mCode == Keyboard.CODE_SHIFT;
}
+ public int getKeyIndexOn(int x, int y) {
+ return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
+ }
+
public boolean isSpaceKey(int keyIndex) {
Key key = getKey(keyIndex);
return key != null && key.mCode == Keyboard.CODE_SPACE;
}
- public void releaseKey() {
- updateKeyGraphics(NOT_A_KEY);
+ public void setReleasedKeyGraphics() {
+ setReleasedKeyGraphics(mKeyIndex);
}
- private void updateKeyGraphics(int keyIndex) {
- int oldKeyIndex = mPreviousKey;
- mPreviousKey = keyIndex;
- if (keyIndex != oldKeyIndex) {
- if (isValidKeyIndex(oldKeyIndex)) {
- // if new key index is not a key, old key was just released inside of the key.
- final boolean inside = (keyIndex == NOT_A_KEY);
- mKeys[oldKeyIndex].onReleased(inside);
- mProxy.invalidateKey(mKeys[oldKeyIndex]);
- }
- if (isValidKeyIndex(keyIndex)) {
- mKeys[keyIndex].onPressed();
- mProxy.invalidateKey(mKeys[keyIndex]);
- }
+ private void setReleasedKeyGraphics(int keyIndex) {
+ final Key key = getKey(keyIndex);
+ if (key != null) {
+ key.onReleased();
+ mDrawingProxy.invalidateKey(key);
}
}
- public void setAlreadyProcessed() {
- mKeyAlreadyProcessed = true;
+ private void setPressedKeyGraphics(int keyIndex) {
+ final Key key = getKey(keyIndex);
+ if (key != null && key.isEnabled()) {
+ key.onPressed();
+ mDrawingProxy.invalidateKey(key);
+ }
}
- private void checkAssertion(PointerTrackerQueue queue) {
- if (mHasDistinctMultitouch && queue == null)
- throw new RuntimeException(
- "PointerTrackerQueue must be passed on distinct multi touch device");
- if (!mHasDistinctMultitouch && queue != null)
- throw new RuntimeException(
- "PointerTrackerQueue must be null on non-distinct multi touch device");
- }
-
- public void onTouchEvent(int action, int x, int y, long eventTime, PointerTrackerQueue queue) {
- switch (action) {
- case MotionEvent.ACTION_MOVE:
- onMoveEvent(x, y, eventTime, queue);
- break;
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_POINTER_DOWN:
- onDownEvent(x, y, eventTime, queue);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_POINTER_UP:
- onUpEvent(x, y, eventTime, queue);
- break;
- case MotionEvent.ACTION_CANCEL:
- onCancelEvent(x, y, eventTime, queue);
- break;
- }
+ public int getLastX() {
+ return mLastX;
}
- public void onDownEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
- if (ENABLE_ASSERTION) checkAssertion(queue);
+ public int getLastY() {
+ return mLastY;
+ }
+
+ public long getDownTime() {
+ return mDownTime;
+ }
+
+ private int onDownKey(int x, int y, long eventTime) {
+ mDownTime = eventTime;
+ return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
+ }
+
+ private int onMoveKeyInternal(int x, int y) {
+ mLastX = x;
+ mLastY = y;
+ return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
+ }
+
+ private int onMoveKey(int x, int y) {
+ return onMoveKeyInternal(x, y);
+ }
+
+ private int onMoveToNewKey(int keyIndex, int x, int y) {
+ mKeyIndex = keyIndex;
+ mKeyX = x;
+ mKeyY = y;
+ return keyIndex;
+ }
+
+ private int onUpKey(int x, int y, long eventTime) {
+ mUpTime = eventTime;
+ mKeyIndex = KeyDetector.NOT_A_KEY;
+ return onMoveKeyInternal(x, y);
+ }
+
+ public void onDownEvent(int x, int y, long eventTime, KeyEventHandler handler) {
if (DEBUG_EVENT)
printTouchEvent("onDownEvent:", x, y, eventTime);
+ mDrawingProxy = handler.getDrawingProxy();
+ mTimerProxy = handler.getTimerProxy();
+ setKeyboardActionListener(handler.getKeyboardActionListener());
+ setKeyDetectorInner(handler.getKeyDetector());
// Naive up-to-down noise filter.
- final long deltaT = eventTime - mKeyState.getUpTime();
- if (deltaT < mTouchNoiseThresholdMillis) {
- final int dx = x - mKeyState.getLastX();
- final int dy = y - mKeyState.getLastY();
+ final long deltaT = eventTime - mUpTime;
+ if (deltaT < sTouchNoiseThresholdMillis) {
+ final int dx = x - mLastX;
+ final int dy = y - mLastY;
final int distanceSquared = (dx * dx + dy * dy);
- if (distanceSquared < mTouchNoiseThresholdDistanceSquared) {
+ if (distanceSquared < sTouchNoiseThresholdDistanceSquared) {
if (DEBUG_MODE)
Log.w(TAG, "onDownEvent: ignore potential noise: time=" + deltaT
+ " distance=" + distanceSquared);
- setAlreadyProcessed();
+ mKeyAlreadyProcessed = true;
return;
}
}
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
if (isOnModifierKey(x, y)) {
// Before processing a down event of modifier key, all pointers already being
@@ -319,48 +426,54 @@ public class PointerTracker {
}
private void onDownEventInternal(int x, int y, long eventTime) {
- int keyIndex = mKeyState.onDownKey(x, y, eventTime);
+ int keyIndex = onDownKey(x, y, eventTime);
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
- // from modifier key, 3) this pointer is on mini-keyboard, or 4) accessibility is enabled.
- mIsAllowedSlidingKeyInput = mConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
- || mKeyDetector instanceof MiniKeyboardKeyDetector
- || mIsAccessibilityEnabled;
+ // from modifier key, or 3) this pointer is on mini-keyboard.
+ mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
+ || mKeyDetector instanceof MiniKeyboardKeyDetector;
mKeyboardLayoutHasBeenChanged = false;
mKeyAlreadyProcessed = false;
mIsRepeatableKey = false;
mIsInSlidingKeyInput = false;
+ mIsInSlidingLanguageSwitch = false;
+ mIgnoreModifierKey = false;
if (isValidKeyIndex(keyIndex)) {
// 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
// keyboard layout.
- if (callListenerOnPressAndCheckKeyboardLayoutChange(mKeys[keyIndex], false))
- keyIndex = mKeyState.onDownKey(x, y, eventTime);
- }
- if (isValidKeyIndex(keyIndex)) {
- // Accessibility disables key repeat because users may need to pause on a key to hear
- // its spoken description.
- if (mKeys[keyIndex].mRepeatable && !mIsAccessibilityEnabled) {
- repeatKey(keyIndex);
- mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
- mIsRepeatableKey = true;
- }
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), false))
+ keyIndex = onDownKey(x, y, eventTime);
+
+ startRepeatKey(keyIndex);
startLongPressTimer(keyIndex);
+ showKeyPreview(keyIndex);
+ setPressedKeyGraphics(keyIndex);
}
- showKeyPreviewAndUpdateKeyGraphics(keyIndex);
}
- public void onMoveEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
- if (ENABLE_ASSERTION) checkAssertion(queue);
+ private void startSlidingKeyInput(Key key) {
+ if (!mIsInSlidingKeyInput)
+ mIgnoreModifierKey = isModifierCode(key.mCode);
+ mIsInSlidingKeyInput = true;
+ }
+
+ public void onMoveEvent(int x, int y, long eventTime) {
if (DEBUG_MOVE_EVENT)
printTouchEvent("onMoveEvent:", x, y, eventTime);
if (mKeyAlreadyProcessed)
return;
- final PointerTrackerKeyState keyState = mKeyState;
- final int lastX = keyState.getLastX();
- final int lastY = keyState.getLastY();
- int keyIndex = keyState.onMoveKey(x, y);
- final Key oldKey = getKey(keyState.getKeyIndex());
+ // TODO: Remove this hacking code
+ if (mIsInSlidingLanguageSwitch) {
+ ((LatinKeyboard)mKeyboard).updateSpacebarPreviewIcon(x - mKeyX);
+ showKeyPreview(mSpaceKeyIndex);
+ return;
+ }
+ 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)) {
if (oldKey == null) {
// The pointer has been slid in to the new key, but the finger was not on any keys.
@@ -369,24 +482,30 @@ public class PointerTracker {
// {@link #setKeyboard}. In those cases, we should update keyIndex according to the
// new keyboard layout.
if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), true))
- keyIndex = keyState.onMoveKey(x, y);
- keyState.onMoveToNewKey(keyIndex, x, y);
+ keyIndex = onMoveKey(x, y);
+ onMoveToNewKey(keyIndex, x, y);
startLongPressTimer(keyIndex);
- } else if (!isMinorMoveBounce(x, y, keyIndex)) {
+ showKeyPreview(keyIndex);
+ setPressedKeyGraphics(keyIndex);
+ } else if (isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) {
// 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.
- mIsInSlidingKeyInput = true;
+ setReleasedKeyGraphics(oldKeyIndex);
callListenerOnRelease(oldKey, oldKey.mCode, true);
- mHandler.cancelLongPressTimers();
+ startSlidingKeyInput(oldKey);
+ mTimerProxy.cancelKeyTimers();
+ startRepeatKey(keyIndex);
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
// to the new keyboard layout.
if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), true))
- keyIndex = keyState.onMoveKey(x, y);
- keyState.onMoveToNewKey(keyIndex, x, y);
+ keyIndex = onMoveKey(x, y);
+ onMoveToNewKey(keyIndex, x, y);
startLongPressTimer(keyIndex);
+ setPressedKeyGraphics(keyIndex);
+ showKeyPreview(keyIndex);
} 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
@@ -398,165 +517,219 @@ public class PointerTracker {
if (DEBUG_MODE)
Log.w(TAG, String.format("onMoveEvent: sudden move is translated to "
+ "up[%d,%d]/down[%d,%d] events", lastX, lastY, x, y));
- onUpEventInternal(lastX, lastY, eventTime);
+ onUpEventInternal(lastX, lastY, eventTime, true);
onDownEventInternal(x, y, eventTime);
} else {
- setAlreadyProcessed();
- showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
+ mKeyAlreadyProcessed = true;
+ dismissKeyPreview();
+ setReleasedKeyGraphics(oldKeyIndex);
+ }
+ }
+ }
+ // TODO: Remove this hack code
+ else if (isSpaceKey(keyIndex) && !mIsInSlidingLanguageSwitch
+ && mKeyboard instanceof LatinKeyboard) {
+ final LatinKeyboard keyboard = ((LatinKeyboard)mKeyboard);
+ if (sSubtypeSwitcher.useSpacebarLanguageSwitcher()
+ && sSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
+ final int diff = x - mKeyX;
+ if (keyboard.shouldTriggerSpacebarSlidingLanguageSwitch(diff)) {
+ // Detect start sliding language switch.
+ mIsInSlidingLanguageSwitch = true;
+ mSpaceKeyIndex = keyIndex;
+ keyboard.updateSpacebarPreviewIcon(diff);
+ // Display spacebar slide language switcher.
+ showKeyPreview(keyIndex);
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
+ if (queue != null)
+ queue.releaseAllPointersExcept(this, eventTime, true);
}
- return;
}
}
} else {
- if (oldKey != null && !isMinorMoveBounce(x, y, keyIndex)) {
+ if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) {
// The pointer has been slid out from the previous key, we must call onRelease() to
// notify that the previous key has been released.
- mIsInSlidingKeyInput = true;
+ setReleasedKeyGraphics(oldKeyIndex);
callListenerOnRelease(oldKey, oldKey.mCode, true);
- mHandler.cancelLongPressTimers();
+ startSlidingKeyInput(oldKey);
+ mTimerProxy.cancelLongPressTimers();
if (mIsAllowedSlidingKeyInput) {
- keyState.onMoveToNewKey(keyIndex, x ,y);
+ onMoveToNewKey(keyIndex, x, y);
} else {
- setAlreadyProcessed();
- showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
- return;
+ mKeyAlreadyProcessed = true;
+ dismissKeyPreview();
}
}
}
- showKeyPreviewAndUpdateKeyGraphics(mKeyState.getKeyIndex());
}
- public void onUpEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
- if (ENABLE_ASSERTION) checkAssertion(queue);
+ public void onUpEvent(int x, int y, long eventTime) {
if (DEBUG_EVENT)
printTouchEvent("onUpEvent :", x, y, eventTime);
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
if (isModifier()) {
// Before processing an up event of modifier key, all pointers already being
// tracked should be released.
- queue.releaseAllPointersExcept(this, eventTime);
+ queue.releaseAllPointersExcept(this, eventTime, true);
} else {
queue.releaseAllPointersOlderThan(this, eventTime);
}
queue.remove(this);
}
- onUpEventInternal(x, y, eventTime);
+ onUpEventInternal(x, y, eventTime, true);
}
- public void onUpEventForRelease(int x, int y, long eventTime) {
- onUpEventInternal(x, y, eventTime);
+ // Let this pointer tracker know that one of newer-than-this pointer trackers got an up event.
+ // This pointer tracker needs to keep the key top graphics "pressed", but needs to get a
+ // "virtual" up event.
+ public void onPhantomUpEvent(int x, int y, long eventTime, boolean updateReleasedKeyGraphics) {
+ if (DEBUG_EVENT)
+ printTouchEvent("onPhntEvent:", x, y, eventTime);
+ onUpEventInternal(x, y, eventTime, updateReleasedKeyGraphics);
+ mKeyAlreadyProcessed = true;
}
- private void onUpEventInternal(int pointX, int pointY, long eventTime) {
- int x = pointX;
- int y = pointY;
- mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
- showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
+ private void onUpEventInternal(int x, int y, long eventTime,
+ boolean updateReleasedKeyGraphics) {
+ mTimerProxy.cancelKeyTimers();
+ mDrawingProxy.cancelShowKeyPreview(this);
mIsInSlidingKeyInput = false;
+ final int keyX, keyY;
+ if (isMajorEnoughMoveToBeOnNewKey(x, y, onMoveKey(x, y))) {
+ keyX = x;
+ keyY = y;
+ } else {
+ // Use previous fixed key coordinates.
+ keyX = mKeyX;
+ keyY = mKeyY;
+ }
+ final int keyIndex = onUpKey(keyX, keyY, eventTime);
+ dismissKeyPreview();
+ if (updateReleasedKeyGraphics)
+ setReleasedKeyGraphics(keyIndex);
if (mKeyAlreadyProcessed)
return;
- final PointerTrackerKeyState keyState = mKeyState;
- int keyIndex = keyState.onUpKey(x, y, eventTime);
- if (isMinorMoveBounce(x, y, keyIndex)) {
- // Use previous fixed key index and coordinates.
- keyIndex = keyState.getKeyIndex();
- x = keyState.getKeyX();
- y = keyState.getKeyY();
+ // TODO: Remove this hacking code
+ if (mIsInSlidingLanguageSwitch) {
+ setReleasedKeyGraphics(mSpaceKeyIndex);
+ final int languageDir = ((LatinKeyboard)mKeyboard).getLanguageChangeDirection();
+ if (languageDir != 0) {
+ final int code = (languageDir == 1)
+ ? LatinKeyboard.CODE_NEXT_LANGUAGE : LatinKeyboard.CODE_PREV_LANGUAGE;
+ // This will change keyboard layout.
+ mListener.onCodeInput(code, new int[] {code}, keyX, keyY);
+ }
+ mIsInSlidingLanguageSwitch = false;
+ ((LatinKeyboard)mKeyboard).setSpacebarSlidingLanguageSwitchDiff(0);
+ return;
}
if (!mIsRepeatableKey) {
- detectAndSendKey(keyIndex, x, y);
+ detectAndSendKey(keyIndex, keyX, keyY);
}
+ }
- if (isValidKeyIndex(keyIndex))
- mProxy.invalidateKey(mKeys[keyIndex]);
+ public void onLongPressed() {
+ mKeyAlreadyProcessed = true;
+ setReleasedKeyGraphics();
+ dismissKeyPreview();
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
+ if (queue != null) {
+ queue.remove(this);
+ }
}
- public void onCancelEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
- if (ENABLE_ASSERTION) checkAssertion(queue);
+ public void onCancelEvent(int x, int y, long eventTime) {
if (DEBUG_EVENT)
printTouchEvent("onCancelEvt:", x, y, eventTime);
- if (queue != null)
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
+ if (queue != null) {
+ queue.releaseAllPointersExcept(this, eventTime, true);
queue.remove(this);
+ }
onCancelEventInternal();
}
private void onCancelEventInternal() {
- mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
- showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
+ mTimerProxy.cancelKeyTimers();
+ mDrawingProxy.cancelShowKeyPreview(this);
+ dismissKeyPreview();
+ setReleasedKeyGraphics(mKeyIndex);
mIsInSlidingKeyInput = false;
- int keyIndex = mKeyState.getKeyIndex();
- if (isValidKeyIndex(keyIndex))
- mProxy.invalidateKey(mKeys[keyIndex]);
}
- public void repeatKey(int keyIndex) {
+ private void startRepeatKey(int keyIndex) {
+ final Key key = getKey(keyIndex);
+ if (key != null && key.mRepeatable) {
+ dismissKeyPreview();
+ onRepeatKey(keyIndex);
+ mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, keyIndex, this);
+ mIsRepeatableKey = true;
+ } else {
+ mIsRepeatableKey = false;
+ }
+ }
+
+ public void onRepeatKey(int keyIndex) {
Key key = getKey(keyIndex);
if (key != null) {
detectAndSendKey(keyIndex, key.mX, key.mY);
}
}
- public int getLastX() {
- return mKeyState.getLastX();
- }
-
- public int getLastY() {
- return mKeyState.getLastY();
- }
-
- public long getDownTime() {
- return mKeyState.getDownTime();
- }
-
- private boolean isMinorMoveBounce(int x, int y, int newKey) {
- if (mKeys == null || mKeyHysteresisDistanceSquared < 0)
- throw new IllegalStateException("keyboard and/or hysteresis not set");
- int curKey = mKeyState.getKeyIndex();
+ private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, int newKey) {
+ if (mKeys == null || mKeyDetector == null)
+ throw new NullPointerException("keyboard and/or key detector not set");
+ int curKey = mKeyIndex;
if (newKey == curKey) {
- return true;
+ return false;
} else if (isValidKeyIndex(curKey)) {
- return mKeys[curKey].squaredDistanceToEdge(x, y) < mKeyHysteresisDistanceSquared;
+ return mKeys.get(curKey).squaredDistanceToEdge(x, y)
+ >= mKeyDetector.getKeyHysteresisDistanceSquared();
} else {
- return false;
+ return true;
}
}
- private void showKeyPreviewAndUpdateKeyGraphics(int keyIndex) {
- updateKeyGraphics(keyIndex);
- // The modifier key, such as shift key, should not be shown as preview when multi-touch is
- // supported. On the other hand, if multi-touch is not supported, the modifier key should
- // be shown as preview. If accessibility is turned on, the modifier key should be shown as
- // preview.
- if (mHasDistinctMultitouch && isModifier() && !mIsAccessibilityEnabled) {
- mProxy.showPreview(NOT_A_KEY, this);
- } else {
- mProxy.showPreview(keyIndex, this);
- }
+ // The modifier key, such as shift key, should not show its key preview.
+ private boolean isKeyPreviewNotRequired(int keyIndex) {
+ final Key key = getKey(keyIndex);
+ if (key == null || !key.isEnabled())
+ return true;
+ // Such as spacebar sliding language switch.
+ if (mKeyboard.needSpacebarPreview(keyIndex))
+ return false;
+ final int code = key.mCode;
+ return isModifierCode(code) || code == Keyboard.CODE_DELETE
+ || code == Keyboard.CODE_ENTER || code == Keyboard.CODE_SPACE;
}
- private void startLongPressTimer(int keyIndex) {
- // Accessibility disables long press because users are likely to need to pause on a key
- // for an unspecified duration in order to hear the key's spoken description.
- if (mIsAccessibilityEnabled) {
+ private void showKeyPreview(int keyIndex) {
+ if (isKeyPreviewNotRequired(keyIndex))
return;
- }
+ mDrawingProxy.showKeyPreview(keyIndex, this);
+ }
+
+ private void dismissKeyPreview() {
+ mDrawingProxy.dismissKeyPreview(this);
+ }
+
+ private void startLongPressTimer(int keyIndex) {
Key key = getKey(keyIndex);
if (key.mCode == Keyboard.CODE_SHIFT) {
- mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
- } else if (key.mManualTemporaryUpperCaseCode != Keyboard.CODE_DUMMY
- && mKeyboard.isManualTemporaryUpperCase()) {
+ mTimerProxy.startLongPressShiftTimer(sLongPressShiftKeyTimeout, 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 (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
+ } else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
// We use longer timeout for sliding finger input started from the symbols mode key.
- mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
+ mTimerProxy.startLongPressTimer(sLongPressKeyTimeout * 3, keyIndex, this);
} else {
- mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
+ mTimerProxy.startLongPressTimer(sLongPressKeyTimeout, keyIndex, this);
}
}
@@ -575,10 +748,9 @@ public class PointerTracker {
mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
// If keyboard is in manual temporary upper case state and key has manual temporary
- // shift code, alternate character code should be sent.
- if (mKeyboard.isManualTemporaryUpperCase()
- && key.mManualTemporaryUpperCaseCode != Keyboard.CODE_DUMMY) {
- code = key.mManualTemporaryUpperCaseCode;
+ // 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;
}
@@ -594,10 +766,6 @@ public class PointerTracker {
}
}
- public CharSequence getPreviewText(Key key) {
- return key.mLabel;
- }
-
private long mPreviousEventTime;
private void printTouchEvent(String title, int x, int y, long eventTime) {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
deleted file mode 100644
index 64ba80a04..000000000
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
+++ /dev/null
@@ -1,97 +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;
-
-/**
- * This class keeps track of a key index and a position where {@link PointerTracker} is.
- */
-/* package */ class PointerTrackerKeyState {
- private final KeyDetector mKeyDetector;
-
- // The position and time at which first down event occurred.
- 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.
- private int mKeyX;
- private int mKeyY;
-
- // Last pointer position.
- private int mLastX;
- private int mLastY;
-
- public PointerTrackerKeyState(KeyDetector keyDetecor) {
- mKeyDetector = keyDetecor;
- }
-
- public int getKeyIndex() {
- return mKeyIndex;
- }
-
- public int getKeyX() {
- return mKeyX;
- }
-
- public int getKeyY() {
- return mKeyY;
- }
-
- public long getDownTime() {
- return mDownTime;
- }
-
- public long getUpTime() {
- return mUpTime;
- }
-
- public int getLastX() {
- return mLastX;
- }
-
- public int getLastY() {
- return mLastY;
- }
-
- public int onDownKey(int x, int y, long eventTime) {
- mDownTime = eventTime;
- return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
- }
-
- private int onMoveKeyInternal(int x, int y) {
- mLastX = x;
- mLastY = y;
- return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
- }
-
- public int onMoveKey(int x, int y) {
- return onMoveKeyInternal(x, y);
- }
-
- public int onMoveToNewKey(int keyIndex, int x, int y) {
- mKeyIndex = keyIndex;
- mKeyX = x;
- mKeyY = y;
- return keyIndex;
- }
-
- public int onUpKey(int x, int y, long eventTime) {
- mUpTime = eventTime;
- return onMoveKeyInternal(x, y);
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
new file mode 100644
index 000000000..af8e59568
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -0,0 +1,193 @@
+/*
+ * 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.Resources;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.PopupWindow;
+
+import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
+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.
+ */
+public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
+ private final int[] mCoordinates = new int[2];
+ private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
+
+ private final KeyDetector mKeyDetector;
+ private final int mVerticalCorrection;
+
+ private LatinKeyboardBaseView mParentKeyboardView;
+ private int mOriginX;
+ private int mOriginY;
+
+ private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy() {
+ @Override
+ public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ @Override
+ public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ @Override
+ public void startLongPressShiftTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ @Override
+ public void cancelLongPressTimers() {}
+ @Override
+ public void cancelKeyTimers() {}
+ };
+
+ private final KeyboardActionListener mListner = new KeyboardActionListener() {
+ @Override
+ public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
+ mParentKeyboardView.getKeyboardActionListener()
+ .onCodeInput(primaryCode, keyCodes, x, y);
+ mParentKeyboardView.dismissMiniKeyboard();
+ }
+
+ @Override
+ public void onTextInput(CharSequence text) {
+ mParentKeyboardView.getKeyboardActionListener().onTextInput(text);
+ mParentKeyboardView.dismissMiniKeyboard();
+ }
+
+ @Override
+ public void onCancelInput() {
+ mParentKeyboardView.getKeyboardActionListener().onCancelInput();
+ mParentKeyboardView.dismissMiniKeyboard();
+ }
+
+ @Override
+ public void onPress(int primaryCode, boolean withSliding) {
+ mParentKeyboardView.getKeyboardActionListener().onPress(primaryCode, withSliding);
+ }
+ @Override
+ public void onRelease(int primaryCode, boolean withSliding) {
+ mParentKeyboardView.getKeyboardActionListener().onRelease(primaryCode, withSliding);
+ }
+ };
+
+ public PopupMiniKeyboardView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.popupMiniKeyboardViewStyle);
+ }
+
+ public PopupMiniKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+ mVerticalCorrection = a.getDimensionPixelOffset(
+ R.styleable.KeyboardView_verticalCorrection, 0);
+ a.recycle();
+
+ final Resources res = context.getResources();
+ mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean(
+ R.bool.config_show_mini_keyboard_at_touched_point);
+ // Override default ProximityKeyDetector.
+ mKeyDetector = new MiniKeyboardKeyDetector(res.getDimension(
+ R.dimen.mini_keyboard_slide_allowance));
+ // Remove gesture detector on mini-keyboard
+ setKeyPreviewPopupEnabled(false, 0);
+ }
+
+ @Override
+ public void setKeyboard(Keyboard keyboard) {
+ super.setKeyboard(keyboard);
+ mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
+ -getPaddingTop() + mVerticalCorrection);
+ }
+
+ @Override
+ public KeyDetector getKeyDetector() {
+ return mKeyDetector;
+ }
+
+ @Override
+ public KeyboardActionListener getKeyboardActionListener() {
+ return mListner;
+ }
+
+ @Override
+ public DrawingProxy getDrawingProxy() {
+ return this;
+ }
+
+ @Override
+ public TimerProxy getTimerProxy() {
+ return EMPTY_TIMER_PROXY;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ // Do nothing for the mini keyboard.
+ }
+
+ @Override
+ public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ // Mini 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 showPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
+ PointerTracker tracker, PopupWindow window) {
+ mParentKeyboardView = parentKeyboardView;
+ final View container = (View)getParent();
+ final MiniKeyboard miniKeyboard = (MiniKeyboard)getKeyboard();
+ final Keyboard parentKeyboard = parentKeyboardView.getKeyboard();
+
+ parentKeyboardView.getLocationInWindow(mCoordinates);
+ final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX()
+ : parentKey.mX + parentKey.mWidth / 2;
+ final int pointY = parentKey.mY;
+ final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX()
+ + parentKeyboardView.getPaddingLeft();
+ final int x = Math.max(0, Math.min(miniKeyboardLeft,
+ parentKeyboardView.getWidth() - miniKeyboard.getMinWidth()))
+ - container.getPaddingLeft() + mCoordinates[0];
+ final int y = pointY - parentKeyboard.getVerticalGap()
+ - (container.getMeasuredHeight() - container.getPaddingBottom())
+ + parentKeyboardView.getPaddingTop() + mCoordinates[1];
+
+ if (miniKeyboard.setShifted(parentKeyboard.isShiftedOrShiftLocked())) {
+ invalidateAllKeys();
+ }
+ window.setContentView(container);
+ window.setWidth(container.getMeasuredWidth());
+ window.setHeight(container.getMeasuredHeight());
+ window.showAtLocation(parentKeyboardView, Gravity.NO_GRAVITY, x, y);
+
+ mOriginX = x + container.getPaddingLeft() - mCoordinates[0];
+ mOriginY = y + container.getPaddingTop() - mCoordinates[1];
+ }
+
+ @Override
+ public int translateX(int x) {
+ return x - mOriginX;
+ }
+
+ @Override
+ public int translateY(int y) {
+ return y - mOriginY;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/PopupPanel.java b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
new file mode 100644
index 000000000..f94d1c562
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
@@ -0,0 +1,45 @@
+/*
+ * 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.widget.PopupWindow;
+
+public interface PopupPanel extends PointerTracker.KeyEventHandler {
+ /**
+ * Show popup panel.
+ * @param parentKeyboardView the parent KeyboardView that has the parent key.
+ * @param parentKey the parent key that is the source of this popup panel
+ * @param tracker the pointer tracker that pressesd the parent key
+ * @param window PopupWindow to be used to show this popup panel
+ */
+ public void showPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
+ PointerTracker tracker, PopupWindow window);
+
+ /**
+ * Translate X-coordinate of touch event to the local X-coordinate of this PopupPanel.
+ * @param x the global X-coordinate
+ * @return the local X-coordinate to this PopupPanel
+ */
+ public int translateX(int x);
+
+ /**
+ * Translate Y-coordinate of touch event to the local Y-coordinate of this PopupPanel.
+ * @param y the global Y-coordinate
+ * @return the local Y-coordinate to this PopupPanel
+ */
+ public int translateY(int y);
+}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 33acc6907..aadedc69d 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -23,15 +23,35 @@ import java.util.List;
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 final int mGridWidth;
private final int mGridHeight;
private final int mGridSize;
+ private final int mCellWidth;
+ private final int mCellHeight;
+ // TODO: Find a proper name for mKeyboardMinWidth
+ private final int mKeyboardMinWidth;
+ private final int mKeyboardHeight;
+ private final int[][] mGridNeighbors;
- ProximityInfo(int gridWidth, int gridHeight) {
+ ProximityInfo(
+ int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, List<Key> keys) {
mGridWidth = gridWidth;
mGridHeight = gridHeight;
mGridSize = mGridWidth * mGridHeight;
+ mCellWidth = (minWidth + mGridWidth - 1) / mGridWidth;
+ mCellHeight = (height + mGridHeight - 1) / mGridHeight;
+ mKeyboardMinWidth = minWidth;
+ mKeyboardHeight = height;
+ mGridNeighbors = new int[mGridSize][];
+ if (minWidth == 0 || height == 0) {
+ // No proximity required. Keyboard might be mini keyboard.
+ return;
+ }
+ computeNearestNeighbors(keyWidth, keys);
}
private int mNativeProximityInfo;
@@ -42,7 +62,7 @@ public class ProximityInfo {
int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray);
private native void releaseProximityInfoNative(int nativeProximityInfo);
- public final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
+ private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
int keyboardHeight, List<Key> keys) {
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
@@ -57,12 +77,7 @@ public class ProximityInfo {
keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray);
}
- // TODO: Get rid of this function's input (keyboard).
- public int getNativeProximityInfo(Keyboard keyboard) {
- if (mNativeProximityInfo == 0) {
- // TODO: Move this function to ProximityInfo and make this private.
- keyboard.computeNearestNeighbors();
- }
+ public int getNativeProximityInfo() {
return mNativeProximityInfo;
}
@@ -77,4 +92,42 @@ public class ProximityInfo {
super.finalize();
}
}
+
+ private void computeNearestNeighbors(int defaultWidth, List<Key> keys) {
+ 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 int gridWidth = mGridWidth * mCellWidth;
+ final int gridHeight = mGridHeight * mCellHeight;
+ for (int x = 0; x < gridWidth; x += mCellWidth) {
+ for (int y = 0; y < gridHeight; y += mCellHeight) {
+ 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);
+ if (key.squaredDistanceToEdge(centerX, centerY) < threshold)
+ indices[count++] = i;
+ }
+ final int[] cell = new int[count];
+ System.arraycopy(indices, 0, cell, 0, count);
+ mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
+ }
+ }
+ setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys);
+ }
+
+ public int[] getNearestKeys(int x, int y) {
+ if (mGridNeighbors == null) {
+ return EMPTY_INT_ARRAY;
+ }
+ if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
+ int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
+ if (index < mGridSize) {
+ return mGridNeighbors[index];
+ }
+ }
+ return EMPTY_INT_ARRAY;
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
deleted file mode 100644
index e2ff8c48e..000000000
--- a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
+++ /dev/null
@@ -1,126 +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;
-
-import android.util.Log;
-
-import java.util.Arrays;
-
-public class ProximityKeyDetector extends KeyDetector {
- private static final String TAG = ProximityKeyDetector.class.getSimpleName();
- private static final boolean DEBUG = false;
-
- private static final int MAX_NEARBY_KEYS = 12;
-
- // working area
- private final int[] mDistances = new int[MAX_NEARBY_KEYS];
- private final int[] mIndices = new int[MAX_NEARBY_KEYS];
-
- @Override
- protected int getMaxNearbyKeys() {
- return MAX_NEARBY_KEYS;
- }
-
- private void initializeNearbyKeys() {
- Arrays.fill(mDistances, Integer.MAX_VALUE);
- Arrays.fill(mIndices, NOT_A_KEY);
- }
-
- /**
- * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance.
- *
- * @param keyIndex index of the key.
- * @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) {
- final int[] distances = mDistances;
- final int[] indices = mIndices;
- for (int insertPos = 0; insertPos < distances.length; insertPos++) {
- final int comparingDistance = distances[insertPos];
- if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) {
- final int nextPos = insertPos + 1;
- if (nextPos < distances.length) {
- System.arraycopy(distances, insertPos, distances, nextPos,
- distances.length - nextPos);
- System.arraycopy(indices, insertPos, indices, nextPos,
- indices.length - nextPos);
- }
- distances[insertPos] = distance;
- indices[insertPos] = keyIndex;
- return insertPos;
- }
- }
- return distances.length;
- }
-
- private void getNearbyKeyCodes(final int[] allCodes) {
- final Key[] keys = getKeys();
- final int[] indices = mIndices;
-
- // allCodes[0] should always have the key code even if it is a non-letter key.
- if (indices[0] == NOT_A_KEY) {
- 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)
- break;
- final int code = keys[index].mCode;
- // filter out a non-letter key from nearby keys
- if (code < Keyboard.CODE_SPACE)
- continue;
- allCodes[numCodes++] = code;
- }
- }
-
- @Override
- public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
- final Key[] keys = getKeys();
- 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[index];
- final boolean isInside = key.isInside(touchX, touchY);
- final int distance = key.squaredDistanceToEdge(touchX, touchY);
- if (isInside || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
- final int insertedPosition = sortNearbyKeys(index, distance, isInside);
- if (insertedPosition == 0 && isInside)
- primaryIndex = index;
- }
- }
-
- if (allCodes != null && allCodes.length > 0) {
- getNearbyKeyCodes(allCodes);
- if (DEBUG) {
- Log.d(TAG, "x=" + x + " y=" + y
- + " primary="
- + (primaryIndex == NOT_A_KEY ? "none" : keys[primaryIndex].mCode)
- + " codes=" + Arrays.toString(allCodes));
- }
- }
-
- return primaryIndex;
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/SwipeTracker.java b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
deleted file mode 100644
index 975b13b50..000000000
--- a/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
+++ /dev/null
@@ -1,157 +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;
-
-import android.view.MotionEvent;
-
-public class SwipeTracker {
- private static final int NUM_PAST = 4;
- private static final int LONGEST_PAST_TIME = 200;
-
- final EventRingBuffer mBuffer = new EventRingBuffer(NUM_PAST);
-
- private float mYVelocity;
- private float mXVelocity;
-
- public void addMovement(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mBuffer.clear();
- return;
- }
- long time = ev.getEventTime();
- final int count = ev.getHistorySize();
- for (int i = 0; i < count; i++) {
- addPoint(ev.getHistoricalX(i), ev.getHistoricalY(i), ev.getHistoricalEventTime(i));
- }
- addPoint(ev.getX(), ev.getY(), time);
- }
-
- private void addPoint(float x, float y, long time) {
- final EventRingBuffer buffer = mBuffer;
- while (buffer.size() > 0) {
- long lastT = buffer.getTime(0);
- if (lastT >= time - LONGEST_PAST_TIME)
- break;
- buffer.dropOldest();
- }
- buffer.add(x, y, time);
- }
-
- public void computeCurrentVelocity(int units) {
- computeCurrentVelocity(units, Float.MAX_VALUE);
- }
-
- public void computeCurrentVelocity(int units, float maxVelocity) {
- final EventRingBuffer buffer = mBuffer;
- final float oldestX = buffer.getX(0);
- final float oldestY = buffer.getY(0);
- final long oldestTime = buffer.getTime(0);
-
- float accumX = 0;
- float accumY = 0;
- final int count = buffer.size();
- for (int pos = 1; pos < count; pos++) {
- final int dur = (int)(buffer.getTime(pos) - oldestTime);
- if (dur == 0) continue;
- float dist = buffer.getX(pos) - oldestX;
- float vel = (dist / dur) * units; // pixels/frame.
- if (accumX == 0) accumX = vel;
- else accumX = (accumX + vel) * .5f;
-
- dist = buffer.getY(pos) - oldestY;
- vel = (dist / dur) * units; // pixels/frame.
- if (accumY == 0) accumY = vel;
- else accumY = (accumY + vel) * .5f;
- }
- mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
- : Math.min(accumX, maxVelocity);
- mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
- : Math.min(accumY, maxVelocity);
- }
-
- public float getXVelocity() {
- return mXVelocity;
- }
-
- public float getYVelocity() {
- return mYVelocity;
- }
-
- public static class EventRingBuffer {
- private final int bufSize;
- private final float xBuf[];
- private final float yBuf[];
- private final long timeBuf[];
- private int top; // points new event
- private int end; // points oldest event
- private int count; // the number of valid data
-
- public EventRingBuffer(int max) {
- this.bufSize = max;
- xBuf = new float[max];
- yBuf = new float[max];
- timeBuf = new long[max];
- clear();
- }
-
- public void clear() {
- top = end = count = 0;
- }
-
- public int size() {
- return count;
- }
-
- // Position 0 points oldest event
- private int index(int pos) {
- return (end + pos) % bufSize;
- }
-
- private int advance(int index) {
- return (index + 1) % bufSize;
- }
-
- public void add(float x, float y, long time) {
- xBuf[top] = x;
- yBuf[top] = y;
- timeBuf[top] = time;
- top = advance(top);
- if (count < bufSize) {
- count++;
- } else {
- end = advance(end);
- }
- }
-
- public float getX(int pos) {
- return xBuf[index(pos)];
- }
-
- public float getY(int pos) {
- return yBuf[index(pos)];
- }
-
- public long getTime(int pos) {
- return timeBuf[index(pos)];
- }
-
- public void dropOldest() {
- count--;
- end = advance(end);
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
index 8d9b1b41e..30d9692a8 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
@@ -14,16 +14,15 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.keyboard.KeyboardParser.ParseException;
-import com.android.inputmethod.latin.R;
+package com.android.inputmethod.keyboard.internal;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
-import android.graphics.drawable.Drawable;
import android.util.Log;
+import com.android.inputmethod.keyboard.internal.KeyboardParser.ParseException;
+import com.android.inputmethod.latin.R;
+
import java.util.ArrayList;
import java.util.HashMap;
@@ -37,7 +36,6 @@ public class KeyStyles {
public interface KeyStyle {
public CharSequence[] getTextArray(TypedArray a, int index);
- public Drawable getDrawable(TypedArray a, int index);
public CharSequence getText(TypedArray a, int index);
public int getInt(TypedArray a, int index, int defaultValue);
public int getFlag(TypedArray a, int index, int defaultValue);
@@ -55,11 +53,6 @@ public class KeyStyles {
}
@Override
- public Drawable getDrawable(TypedArray a, int index) {
- return a.getDrawable(index);
- }
-
- @Override
public CharSequence getText(TypedArray a, int index) {
return a.getText(index);
}
@@ -140,12 +133,6 @@ public class KeyStyles {
}
@Override
- public Drawable getDrawable(TypedArray a, int index) {
- return a.hasValue(index)
- ? super.getDrawable(a, index) : (Drawable)mAttributes.get(index);
- }
-
- @Override
public CharSequence getText(TypedArray a, int index) {
return a.hasValue(index)
? super.getText(a, index) : (CharSequence)mAttributes.get(index);
@@ -177,25 +164,20 @@ public class KeyStyles {
// 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);
- readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelOption);
+ readText(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
+ readText(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
readTextArray(keyAttr, R.styleable.Keyboard_Key_popupCharacters);
+ readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelOption);
+ readInt(keyAttr, R.styleable.Keyboard_Key_keyIcon);
+ readInt(keyAttr, R.styleable.Keyboard_Key_keyIconPreview);
+ readInt(keyAttr, R.styleable.Keyboard_Key_keyIconShifted);
readInt(keyAttr, R.styleable.Keyboard_Key_maxPopupKeyboardColumn);
- readText(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
- readDrawable(keyAttr, R.styleable.Keyboard_Key_keyIcon);
- readDrawable(keyAttr, R.styleable.Keyboard_Key_iconPreview);
- readDrawable(keyAttr, R.styleable.Keyboard_Key_keyHintIcon);
- readDrawable(keyAttr, R.styleable.Keyboard_Key_shiftedIcon);
- readBoolean(keyAttr, R.styleable.Keyboard_Key_isModifier);
+ readBoolean(keyAttr, R.styleable.Keyboard_Key_isFunctional);
readBoolean(keyAttr, R.styleable.Keyboard_Key_isSticky);
readBoolean(keyAttr, R.styleable.Keyboard_Key_isRepeatable);
readBoolean(keyAttr, R.styleable.Keyboard_Key_enabled);
}
- private void readDrawable(TypedArray a, int index) {
- if (a.hasValue(index))
- mAttributes.put(index, a.getDrawable(index));
- }
-
private void readText(TypedArray a, int index) {
if (a.hasValue(index))
mAttributes.put(index, a.getText(index));
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
new file mode 100644
index 000000000..535a6954c
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -0,0 +1,119 @@
+/*
+ * 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.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.R;
+
+public class KeyboardIconsSet {
+ private static final String TAG = KeyboardIconsSet.class.getSimpleName();
+
+ public static final int ICON_UNDEFINED = 0;
+
+ // This should be aligned with Keyboard.keyIcon enum.
+ private static final int ICON_SHIFT_KEY = 1;
+ private static final int ICON_TO_SYMBOL_KEY = 2;
+ private static final int ICON_TO_SYMBOL_KEY_WITH_SHORTCUT = 3;
+ private static final int ICON_DELETE_KEY = 4;
+ private static final int ICON_DELETE_RTL_KEY = 5;
+ private static final int ICON_SETTINGS_KEY = 6;
+ private static final int ICON_SHORTCUT_KEY = 7;
+ private static final int ICON_SPACE_KEY = 8;
+ private static final int ICON_RETURN_KEY = 9;
+ private static final int ICON_SEARCH_KEY = 10;
+ private static final int ICON_TAB_KEY = 11;
+ // This should be aligned with Keyboard.keyIconShifted enum.
+ private static final int ICON_SHIFTED_SHIFT_KEY = 12;
+ // This should be aligned with Keyboard.keyIconPreview enum.
+ private static final int ICON_PREVIEW_SPACE_KEY = 13;
+ private static final int ICON_PREVIEW_TAB_KEY = 14;
+ private static final int ICON_PREVIEW_SETTINGS_KEY = 15;
+ private static final int ICON_PREVIEW_SHORTCUT_KEY = 16;
+
+ private static final int ICON_LAST = 16;
+
+ private final Drawable mIcons[] = new Drawable[ICON_LAST + 1];
+
+ private static final int getIconId(int attrIndex) {
+ switch (attrIndex) {
+ case R.styleable.Keyboard_iconShiftKey:
+ return ICON_SHIFT_KEY;
+ case R.styleable.Keyboard_iconToSymbolKey:
+ return ICON_TO_SYMBOL_KEY;
+ case R.styleable.Keyboard_iconToSymbolKeyWithShortcut:
+ return ICON_TO_SYMBOL_KEY_WITH_SHORTCUT;
+ case R.styleable.Keyboard_iconDeleteKey:
+ return ICON_DELETE_KEY;
+ case R.styleable.Keyboard_iconDeleteRtlKey:
+ return ICON_DELETE_RTL_KEY;
+ case R.styleable.Keyboard_iconSettingsKey:
+ return ICON_SETTINGS_KEY;
+ case R.styleable.Keyboard_iconShortcutKey:
+ return ICON_SHORTCUT_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_iconShiftedShiftKey:
+ return ICON_SHIFTED_SHIFT_KEY;
+ case R.styleable.Keyboard_iconPreviewSpaceKey:
+ return ICON_PREVIEW_SPACE_KEY;
+ case R.styleable.Keyboard_iconPreviewTabKey:
+ return ICON_PREVIEW_TAB_KEY;
+ case R.styleable.Keyboard_iconPreviewSettingsKey:
+ return ICON_PREVIEW_SETTINGS_KEY;
+ case R.styleable.Keyboard_iconPreviewShortcutKey:
+ return ICON_PREVIEW_SHORTCUT_KEY;
+ default:
+ return ICON_UNDEFINED;
+ }
+ }
+
+ public void loadIcons(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 {
+ final Drawable icon = keyboardAttrs.getDrawable(attrIndex);
+ Keyboard.setDefaultBounds(icon);
+ mIcons[iconId] = icon;
+ } catch (Resources.NotFoundException e) {
+ Log.w(TAG, "Drawable resource for icon #" + iconId + " not found");
+ }
+ }
+ }
+ }
+
+ public Drawable getIcon(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];
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
index b240f6d09..e35db8955 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
@@ -14,13 +14,9 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.latin.R;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
+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;
@@ -29,6 +25,15 @@ 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.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@@ -86,14 +91,14 @@ import java.util.List;
* You can declare Key style and specify styles within Key tags.
* <pre>
* &gt;switch&lt;
- * &gt;case colorScheme="white"&lt;
- * &gt;key-style styleName="shift-key" parentStyle="modifier-key"
- * keyIcon="@drawable/sym_keyboard_shift"
+ * &gt;case mode="email"&lt;
+ * &gt;key-style styleName="f1-key" parentStyle="modifier-key"
+ * keyLabel=".com"
* /&lt;
* &gt;/case&lt;
- * &gt;case colorScheme="black"&lt;
- * &gt;key-style styleName="shift-key" parentStyle="modifier-key"
- * keyIcon="@drawable/sym_bkeyboard_shift"
+ * &gt;case mode="url"&lt;
+ * &gt;key-style styleName="f1-key" parentStyle="modifier-key"
+ * keyLabel="http://"
* /&lt;
* &gt;/case&lt;
* &gt;/switch&lt;
@@ -119,8 +124,12 @@ public class KeyboardParser {
public static final String TAG_KEY_STYLE = "key-style";
private final Keyboard mKeyboard;
+ private final Context mContext;
private final Resources mResources;
+ private int mKeyboardTopPadding;
+ private int mKeyboardBottomPadding;
+ private int mHorizontalEdgesPadding;
private int mCurrentX = 0;
private int mCurrentY = 0;
private int mMaxRowWidth = 0;
@@ -128,9 +137,12 @@ public class KeyboardParser {
private Row mCurrentRow = null;
private final KeyStyles mKeyStyles = new KeyStyles();
- public KeyboardParser(Keyboard keyboard, Resources res) {
+ public KeyboardParser(Keyboard keyboard, Context context) {
mKeyboard = keyboard;
+ mContext = context;
+ final Resources res = context.getResources();
mResources = res;
+ mHorizontalEdgesPadding = (int)res.getDimension(R.dimen.keyboard_horizontal_edges_padding);
}
public int getMaxRowWidth() {
@@ -150,6 +162,7 @@ public class KeyboardParser {
final String tag = parser.getName();
if (TAG_KEYBOARD.equals(tag)) {
parseKeyboardAttributes(parser);
+ startKeyboard();
parseKeyboardContent(parser, mKeyboard.getKeys());
break;
} else {
@@ -159,10 +172,33 @@ public class KeyboardParser {
}
}
+ public static String parseKeyboardLocale(
+ Context context, int resId) throws XmlPullParserException, IOException {
+ final Resources res = context.getResources();
+ final XmlResourceParser 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);
+ return keyboardAttr.getString(R.styleable.Keyboard_keyboardLocale);
+ } else {
+ throw new IllegalStartTag(parser, TAG_KEYBOARD);
+ }
+ }
+ }
+ return "";
+ }
+
private void parseKeyboardAttributes(XmlResourceParser parser) {
final Keyboard keyboard = mKeyboard;
- final TypedArray keyboardAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
+ final int displayWidth = keyboard.getDisplayWidth();
+ 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 {
@@ -170,25 +206,40 @@ public class KeyboardParser {
final int keyboardHeight = (int)keyboardAttr.getDimension(
R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
final int maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- // Keyboard height will not exceed maxKeyboardHeight.
- final int height = Math.min(keyboardHeight, maxKeyboardHeight);
- final int width = keyboard.getDisplayWidth();
+ R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
+ int minKeyboardHeight = 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 = -getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
+ }
+ // Keyboard height will not exceed maxKeyboardHeight and will not be less than
+ // minKeyboardHeight.
+ final int height = Math.max(
+ Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
+
keyboard.setKeyboardHeight(height);
keyboard.setKeyWidth(getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyWidth, width, width / 10));
+ R.styleable.Keyboard_keyWidth, displayWidth, displayWidth / 10));
keyboard.setRowHeight(getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_rowHeight, height, 50));
keyboard.setHorizontalGap(getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_horizontalGap, width, 0));
+ R.styleable.Keyboard_horizontalGap, displayWidth, 0));
keyboard.setVerticalGap(getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_verticalGap, height, 0));
keyboard.setPopupKeyboardResId(keyboardAttr.getResourceId(
R.styleable.Keyboard_popupKeyboardTemplate, 0));
-
keyboard.setMaxPopupKeyboardColumn(keyAttr.getInt(
R.styleable.Keyboard_Key_maxPopupKeyboardColumn, 5));
+
+ mKeyboard.mIconsSet.loadIcons(keyboardAttr);
+ mKeyboardTopPadding = getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_keyboardTopPadding, height, 0);
+ mKeyboardBottomPadding = getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_keyboardBottomPadding, height, 0);
} finally {
keyAttr.recycle();
keyboardAttr.recycle();
@@ -280,7 +331,7 @@ public class KeyboardParser {
} else {
Key key = new Key(mResources, row, mCurrentX, mCurrentY, parser, mKeyStyles);
if (DEBUG) Log.d(TAG, String.format("<%s%s keyLabel=%s code=%d popupCharacters=%s />",
- TAG_KEY, (key.mEnabled ? "" : " disabled"), key.mLabel, key.mCode,
+ TAG_KEY, (key.isEnabled() ? "" : " disabled"), key.mLabel, key.mCode,
Arrays.toString(key.mPopupCharacters)));
checkEndTag(TAG_KEY, parser);
keys.add(key);
@@ -300,18 +351,18 @@ public class KeyboardParser {
R.styleable.Keyboard);
if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap))
throw new IllegalAttribute(parser, "horizontalGap");
- final int defaultWidth = (row != null) ? row.mDefaultWidth : 0;
+ final int keyboardWidth = mKeyboard.getDisplayWidth();
final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth,
- mKeyboard.getDisplayWidth(), defaultWidth);
+ keyboardWidth, row.mDefaultWidth);
keyboardAttr.recycle();
final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard_Key);
int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyXPos, mKeyboard.getDisplayWidth(), mCurrentX);
+ R.styleable.Keyboard_Key_keyXPos, keyboardWidth, mCurrentX);
if (keyXPos < 0) {
// If keyXPos is negative, the actual x-coordinate will be display_width + keyXPos.
- keyXPos += mKeyboard.getDisplayWidth();
+ keyXPos += keyboardWidth;
}
checkEndTag(TAG_SPACER, parser);
@@ -430,13 +481,13 @@ public class KeyboardParser {
final TypedArray viewAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.KeyboardView);
try {
- final boolean modeMatched = matchInteger(a,
- R.styleable.Keyboard_Case_mode, id.mMode);
- final boolean webInputMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_webInput, id.mWebInput);
+ 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 settingsKeyMatched = matchBoolean(a,
+ final boolean hasSettingsKeyMatched = matchBoolean(a,
R.styleable.Keyboard_Case_hasSettingsKey, id.mHasSettingsKey);
final boolean f2KeyModeMatched = matchInteger(a,
R.styleable.Keyboard_Case_f2KeyMode, id.mF2KeyMode);
@@ -446,30 +497,26 @@ public class KeyboardParser {
R.styleable.Keyboard_Case_voiceKeyEnabled, id.mVoiceKeyEnabled);
final boolean voiceKeyMatched = matchBoolean(a,
R.styleable.Keyboard_Case_hasVoiceKey, id.mHasVoiceKey);
- final boolean colorSchemeMatched = matchInteger(viewAttr,
- R.styleable.KeyboardView_colorScheme, id.mColorScheme);
// 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 && webInputMatched && passwordInputMatched
- && settingsKeyMatched && f2KeyModeMatched && clobberSettingsKeyMatched
- && voiceEnabledMatched && voiceKeyMatched && colorSchemeMatched
- && imeActionMatched && languageCodeMatched && countryCodeMatched;
+ final boolean selected = modeMatched && navigateActionMatched && passwordInputMatched
+ && hasSettingsKeyMatched && f2KeyModeMatched && clobberSettingsKeyMatched
+ && voiceEnabledMatched && voiceKeyMatched && 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(KeyboardId.modeName(
- a.getInt(R.styleable.Keyboard_Case_mode, -1)), "mode"),
- textAttr(KeyboardId.colorSchemeName(
- viewAttr.getInt(
- R.styleable.KeyboardView_colorScheme, -1)), "colorSchemeName"),
- booleanAttr(a, R.styleable.Keyboard_Case_webInput, "webInput"),
+ 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(
@@ -478,8 +525,9 @@ public class KeyboardParser {
"clobberSettingsKey"),
booleanAttr(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"),
- textAttr(KeyboardId.imeOptionsName(
+ 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)));
@@ -506,7 +554,30 @@ public class KeyboardParser {
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) || a.getString(index).equals(value);
+ 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(XmlResourceParser parser, Row row, List<Key> keys)
@@ -544,25 +615,32 @@ public class KeyboardParser {
throw new NonEmptyTag(tag, parser);
}
+ private void startKeyboard() {
+ mCurrentY += mKeyboardTopPadding;
+ }
+
private void startRow(Row row) {
mCurrentX = 0;
+ setSpacer(mCurrentX, mHorizontalEdgesPadding);
mCurrentRow = row;
}
private void endRow() {
if (mCurrentRow == null)
throw new InflateException("orphant end row tag");
+ setSpacer(mCurrentX, mHorizontalEdgesPadding);
+ if (mCurrentX > mMaxRowWidth)
+ mMaxRowWidth = mCurrentX;
mCurrentY += mCurrentRow.mDefaultHeight;
mCurrentRow = null;
}
private void endKey(Key key) {
mCurrentX = key.mX - key.mGap / 2 + key.mWidth + key.mGap;
- if (mCurrentX > mMaxRowWidth)
- mMaxRowWidth = mCurrentX;
}
private void endKeyboard(int defaultVerticalGap) {
+ mCurrentY += mKeyboardBottomPadding;
mTotalHeight = mCurrentY - defaultVerticalGap;
}
@@ -574,15 +652,34 @@ public class KeyboardParser {
final TypedValue value = a.peekValue(index);
if (value == null)
return defValue;
- if (value.type == TypedValue.TYPE_DIMENSION) {
- return a.getDimensionPixelOffset(index, defValue);
- } else if (value.type == TypedValue.TYPE_FRACTION) {
+ if (isFractionValue(value)) {
// Round it to avoid values like 47.9999 from getting truncated
return Math.round(a.getFraction(index, base, base, defValue));
+ } else if (isDimensionValue(value)) {
+ return a.getDimensionPixelOffset(index, defValue);
+ } else if (isIntegerValue(value)) {
+ // For enum 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, XmlResourceParser parser) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java
index e015b5158..0cde4e5b5 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardShiftState.java
@@ -14,10 +14,12 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
+package com.android.inputmethod.keyboard.internal;
import android.util.Log;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+
public class KeyboardShiftState {
private static final String TAG = "KeyboardShiftState";
private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java
index 765750fbe..cc89579bb 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MiniKeyboardBuilder.java
@@ -14,15 +14,19 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.latin.R;
+package com.android.inputmethod.keyboard.internal;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.Rect;
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.keyboard.MiniKeyboard;
+import com.android.inputmethod.latin.R;
+
import java.util.List;
public class MiniKeyboardBuilder {
@@ -39,6 +43,7 @@ public class MiniKeyboardBuilder {
public final int mNumColumns;
public final int mLeftKeys;
public final int mRightKeys; // includes default key.
+ public int mTopPadding;
/**
* The object holding mini keyboard layout parameters.
@@ -49,6 +54,7 @@ public class MiniKeyboardBuilder {
* @param rowHeight mini keyboard row height in pixel, including vertical gap.
* @param coordXInParent coordinate x of the popup key in parent keyboard.
* @param parentKeyboardWidth parent keyboard width in pixel.
+ * parent keyboard.
*/
public MiniKeyboardLayoutParams(int numKeys, int maxColumns, int keyWidth, int rowHeight,
int coordXInParent, int parentKeyboardWidth) {
@@ -166,7 +172,7 @@ public class MiniKeyboardBuilder {
}
public int getY(int row) {
- return (mNumRows - 1 - row) * mRowHeight;
+ return (mNumRows - 1 - row) * mRowHeight + mTopPadding;
}
public int getRowFlags(int row) {
@@ -179,13 +185,26 @@ public class MiniKeyboardBuilder {
private boolean isTopRow(int rowCount) {
return rowCount == mNumRows - 1;
}
+
+ public void setTopPadding (int topPadding) {
+ mTopPadding = topPadding;
+ }
+
+ public int getKeyboardHeight() {
+ return mNumRows * mRowHeight + mTopPadding;
+ }
+
+ public int getKeyboardWidth() {
+ return mNumColumns * mKeyWidth;
+ }
}
public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey,
Keyboard parentKeyboard) {
final Context context = view.getContext();
mRes = context.getResources();
- final MiniKeyboard keyboard = new MiniKeyboard(context, layoutTemplateResId, null);
+ final MiniKeyboard keyboard = new MiniKeyboard(
+ context, layoutTemplateResId, parentKeyboard);
mKeyboard = keyboard;
mPopupCharacters = parentKey.mPopupCharacters;
@@ -195,11 +214,12 @@ public class MiniKeyboardBuilder {
keyWidth, parentKeyboard.getRowHeight(),
parentKey.mX + (parentKey.mWidth + parentKey.mGap) / 2 - keyWidth / 2,
view.getMeasuredWidth());
+ params.setTopPadding(keyboard.getVerticalGap());
mParams = params;
keyboard.setRowHeight(params.mRowHeight);
- keyboard.setHeight(params.mNumRows * params.mRowHeight);
- keyboard.setMinWidth(params.mNumColumns * params.mKeyWidth);
+ keyboard.setHeight(params.getKeyboardHeight());
+ keyboard.setMinWidth(params.getKeyboardWidth());
keyboard.setDefaultCoordX(params.getDefaultKeyCoordX() + params.mKeyWidth / 2);
}
@@ -216,7 +236,7 @@ public class MiniKeyboardBuilder {
paint = new Paint();
paint.setAntiAlias(true);
}
- final int labelSize = view.getLabelSizeAndSetPaint(label, 0, paint);
+ final int labelSize = view.getDefaultLabelSizeAndSetPaint(paint);
paint.setTextSize(labelSize);
if (bounds == null) bounds = new Rect();
paint.getTextBounds(label.toString(), 0, label.length(), bounds);
diff --git a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
index ebbc79a9e..dae73c4e4 100644
--- a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
@@ -14,10 +14,12 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
+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;
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index 01d9b5d2c..545b27fdc 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -14,7 +14,9 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
+package com.android.inputmethod.keyboard.internal;
+
+import com.android.inputmethod.keyboard.PointerTracker;
import java.util.LinkedList;
@@ -29,29 +31,28 @@ public class PointerTrackerQueue {
if (mQueue.lastIndexOf(tracker) < 0) {
return;
}
- LinkedList<PointerTracker> queue = mQueue;
+ 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 {
- t.onUpEventForRelease(t.getLastX(), t.getLastY(), eventTime);
- t.setAlreadyProcessed();
+ t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, true);
queue.remove(oldestPos);
}
}
}
public void releaseAllPointers(long eventTime) {
- releaseAllPointersExcept(null, eventTime);
+ releaseAllPointersExcept(null, eventTime, true);
}
- public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
+ public void releaseAllPointersExcept(PointerTracker tracker, long eventTime,
+ boolean updateReleasedKeyGraphics) {
for (PointerTracker t : mQueue) {
if (t == tracker)
continue;
- t.onUpEventForRelease(t.getLastX(), t.getLastY(), eventTime);
- t.setAlreadyProcessed();
+ t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, updateReleasedKeyGraphics);
}
mQueue.clear();
if (tracker != null)
@@ -62,7 +63,7 @@ public class PointerTrackerQueue {
mQueue.remove(tracker);
}
- public boolean isInSlidingKeyInput() {
+ public boolean isAnyInSlidingKeyInput() {
for (final PointerTracker tracker : mQueue) {
if (tracker.isInSlidingKeyInput())
return true;
diff --git a/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java b/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
index ff78ee5c9..8276f5d78 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PopupCharactersParser.java
@@ -14,13 +14,14 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.latin.R;
+package com.android.inputmethod.keyboard.internal;
import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.R;
/**
* String parser of popupCharacters attribute of Key.
@@ -28,16 +29,19 @@ import android.text.TextUtils;
* Each popup key text is one of the following:
* - A single letter (Letter)
* - Label optionally followed by keyOutputText or code (keyLabel|keyOutputText).
- * - Icon followed by keyOutputText or code (@drawable/icon|@integer/key_code)
+ * - 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 PopupCharactersParser {
+ private static final String TAG = PopupCharactersParser.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 + "drawable/";
+ private static final String PREFIX_ICON = PREFIX_AT + "icon/";
private static final String PREFIX_CODE = PREFIX_AT + "integer/";
private PopupCharactersParser() {
@@ -150,13 +154,18 @@ public class PopupCharactersParser {
return Keyboard.CODE_DUMMY;
}
- public static Drawable getIcon(Resources res, String popupSpec) {
+ public static int getIconId(String popupSpec) {
if (hasIcon(popupSpec)) {
int end = popupSpec.indexOf(LABEL_END, PREFIX_ICON.length() + 1);
- int resId = getResourceId(res, popupSpec.substring(PREFIX_AT.length(), end));
- return res.getDrawable(resId);
+ final String iconId = popupSpec.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 null;
+ return KeyboardIconsSet.ICON_UNDEFINED;
}
private static int getResourceId(Resources res, String name) {
diff --git a/java/src/com/android/inputmethod/keyboard/Row.java b/java/src/com/android/inputmethod/keyboard/internal/Row.java
index 40d7e1472..06aadcc05 100644
--- a/java/src/com/android/inputmethod/keyboard/Row.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/Row.java
@@ -14,15 +14,16 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.latin.R;
+package com.android.inputmethod.keyboard.internal;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.Xml;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.R;
+
/**
* 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}
diff --git a/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
index ba15624f0..6617b917f 100644
--- a/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
+package com.android.inputmethod.keyboard.internal;
import android.util.Log;
diff --git a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/internal/SlidingLocaleDrawable.java
index ad8b0d623..ef3ea4c12 100644
--- a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SlidingLocaleDrawable.java
@@ -14,40 +14,41 @@
* the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
+package com.android.inputmethod.keyboard.internal;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
-import android.graphics.PixelFormat;
import android.graphics.Paint.Align;
+import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.view.ViewConfiguration;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.LatinKeyboard;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+
/**
* Animation to be displayed on the spacebar preview popup when switching languages by swiping the
* spacebar. It draws the current, previous and next languages and moves them by the delta of touch
* movement on the spacebar.
*/
public class SlidingLocaleDrawable extends Drawable {
-
- private final Context mContext;
- private final Resources mRes;
+ private static final int SLIDE_SPEED_MULTIPLIER_RATIO = 150;
private final int mWidth;
private final int mHeight;
private final Drawable mBackground;
+ private final int mSpacebarTextColor;
private final TextPaint mTextPaint;
private final int mMiddleX;
- private final Drawable mLeftDrawable;
- private final Drawable mRightDrawable;
+ private final boolean mDrawArrows;
private final int mThreshold;
+
private int mDiff;
private boolean mHitThreshold;
private String mCurrentLanguage;
@@ -55,42 +56,37 @@ public class SlidingLocaleDrawable extends Drawable {
private String mPrevLanguage;
public SlidingLocaleDrawable(Context context, Drawable background, int width, int height) {
- mContext = context;
- mRes = context.getResources();
mBackground = background;
- Keyboard.setDefaultBounds(mBackground);
+ Keyboard.setDefaultBounds(background);
mWidth = width;
mHeight = height;
final TextPaint textPaint = new TextPaint();
- textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18));
- textPaint.setColor(R.color.latinkeyboard_transparent);
- textPaint.setTextAlign(Align.CENTER);
- textPaint.setAlpha(LatinKeyboard.OPACITY_FULLY_OPAQUE);
+ textPaint.setTextSize(LatinKeyboard.getTextSizeFromTheme(
+ context.getTheme(), android.R.style.TextAppearance_Medium, 18));
+ textPaint.setColor(Color.TRANSPARENT);
textPaint.setAntiAlias(true);
mTextPaint = textPaint;
- mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2;
- final Resources res = mRes;
- mLeftDrawable = res.getDrawable(
- R.drawable.sym_keyboard_feedback_language_arrows_left);
- mRightDrawable = res.getDrawable(
- R.drawable.sym_keyboard_feedback_language_arrows_right);
- mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ mMiddleX = (background != null) ? (mWidth - mBackground.getIntrinsicWidth()) / 2 : 0;
+
+ final TypedArray a = context.obtainStyledAttributes(
+ null, R.styleable.KeyboardView, R.attr.keyboardViewStyle, R.style.KeyboardView);
+ mSpacebarTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
+ final int spacebarPreviewBackrgound = a.getResourceId(
+ R.styleable.KeyboardView_keyPreviewSpacebarBackground, 0);
+ // If spacebar preview background is transparent, we need not draw arrows.
+ mDrawArrows = (spacebarPreviewBackrgound != R.drawable.transparent);
+ a.recycle();
+
+ mThreshold = ViewConfiguration.get(context).getScaledTouchSlop();
}
- private int getTextSizeFromTheme(int style, int defValue) {
- TypedArray array = mContext.getTheme().obtainStyledAttributes(
- style, new int[] { android.R.attr.textSize });
- int textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue);
- return textSize;
- }
-
- void setDiff(int diff) {
+ public void setDiff(int diff) {
if (diff == Integer.MAX_VALUE) {
mHitThreshold = false;
mCurrentLanguage = null;
return;
}
- mDiff = diff;
+ mDiff = Math.max(diff, diff * SLIDE_SPEED_MULTIPLIER_RATIO / 100);
if (mDiff > mWidth) mDiff = mWidth;
if (mDiff < -mWidth) mDiff = -mWidth;
if (Math.abs(mDiff) > mThreshold) mHitThreshold = true;
@@ -106,8 +102,6 @@ public class SlidingLocaleDrawable extends Drawable {
final int width = mWidth;
final int height = mHeight;
final int diff = mDiff;
- final Drawable lArrow = mLeftDrawable;
- final Drawable rArrow = mRightDrawable;
canvas.clipRect(0, 0, width, height);
if (mCurrentLanguage == null) {
SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance();
@@ -115,19 +109,20 @@ public class SlidingLocaleDrawable extends Drawable {
mNextLanguage = subtypeSwitcher.getNextInputLanguageName();
mPrevLanguage = subtypeSwitcher.getPreviousInputLanguageName();
}
- // Draw language text with shadow
+ // Draw language text.
final float baseline = mHeight * LatinKeyboard.SPACEBAR_LANGUAGE_BASELINE
- paint.descent();
- paint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text));
+ paint.setColor(mSpacebarTextColor);
+ paint.setTextAlign(Align.CENTER);
canvas.drawText(mCurrentLanguage, width / 2 + diff, baseline, paint);
canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint);
canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint);
-
- Keyboard.setDefaultBounds(lArrow);
- rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width,
- rArrow.getIntrinsicHeight());
- lArrow.draw(canvas);
- rArrow.draw(canvas);
+ if (mDrawArrows) {
+ paint.setTextAlign(Align.LEFT);
+ canvas.drawText(LatinKeyboard.ARROW_LEFT, 0, baseline, paint);
+ paint.setTextAlign(Align.RIGHT);
+ canvas.drawText(LatinKeyboard.ARROW_RIGHT, width, baseline, paint);
+ }
}
if (mBackground != null) {
canvas.translate(mMiddleX, 0);
diff --git a/java/src/com/android/inputmethod/latin/AccessibilityUtils.java b/java/src/com/android/inputmethod/latin/AccessibilityUtils.java
deleted file mode 100644
index cd3f9e0ad..000000000
--- a/java/src/com/android/inputmethod/latin/AccessibilityUtils.java
+++ /dev/null
@@ -1,211 +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.latin;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.TypedArray;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Utility functions for accessibility support.
- */
-public class AccessibilityUtils {
- /** Shared singleton instance. */
- private static final AccessibilityUtils sInstance = new AccessibilityUtils();
- private /* final */ LatinIME mService;
- private /* final */ AccessibilityManager mAccessibilityManager;
- private /* final */ Map<Integer, CharSequence> mDescriptions;
-
- /**
- * Returns a shared instance of AccessibilityUtils.
- *
- * @return A shared instance of AccessibilityUtils.
- */
- public static AccessibilityUtils getInstance() {
- return sInstance;
- }
-
- /**
- * Initializes (or re-initializes) the shared instance of AccessibilityUtils
- * with the specified parent service and preferences.
- *
- * @param service The parent input method service.
- * @param prefs The parent preferences.
- */
- public static void init(LatinIME service, SharedPreferences prefs) {
- sInstance.initialize(service, prefs);
- }
-
- private AccessibilityUtils() {
- // This class is not publicly instantiable.
- }
-
- /**
- * Initializes (or re-initializes) with the specified parent service and
- * preferences.
- *
- * @param service The parent input method service.
- * @param prefs The parent preferences.
- */
- private void initialize(LatinIME service, SharedPreferences prefs) {
- mService = service;
- mAccessibilityManager = (AccessibilityManager) service.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- mDescriptions = null;
- }
-
- /**
- * Returns true if accessibility is enabled.
- *
- * @return {@code true} if accessibility is enabled.
- */
- public boolean isAccessibilityEnabled() {
- return mAccessibilityManager.isEnabled();
- }
-
- /**
- * Speaks a key's action after it has been released. Does not speak letter
- * keys since typed keys are already spoken aloud by TalkBack.
- * <p>
- * No-op if accessibility is not enabled.
- * </p>
- *
- * @param primaryCode The primary code of the released key.
- * @param switcher The input method's {@link KeyboardSwitcher}.
- */
- public void onRelease(int primaryCode, KeyboardSwitcher switcher) {
- if (!isAccessibilityEnabled()) {
- return;
- }
-
- int resId = -1;
-
- switch (primaryCode) {
- case Keyboard.CODE_SHIFT: {
- if (switcher.isShiftedOrShiftLocked()) {
- resId = R.string.description_shift_on;
- } else {
- resId = R.string.description_shift_off;
- }
- break;
- }
-
- case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: {
- if (switcher.isAlphabetMode()) {
- resId = R.string.description_symbols_off;
- } else {
- resId = R.string.description_symbols_on;
- }
- break;
- }
- }
-
- if (resId >= 0) {
- speakDescription(mService.getResources().getText(resId));
- }
- }
-
- /**
- * Speaks a key's description for accessibility. If a key has an explicit
- * description defined in keycodes.xml, that will be used. Otherwise, if the
- * key is a Unicode character, then its character will be used.
- * <p>
- * No-op if accessibility is not enabled.
- * </p>
- *
- * @param primaryCode The primary code of the pressed key.
- * @param switcher The input method's {@link KeyboardSwitcher}.
- */
- public void onPress(int primaryCode, KeyboardSwitcher switcher) {
- if (!isAccessibilityEnabled()) {
- return;
- }
-
- // TODO Use the current keyboard state to read "Switch to symbols"
- // instead of just "Symbols" (and similar for shift key).
- CharSequence description = describeKey(primaryCode);
- if (description == null && Character.isDefined((char) primaryCode)) {
- description = Character.toString((char) primaryCode);
- }
-
- if (description != null) {
- speakDescription(description);
- }
- }
-
- /**
- * Returns a text description for a given key code. If the key does not have
- * an explicit description, returns <code>null</code>.
- *
- * @param keyCode An integer key code.
- * @return A {@link CharSequence} describing the key or <code>null</code> if
- * no description is available.
- */
- private CharSequence describeKey(int keyCode) {
- // If not loaded yet, load key descriptions from XML file.
- if (mDescriptions == null) {
- mDescriptions = loadDescriptions();
- }
-
- return mDescriptions.get(keyCode);
- }
-
- /**
- * Loads key descriptions from resources.
- */
- private Map<Integer, CharSequence> loadDescriptions() {
- final Map<Integer, CharSequence> descriptions = new HashMap<Integer, CharSequence>();
- final TypedArray array = mService.getResources().obtainTypedArray(R.array.key_descriptions);
-
- // Key descriptions are stored as a key code followed by a string.
- for (int i = 0; i < array.length() - 1; i += 2) {
- int code = array.getInteger(i, 0);
- CharSequence desc = array.getText(i + 1);
-
- descriptions.put(code, desc);
- }
-
- array.recycle();
-
- return descriptions;
- }
-
- /**
- * Sends a character sequence to be read aloud.
- *
- * @param description The {@link CharSequence} to be read aloud.
- */
- private void speakDescription(CharSequence description) {
- // TODO We need to add an AccessibilityEvent type for IMEs.
- final AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
- event.setPackageName(mService.getPackageName());
- event.setClassName(getClass().getName());
- event.setAddedCount(description.length());
- event.getText().add(description);
-
- mAccessibilityManager.sendAccessibilityEvent(event);
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/AssetFileAddress.java b/java/src/com/android/inputmethod/latin/AssetFileAddress.java
new file mode 100644
index 000000000..074ecacc5
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/AssetFileAddress.java
@@ -0,0 +1,52 @@
+/*
+ * 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 java.io.File;
+
+/**
+ * Immutable class to hold the address of an asset.
+ * As opposed to a normal file, an asset is usually represented as a contiguous byte array in
+ * the package file. Open it correctly thus requires the name of the package it is in, but
+ * also the offset in the file and the length of this data. This class encapsulates these three.
+ */
+class AssetFileAddress {
+ public final String mFilename;
+ public final long mOffset;
+ public final long mLength;
+
+ public AssetFileAddress(final String filename, final long offset, final long length) {
+ mFilename = filename;
+ mOffset = offset;
+ mLength = length;
+ }
+
+ public static AssetFileAddress makeFromFileName(final String filename) {
+ if (null == filename) return null;
+ File f = new File(filename);
+ if (null == f || !f.isFile()) return null;
+ return new AssetFileAddress(filename, 0l, f.length());
+ }
+
+ public static AssetFileAddress makeFromFileNameAndOffset(final String filename,
+ final long offset, final long length) {
+ if (null == filename) return null;
+ File f = new File(filename);
+ if (null == f || !f.isFile()) return null;
+ return new AssetFileAddress(filename, offset, length);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
index 092f7ad63..d3119792c 100644
--- a/java/src/com/android/inputmethod/latin/AutoCorrection.java
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -48,7 +48,7 @@ public class AutoCorrection {
}
public void updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries,
- WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] priorities,
+ WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores,
CharSequence typedWord, double autoCorrectionThreshold, int correctionMode,
CharSequence quickFixedWord, CharSequence whitelistedWord) {
if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) {
@@ -62,7 +62,7 @@ public class AutoCorrection {
mHasAutoCorrection = true;
mAutoCorrectionWord = quickFixedWord;
} else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, correctionMode,
- priorities, typedWord, autoCorrectionThreshold)) {
+ sortedScores, typedWord, autoCorrectionThreshold)) {
mHasAutoCorrection = true;
mAutoCorrectionWord = suggestions.get(0);
}
@@ -114,13 +114,13 @@ public class AutoCorrection {
}
private boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer,
- ArrayList<CharSequence> suggestions, int correctionMode, int[] priorities,
+ ArrayList<CharSequence> suggestions, int correctionMode, int[] sortedScores,
CharSequence typedWord, double autoCorrectionThreshold) {
if (wordComposer.size() > 1 && (correctionMode == Suggest.CORRECTION_FULL
|| correctionMode == Suggest.CORRECTION_FULL_BIGRAM)
- && typedWord != null && suggestions.size() > 0 && priorities.length > 0) {
+ && typedWord != null && suggestions.size() > 0 && sortedScores.length > 0) {
final CharSequence autoCorrectionCandidate = suggestions.get(0);
- final int autoCorrectionCandidateScore = priorities[0];
+ final int autoCorrectionCandidateScore = 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(
diff --git a/java/src/com/android/inputmethod/latin/AutoDictionary.java b/java/src/com/android/inputmethod/latin/AutoDictionary.java
index 54c6f309c..460930f16 100644
--- a/java/src/com/android/inputmethod/latin/AutoDictionary.java
+++ b/java/src/com/android/inputmethod/latin/AutoDictionary.java
@@ -27,7 +27,6 @@ import android.provider.BaseColumns;
import android.util.Log;
import java.util.HashMap;
-import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -42,13 +41,8 @@ public class AutoDictionary extends ExpandableDictionary {
static final int FREQUENCY_FOR_PICKED = 3;
// Weight added to a user typing a new word that doesn't get corrected (or is reverted)
static final int FREQUENCY_FOR_TYPED = 1;
- // A word that is frequently typed and gets promoted to the user dictionary, uses this
- // frequency.
- static final int FREQUENCY_FOR_AUTO_ADD = 250;
// If the user touches a typed word 2 times or more, it will become valid.
private static final int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED;
- // If the user touches a typed word 4 times or more, it will be added to the user dict.
- private static final int PROMOTION_THRESHOLD = 4 * FREQUENCY_FOR_PICKED;
private LatinIME mIme;
// Locale for which this auto dictionary is storing words
@@ -152,11 +146,6 @@ public class AutoDictionary extends ExpandableDictionary {
freq = freq < 0 ? addFrequency : freq + addFrequency;
super.addWord(word, freq);
- if (freq >= PROMOTION_THRESHOLD) {
- mIme.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD);
- freq = 0;
- }
-
synchronized (mPendingWritesLock) {
// Write a null frequency if it is to be deleted from the db
mPendingWrites.put(word, freq == 0 ? null : new Integer(freq));
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 08ddd25fa..9748d6006 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -21,10 +21,7 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.ProximityInfo;
import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.util.Log;
-import java.io.File;
import java.util.Arrays;
/**
@@ -32,8 +29,11 @@ import java.util.Arrays;
*/
public class BinaryDictionary extends Dictionary {
+ public static final String DICTIONARY_PACK_AUTHORITY =
+ "com.android.inputmethod.latin.dictionarypack";
+
/**
- * There is difference between what java and native code can handle.
+ * There is a difference between what java and native code can handle.
* This value should only be used in BinaryDictionary.java
* It is necessary to keep it at this value because some languages e.g. German have
* really long words.
@@ -41,101 +41,59 @@ public class BinaryDictionary extends Dictionary {
public static final int MAX_WORD_LENGTH = 48;
public static final int MAX_WORDS = 18;
+ @SuppressWarnings("unused")
private static final String TAG = "BinaryDictionary";
private static final int MAX_PROXIMITY_CHARS_SIZE = ProximityInfo.MAX_PROXIMITY_CHARS_SIZE;
private static final int MAX_BIGRAMS = 60;
private static final int TYPED_LETTER_MULTIPLIER = 2;
- private static final BinaryDictionary sInstance = new BinaryDictionary();
private int mDicTypeId;
private int mNativeDict;
- private long mDictLength;
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];
- private final int[] mFrequencies = new int[MAX_WORDS];
- private final int[] mFrequencies_bigrams = new int[MAX_BIGRAMS];
+ private final int[] mScores = new int[MAX_WORDS];
+ private final int[] mBigramScores = new int[MAX_BIGRAMS];
private final KeyboardSwitcher mKeyboardSwitcher = KeyboardSwitcher.getInstance();
- private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance();
-
- private static class Flags {
- private static class FlagEntry {
- public final String mName;
- public final int mValue;
- public FlagEntry(String name, int value) {
- mName = name;
- mValue = value;
- }
- }
- public static final FlagEntry[] ALL_FLAGS = {
- // Here should reside all flags that trigger some special processing
- // These *must* match the definition in UnigramDictionary enum in
- // unigram_dictionary.h so please update both at the same time.
- new FlagEntry("requiresGermanUmlautProcessing", 0x1)
- };
- }
- private int mFlags = 0;
- private BinaryDictionary() {
- }
+ public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING =
+ new Flag(R.bool.config_require_umlaut_processing, 0x1);
- /**
- * Initialize a dictionary from a raw resource file
- * @param context application context for reading resources
- * @param resId the resource containing the raw binary dictionary
- * @return initialized instance of BinaryDictionary
- */
- public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) {
- synchronized (sInstance) {
- sInstance.closeInternal();
- try {
- final AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId);
- if (afd == null) {
- Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
- return null;
- }
- final String sourceDir = context.getApplicationInfo().sourceDir;
- final File packagePath = new File(sourceDir);
- // TODO: Come up with a way to handle a directory.
- if (!packagePath.isFile()) {
- Log.e(TAG, "sourceDir is not a file: " + sourceDir);
- return null;
- }
- sInstance.loadDictionary(sourceDir, afd.getStartOffset(), afd.getLength());
- sInstance.mDicTypeId = dicTypeId;
- } catch (android.content.res.Resources.NotFoundException e) {
- Log.e(TAG, "Could not find the resource. resId=" + resId);
- return null;
- }
- }
- sInstance.initFlags();
- return sInstance;
- }
+ // Can create a new flag from extravalue :
+ // public static final Flag FLAG_MYFLAG =
+ // new Flag("my_flag", 0x02);
- /* package for test */ static BinaryDictionary initDictionary(File dictionary, long startOffset,
- long length, int dicTypeId) {
- synchronized (sInstance) {
- sInstance.closeInternal();
- if (dictionary.isFile()) {
- sInstance.loadDictionary(dictionary.getAbsolutePath(), startOffset, length);
- sInstance.mDicTypeId = dicTypeId;
- } else {
- Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
- return null;
- }
- }
- return sInstance;
- }
+ private static final Flag[] ALL_FLAGS = {
+ // Here should reside all flags that trigger some special processing
+ // These *must* match the definition in UnigramDictionary enum in
+ // unigram_dictionary.h so please update both at the same time.
+ FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING,
+ };
- private void initFlags() {
- int flags = 0;
- for (Flags.FlagEntry entry : Flags.ALL_FLAGS) {
- if (mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(entry.mName))
- flags |= entry.mValue;
- }
- mFlags = flags;
+ private int mFlags = 0;
+
+ /**
+ * Constructor for the binary dictionary. This is supposed to be called from the
+ * dictionary factory.
+ * All implementations should pass null into flagArray, except for testing purposes.
+ * @param context the context to access the environment from.
+ * @param filename the name of the file to read through native code.
+ * @param offset the offset of the dictionary data within the file.
+ * @param length the length of the binary data.
+ * @param flagArray the flags to limit the dictionary to, or null for default.
+ */
+ public BinaryDictionary(final Context context,
+ final String filename, final long offset, final long length, Flag[] flagArray) {
+ // Note: at the moment a binary dictionary is always of the "main" type.
+ // Initializing this here will help transitioning out of the scheme where
+ // the Suggest class knows everything about every single dictionary.
+ mDicTypeId = Suggest.DIC_MAIN;
+ // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter
+ mFlags = Flag.initFlags(null == flagArray ? ALL_FLAGS : flagArray, context,
+ SubtypeSwitcher.getInstance());
+ loadDictionary(filename, offset, length);
}
static {
@@ -149,16 +107,15 @@ public class BinaryDictionary extends Dictionary {
private native boolean isValidWordNative(int nativeData, char[] word, int wordLength);
private native int getSuggestionsNative(int dict, int proximityInfo, int[] xCoordinates,
int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars,
- int[] frequencies);
+ int[] scores);
private native int getBigramsNative(int dict, char[] prevWord, int prevWordLength,
- int[] inputCodes, int inputCodesLength, char[] outputChars, int[] frequencies,
+ int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores,
int maxWordLength, int maxBigrams, int maxAlternatives);
private final void loadDictionary(String path, long startOffset, long length) {
mNativeDict = openNative(path, startOffset, length,
- TYPED_LETTER_MULTIPLIER, FULL_WORD_FREQ_MULTIPLIER,
+ TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER,
MAX_WORD_LENGTH, MAX_WORDS, MAX_PROXIMITY_CHARS_SIZE);
- mDictLength = length;
}
@Override
@@ -168,27 +125,32 @@ public class BinaryDictionary extends Dictionary {
char[] chars = previousWord.toString().toCharArray();
Arrays.fill(mOutputChars_bigrams, (char) 0);
- Arrays.fill(mFrequencies_bigrams, 0);
+ Arrays.fill(mBigramScores, 0);
int codesSize = codes.size();
+ if (codesSize <= 0) {
+ // Do not return bigrams from BinaryDictionary when nothing was typed.
+ // Only use user-history bigrams (or whatever other bigram dictionaries decide).
+ return;
+ }
Arrays.fill(mInputCodes, -1);
int[] alternatives = codes.getCodesAt(0);
System.arraycopy(alternatives, 0, mInputCodes, 0,
Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE));
int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize,
- mOutputChars_bigrams, mFrequencies_bigrams, MAX_WORD_LENGTH, MAX_BIGRAMS,
+ mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS,
MAX_PROXIMITY_CHARS_SIZE);
for (int j = 0; j < count; ++j) {
- if (mFrequencies_bigrams[j] < 1) break;
+ if (mBigramScores[j] < 1) break;
final int start = j * MAX_WORD_LENGTH;
int len = 0;
while (len < MAX_WORD_LENGTH && mOutputChars_bigrams[start + len] != 0) {
++len;
}
if (len > 0) {
- callback.addWord(mOutputChars_bigrams, start, len, mFrequencies_bigrams[j],
+ callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j],
mDicTypeId, DataType.BIGRAM);
}
}
@@ -197,17 +159,17 @@ public class BinaryDictionary extends Dictionary {
@Override
public void getWords(final WordComposer codes, final WordCallback callback) {
final int count = getSuggestions(codes, mKeyboardSwitcher.getLatinKeyboard(),
- mOutputChars, mFrequencies);
+ mOutputChars, mScores);
for (int j = 0; j < count; ++j) {
- if (mFrequencies[j] < 1) break;
+ if (mScores[j] < 1) break;
final int start = j * MAX_WORD_LENGTH;
int len = 0;
while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) {
++len;
}
if (len > 0) {
- callback.addWord(mOutputChars, start, len, mFrequencies[j], mDicTypeId,
+ callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId,
DataType.UNIGRAM);
}
}
@@ -218,7 +180,7 @@ public class BinaryDictionary extends Dictionary {
}
/* package for test */ int getSuggestions(final WordComposer codes, final Keyboard keyboard,
- char[] outputChars, int[] frequencies) {
+ char[] outputChars, int[] scores) {
if (!isValidDictionary()) return -1;
final int codesSize = codes.size();
@@ -232,12 +194,13 @@ public class BinaryDictionary extends Dictionary {
Math.min(alternatives.length, MAX_PROXIMITY_CHARS_SIZE));
}
Arrays.fill(outputChars, (char) 0);
- Arrays.fill(frequencies, 0);
+ Arrays.fill(scores, 0);
+ final int proximityInfo = keyboard == null ? 0 : keyboard.getProximityInfo();
return getSuggestionsNative(
- mNativeDict, keyboard.getProximityInfo(),
+ mNativeDict, proximityInfo,
codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize,
- mFlags, outputChars, frequencies);
+ mFlags, outputChars, scores);
}
@Override
@@ -247,10 +210,6 @@ public class BinaryDictionary extends Dictionary {
return isValidWordNative(mNativeDict, chars, chars.length);
}
- public long getSize() {
- return mDictLength; // This value is initialized in loadDictionary()
- }
-
@Override
public synchronized void close() {
closeInternal();
@@ -260,7 +219,6 @@ public class BinaryDictionary extends Dictionary {
if (mNativeDict != 0) {
closeNative(mNativeDict);
mNativeDict = 0;
- mDictLength = 0;
}
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
new file mode 100644
index 000000000..76a230f82
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -0,0 +1,151 @@
+/*
+ * 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.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.net.Uri;
+import android.text.TextUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Group class for static methods to help with creation and getting of the binary dictionary
+ * file from the dictionary provider
+ */
+public class BinaryDictionaryFileDumper {
+ /**
+ * The size of the temporary buffer to copy files.
+ */
+ static final int FILE_READ_BUFFER_SIZE = 1024;
+
+ // Prevents this class to be accidentally instantiated.
+ private BinaryDictionaryFileDumper() {
+ }
+
+ /**
+ * Generates a file name that matches the locale passed as an argument.
+ * The file name is basically the result of the .toString() method, except we replace
+ * any @File.separator with an underscore to avoid generating a file name that may not
+ * be created.
+ * @param locale the locale for which to get the file name
+ * @param context the context to use for getting the directory
+ * @return the name of the file to be created
+ */
+ private static String getCacheFileNameForLocale(Locale locale, Context context) {
+ // The following assumes two things :
+ // 1. That File.separator is not the same character as "_"
+ // I don't think any android system will ever use "_" as a path separator
+ // 2. That no two locales differ by only a File.separator versus a "_"
+ // Since "_" can't be part of locale components this should be safe.
+ // Examples:
+ // en -> en
+ // en_US_POSIX -> en_US_POSIX
+ // en__foo/bar -> en__foo_bar
+ final String[] separator = { File.separator };
+ final String[] empty = { "_" };
+ final CharSequence basename = TextUtils.replace(locale.toString(), separator, empty);
+ return context.getFilesDir() + File.separator + basename;
+ }
+
+ /**
+ * Return for a given locale the provider URI to query to get the dictionary.
+ */
+ public static Uri getProviderUri(Locale locale) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath(
+ locale.toString()).build();
+ }
+
+ /**
+ * Queries a content provider for dictionary data for some locale and returns the file addresses
+ *
+ * This will query a content provider for dictionary data for a given locale, and return
+ * the addresses of a file set the members of which are suitable to be mmap'ed. It will copy
+ * them to local storage if needed.
+ * It should also check the dictionary versions to avoid unnecessary copies but this is
+ * still in TODO state.
+ * This will make the data from the content provider the cached dictionary for this locale,
+ * overwriting any previous cached data.
+ * @returns the addresses of the files, or null if no data could be obtained.
+ * @throw FileNotFoundException if the provider returns non-existent data.
+ * @throw IOException if the provider-returned data could not be read.
+ */
+ public static List<AssetFileAddress> getDictSetFromContentProvider(Locale locale,
+ Context context) throws FileNotFoundException, IOException {
+ // TODO: check whether the dictionary is the same or not and if it is, return the cached
+ // file.
+ // TODO: This should be able to read a number of files from the dictionary pack, copy
+ // them all and return them.
+ final ContentResolver resolver = context.getContentResolver();
+ final Uri dictionaryPackUri = getProviderUri(locale);
+ final AssetFileDescriptor afd = resolver.openAssetFileDescriptor(dictionaryPackUri, "r");
+ if (null == afd) return null;
+ final String fileName =
+ copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context));
+ return Arrays.asList(AssetFileAddress.makeFromFileName(fileName));
+ }
+
+ /**
+ * Accepts a file as dictionary data for some locale and returns the name of a file.
+ *
+ * This will make the data in the input file the cached dictionary for this locale, overwriting
+ * any previous cached data.
+ */
+ public static String getDictionaryFileFromFile(String fileName, Locale locale,
+ Context context) throws FileNotFoundException, IOException {
+ return copyFileTo(new FileInputStream(fileName), getCacheFileNameForLocale(locale,
+ context));
+ }
+
+ /**
+ * Accepts a resource number as dictionary data for some locale and returns the name of a file.
+ *
+ * This will make the resource the cached dictionary for this locale, overwriting any previous
+ * cached data.
+ */
+ public static String getDictionaryFileFromResource(int resource, Locale locale,
+ Context context) throws FileNotFoundException, IOException {
+ return copyFileTo(context.getResources().openRawResource(resource),
+ getCacheFileNameForLocale(locale, context));
+ }
+
+ /**
+ * Copies the data in an input stream to a target file, creating the file if necessary and
+ * overwriting it if it already exists.
+ * @param input the stream to be copied.
+ * @param outputFileName the name of a file to copy the data to. It is created if necessary.
+ */
+ private static String copyFileTo(final InputStream input, final String outputFileName)
+ throws FileNotFoundException, IOException {
+ final byte[] buffer = new byte[FILE_READ_BUFFER_SIZE];
+ final FileOutputStream output = new FileOutputStream(outputFileName);
+ for (int readBytes = input.read(buffer); readBytes >= 0; readBytes = input.read(buffer))
+ output.write(buffer, 0, readBytes);
+ input.close();
+ return outputFileName;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
new file mode 100644
index 000000000..7ce92920d
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -0,0 +1,97 @@
+/*
+ * 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.res.AssetFileDescriptor;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Helper class to get the address of a mmap'able dictionary file.
+ */
+class BinaryDictionaryGetter {
+
+ /**
+ * Used for Log actions from this class
+ */
+ private static final String TAG = BinaryDictionaryGetter.class.getSimpleName();
+
+ // Prevents this from being instantiated
+ private BinaryDictionaryGetter() {}
+
+ /**
+ * Returns a file address from a resource, or null if it cannot be opened.
+ */
+ private static AssetFileAddress loadFallbackResource(Context context, int fallbackResId) {
+ final AssetFileDescriptor afd = context.getResources().openRawResourceFd(fallbackResId);
+ if (afd == null) {
+ Log.e(TAG, "Found the resource but cannot read it. Is it compressed? resId="
+ + fallbackResId);
+ return null;
+ }
+ return AssetFileAddress.makeFromFileNameAndOffset(
+ context.getApplicationInfo().sourceDir, afd.getStartOffset(), afd.getLength());
+ }
+
+ /**
+ * Returns a list of file addresses for a given locale, trying relevant methods in order.
+ *
+ * Tries to get binary dictionaries from various sources, in order:
+ * - Uses a private method of getting a private dictionaries, as implemented by the
+ * PrivateBinaryDictionaryGetter class.
+ * If that fails:
+ * - Uses a content provider to get a public dictionary set, as per the protocol described
+ * in BinaryDictionaryFileDumper.
+ * If that fails:
+ * - Gets a file name from the fallback resource passed as an argument.
+ * If that fails:
+ * - Returns null.
+ * @return The address of a valid file, or null.
+ */
+ public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context,
+ int fallbackResId) {
+ // Try first to query a private package signed the same way for private files.
+ final List<AssetFileAddress> privateFiles =
+ PrivateBinaryDictionaryGetter.getDictionaryFiles(locale, context);
+ if (null != privateFiles) {
+ return privateFiles;
+ } else {
+ try {
+ // If that was no-go, try to find a publicly exported dictionary.
+ List<AssetFileAddress> listFromContentProvider =
+ BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
+ if (null != listFromContentProvider) {
+ return listFromContentProvider;
+ }
+ // If the list is null, fall through and return the fallback
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Unable to create dictionary file from provider for locale "
+ + locale.toString() + ": falling back to internal dictionary");
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to read source data for locale "
+ + locale.toString() + ": falling back to internal dictionary");
+ }
+ return Arrays.asList(loadFallbackResource(context, fallbackResId));
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index c52f6b2c4..565b01d5a 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -16,17 +16,17 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Typeface;
-import android.os.Handler;
+import android.graphics.drawable.Drawable;
import android.os.Message;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
+import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.BackgroundColorSpan;
import android.text.style.CharacterStyle;
@@ -40,54 +40,95 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
+import com.android.inputmethod.compat.FrameLayoutCompatUtils;
+import com.android.inputmethod.compat.LinearLayoutCompatUtils;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+
import java.util.ArrayList;
import java.util.List;
public class CandidateView extends LinearLayout implements OnClickListener, OnLongClickListener {
+ public interface Listener {
+ public boolean addWordToDictionary(String word);
+ public void pickSuggestionManually(int index, CharSequence word);
+ }
+
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
- private static final int MAX_SUGGESTIONS = 16;
+ // The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
+ private static final int MAX_SUGGESTIONS = 18;
+ private static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
+ private static final int MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT;
private static final boolean DBG = LatinImeLogger.sDBG;
- private final ArrayList<View> mWords = new ArrayList<View>();
- private final boolean mConfigCandidateHighlightFontColorEnabled;
+ private final ViewGroup mCandidatesStrip;
+ private final int mCandidateCountInStrip;
+ private static final int DEFAULT_CANDIDATE_COUNT_IN_STRIP = 3;
+ private final ViewGroup mCandidatesPaneControl;
+ private final TextView mExpandCandidatesPane;
+ private final TextView mCloseCandidatesPane;
+ private ViewGroup mCandidatesPane;
+ private ViewGroup mCandidatesPaneContainer;
+ private View mKeyboardView;
+
+ private final ArrayList<TextView> mWords = new ArrayList<TextView>();
+ private final ArrayList<TextView> mInfos = new ArrayList<TextView>();
+ private final ArrayList<View> mDividers = new ArrayList<View>();
+
+ private final int mCandidateStripHeight;
private final CharacterStyle mInvertedForegroundColorSpan;
private final CharacterStyle mInvertedBackgroundColorSpan;
- private final int mColorNormal;
- private final int mColorRecommended;
- private final int mColorOther;
+ private final int mAutoCorrectHighlight;
+ private static final int AUTO_CORRECT_BOLD = 0x01;
+ private static final int AUTO_CORRECT_UNDERLINE = 0x02;
+ private static final int AUTO_CORRECT_INVERT = 0x04;
+ private final int mColorTypedWord;
+ private final int mColorAutoCorrect;
+ private final int mColorSuggestedCandidate;
+
private final PopupWindow mPreviewPopup;
private final TextView mPreviewText;
- private LatinIME mService;
+ private final View mTouchToSave;
+ private final TextView mWordToSave;
+
+ private Listener mListener;
private SuggestedWords mSuggestions = SuggestedWords.EMPTY;
private boolean mShowingAutoCorrectionInverted;
private boolean mShowingAddToDictionary;
- private final UiHandler mHandler = new UiHandler();
+ private final CandidateViewLayoutParams mParams;
+ private static final int PUNCTUATIONS_IN_STRIP = 6;
+ private static final float MIN_TEXT_XSCALE = 0.75f;
+
+ private final UiHandler mHandler = new UiHandler(this);
- private class UiHandler extends Handler {
+ private static class UiHandler extends StaticInnerHandlerWrapper<CandidateView> {
private static final int MSG_HIDE_PREVIEW = 0;
private static final int MSG_UPDATE_SUGGESTION = 1;
private static final long DELAY_HIDE_PREVIEW = 1000;
private static final long DELAY_UPDATE_SUGGESTION = 300;
+ public UiHandler(CandidateView outerInstance) {
+ super(outerInstance);
+ }
+
@Override
public void dispatchMessage(Message msg) {
+ final CandidateView candidateView = getOuterInstance();
switch (msg.what) {
case MSG_HIDE_PREVIEW:
- hidePreview();
+ candidateView.hidePreview();
break;
case MSG_UPDATE_SUGGESTION:
- updateSuggestions();
+ candidateView.updateSuggestions();
break;
}
}
@@ -117,59 +158,233 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
+ private static class CandidateViewLayoutParams {
+ public final TextPaint mPaint;
+ public final int mPadding;
+ public final int mDividerWidth;
+ public final int mDividerHeight;
+ public final int mControlWidth;
+ private final int mAutoCorrectHighlight;
+
+ public final ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>();
+
+ public int mCountInStrip;
+ // True if the mCountInStrip suggestions can fit in suggestion strip in equally divided
+ // width without squeezing the text.
+ public boolean mCanUseFixedWidthColumns;
+ public int mMaxWidth;
+ public int mAvailableWidthForWords;
+ public int mConstantWidthForPaddings;
+ public int mVariableWidthForWords;
+ public float mScaleX;
+
+ public CandidateViewLayoutParams(Resources res, TextView word, View divider, View control,
+ int autoCorrectHighlight) {
+ mPaint = new TextPaint();
+ final float textSize = res.getDimension(R.dimen.candidate_text_size);
+ mPaint.setTextSize(textSize);
+ mPadding = word.getCompoundPaddingLeft() + word.getCompoundPaddingRight();
+ divider.measure(WRAP_CONTENT, MATCH_PARENT);
+ mDividerWidth = divider.getMeasuredWidth();
+ mDividerHeight = divider.getMeasuredHeight();
+ mControlWidth = control.getMeasuredWidth();
+ mAutoCorrectHighlight = autoCorrectHighlight;
+ }
+
+ public void layoutStrip(SuggestedWords suggestions, int maxWidth, int maxCount) {
+ final int size = suggestions.size();
+ setupTexts(suggestions, size, mAutoCorrectHighlight);
+ mCountInStrip = Math.min(maxCount, size);
+ mScaleX = 1.0f;
+
+ do {
+ mMaxWidth = maxWidth;
+ if (size > mCountInStrip) {
+ mMaxWidth -= mControlWidth;
+ }
+
+ tryLayout();
+
+ if (mCanUseFixedWidthColumns) {
+ return;
+ }
+ if (mVariableWidthForWords <= mAvailableWidthForWords) {
+ return;
+ }
+
+ final float scaleX = mAvailableWidthForWords / (float)mVariableWidthForWords;
+ if (scaleX >= MIN_TEXT_XSCALE) {
+ mScaleX = scaleX;
+ return;
+ }
+
+ mCountInStrip--;
+ } while (mCountInStrip > 1);
+ }
+
+ public void tryLayout() {
+ final int maxCount = mCountInStrip;
+ final int dividers = mDividerWidth * (maxCount - 1);
+ mConstantWidthForPaddings = dividers + mPadding * maxCount;
+ mAvailableWidthForWords = mMaxWidth - mConstantWidthForPaddings;
+
+ mPaint.setTextScaleX(mScaleX);
+ final int maxFixedWidthForWord = (mMaxWidth - dividers) / maxCount - mPadding;
+ mCanUseFixedWidthColumns = true;
+ mVariableWidthForWords = 0;
+ for (int i = 0; i < maxCount; i++) {
+ final int width = getTextWidth(mTexts.get(i), mPaint);
+ if (width > maxFixedWidthForWord)
+ mCanUseFixedWidthColumns = false;
+ mVariableWidthForWords += width;
+ }
+ }
+
+ private void setupTexts(SuggestedWords suggestions, int count, int autoCorrectHighlight) {
+ mTexts.clear();
+ for (int i = 0; i < count; i++) {
+ final CharSequence suggestion = suggestions.getWord(i);
+ if (suggestion == null) continue;
+
+ final boolean isAutoCorrect = suggestions.mHasMinimalSuggestion
+ && ((i == 1 && !suggestions.mTypedWordValid)
+ || (i == 0 && suggestions.mTypedWordValid));
+ // HACK: even if i == 0, we use mColorOther when this suggestion's length is 1
+ // and there are multiple suggestions, such as the default punctuation list.
+ // TODO: Need to revisit this logic with bigram suggestions
+ final CharSequence styled = getStyledCandidateWord(suggestion, isAutoCorrect,
+ autoCorrectHighlight);
+ mTexts.add(styled);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "count=%d width=%d avail=%d fixcol=%s scaleX=%4.2f const=%d var=%d",
+ mCountInStrip, mMaxWidth, mAvailableWidthForWords, mCanUseFixedWidthColumns,
+ mScaleX, mConstantWidthForPaddings, mVariableWidthForWords);
+ }
+ }
+
/**
* Construct a CandidateView for showing suggested words for completion.
* @param context
* @param attrs
*/
public CandidateView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.candidateViewStyle);
+ }
+
+ public CandidateView(Context context, AttributeSet attrs, int defStyle) {
+ // Note: Up to version 10 (Gingerbread) of the API, LinearLayout doesn't have 3-argument
+ // constructor.
+ // TODO: Call 3-argument constructor, super(context, attrs, defStyle), when we abandon
+ // backward compatibility with the version 10 or earlier of the API.
super(context, attrs);
+ if (defStyle != R.attr.candidateViewStyle) {
+ throw new IllegalArgumentException(
+ "can't accept defStyle other than R.attr.candidayeViewStyle: defStyle="
+ + defStyle);
+ }
+ setBackgroundDrawable(LinearLayoutCompatUtils.getBackgroundDrawable(
+ context, attrs, defStyle, R.style.CandidateViewStyle));
+
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.CandidateView, defStyle, R.style.CandidateViewStyle);
+ mAutoCorrectHighlight = a.getInt(R.styleable.CandidateView_autoCorrectHighlight, 0);
+ mColorTypedWord = a.getColor(R.styleable.CandidateView_colorTypedWord, 0);
+ mColorAutoCorrect = a.getColor(R.styleable.CandidateView_colorAutoCorrect, 0);
+ mColorSuggestedCandidate = a.getColor(R.styleable.CandidateView_colorSuggested, 0);
+ mCandidateCountInStrip = a.getInt(
+ R.styleable.CandidateView_candidateCountInStrip, DEFAULT_CANDIDATE_COUNT_IN_STRIP);
+ a.recycle();
Resources res = context.getResources();
- mPreviewPopup = new PopupWindow(context);
LayoutInflater inflater = LayoutInflater.from(context);
+ inflater.inflate(R.layout.candidates_strip, this);
+
+ mPreviewPopup = new PopupWindow(context);
mPreviewText = (TextView) inflater.inflate(R.layout.candidate_preview, null);
mPreviewPopup.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
mPreviewPopup.setContentView(mPreviewText);
mPreviewPopup.setBackgroundDrawable(null);
- mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
- mConfigCandidateHighlightFontColorEnabled =
- res.getBoolean(R.bool.config_candidate_highlight_font_color_enabled);
- mColorNormal = res.getColor(R.color.candidate_normal);
- mColorRecommended = res.getColor(R.color.candidate_recommended);
- mColorOther = res.getColor(R.color.candidate_other);
- mInvertedForegroundColorSpan = new ForegroundColorSpan(mColorNormal ^ 0x00ffffff);
- mInvertedBackgroundColorSpan = new BackgroundColorSpan(mColorNormal);
+ mCandidatesStrip = (ViewGroup)findViewById(R.id.candidates_strip);
+ mCandidateStripHeight = res.getDimensionPixelOffset(R.dimen.candidate_strip_height);
for (int i = 0; i < MAX_SUGGESTIONS; i++) {
- View v = inflater.inflate(R.layout.candidate, null);
- TextView tv = (TextView)v.findViewById(R.id.candidate_word);
- tv.setTag(i);
- tv.setOnClickListener(this);
+ final TextView word = (TextView)inflater.inflate(R.layout.candidate_word, null);
+ word.setTag(i);
+ word.setOnClickListener(this);
if (i == 0)
- tv.setOnLongClickListener(this);
- ImageView divider = (ImageView)v.findViewById(R.id.candidate_divider);
- // Do not display divider of first candidate.
- divider.setVisibility(i == 0 ? GONE : VISIBLE);
- mWords.add(v);
+ word.setOnLongClickListener(this);
+ mWords.add(word);
+ mInfos.add((TextView)inflater.inflate(R.layout.candidate_info, null));
+ mDividers.add(inflater.inflate(R.layout.candidate_divider, null));
}
- scrollTo(0, getScrollY());
+ mTouchToSave = findViewById(R.id.touch_to_save);
+ mWordToSave = (TextView)findViewById(R.id.word_to_save);
+ mWordToSave.setOnClickListener(this);
+
+ mInvertedForegroundColorSpan = new ForegroundColorSpan(mColorTypedWord ^ 0x00ffffff);
+ mInvertedBackgroundColorSpan = new BackgroundColorSpan(mColorTypedWord);
+
+ final TypedArray keyboardViewAttr = context.obtainStyledAttributes(
+ attrs, R.styleable.KeyboardView, R.attr.keyboardViewStyle, R.style.KeyboardView);
+ final Drawable expandBackground = keyboardViewAttr.getDrawable(
+ R.styleable.KeyboardView_keyBackground);
+ final Drawable closeBackground = keyboardViewAttr.getDrawable(
+ R.styleable.KeyboardView_keyBackground);
+ final int keyTextColor = keyboardViewAttr.getColor(
+ R.styleable.KeyboardView_keyTextColor, 0xFF000000);
+ keyboardViewAttr.recycle();
+
+ mCandidatesPaneControl = (ViewGroup)findViewById(R.id.candidates_pane_control);
+ mExpandCandidatesPane = (TextView)findViewById(R.id.expand_candidates_pane);
+ mExpandCandidatesPane.setBackgroundDrawable(expandBackground);
+ mExpandCandidatesPane.setTextColor(keyTextColor);
+ mExpandCandidatesPane.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ expandCandidatesPane();
+ }
+ });
+ mCloseCandidatesPane = (TextView)findViewById(R.id.close_candidates_pane);
+ mCloseCandidatesPane.setBackgroundDrawable(closeBackground);
+ mCloseCandidatesPane.setTextColor(keyTextColor);
+ mCloseCandidatesPane.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ closeCandidatesPane();
+ }
+ });
+ mCandidatesPaneControl.measure(WRAP_CONTENT, WRAP_CONTENT);
+
+ mParams = new CandidateViewLayoutParams(res,
+ mWords.get(0), mDividers.get(0), mCandidatesPaneControl, mAutoCorrectHighlight);
}
/**
- * A connection back to the service to communicate with the text field
+ * A connection back to the input method.
* @param listener
*/
- public void setService(LatinIME listener) {
- mService = listener;
+ public void setListener(Listener listener, View inputView) {
+ mListener = listener;
+ mKeyboardView = inputView.findViewById(R.id.keyboard_view);
+ mCandidatesPane = FrameLayoutCompatUtils.getPlacer(
+ (ViewGroup)inputView.findViewById(R.id.candidates_pane));
+ mCandidatesPane.setOnClickListener(this);
+ mCandidatesPaneContainer = (ViewGroup)inputView.findViewById(
+ R.id.candidates_pane_container);
}
public void setSuggestions(SuggestedWords suggestions) {
if (suggestions == null)
return;
mSuggestions = suggestions;
+ mExpandCandidatesPane.setEnabled(false);
if (mShowingAutoCorrectionInverted) {
mHandler.postUpdateSuggestions();
} else {
@@ -177,80 +392,281 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
+ private static CharSequence getStyledCandidateWord(CharSequence word, boolean isAutoCorrect,
+ int autoCorrectHighlight) {
+ if (!isAutoCorrect)
+ return word;
+ final Spannable spannedWord = new SpannableString(word);
+ if ((autoCorrectHighlight & AUTO_CORRECT_BOLD) != 0)
+ spannedWord.setSpan(BOLD_SPAN, 0, word.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ if ((autoCorrectHighlight & AUTO_CORRECT_UNDERLINE) != 0)
+ spannedWord.setSpan(UNDERLINE_SPAN, 0, word.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ return spannedWord;
+ }
+
+ private int getCandidateTextColor(boolean isAutoCorrect, boolean isSuggestedCandidate,
+ SuggestedWordInfo info) {
+ final int color;
+ if (isAutoCorrect) {
+ color = mColorAutoCorrect;
+ } else if (isSuggestedCandidate) {
+ color = mColorSuggestedCandidate;
+ } else {
+ color = mColorTypedWord;
+ }
+ if (info != null && info.isPreviousSuggestedWord()) {
+ final int newAlpha = (int)(Color.alpha(color) * 0.5f);
+ return Color.argb(newAlpha, Color.red(color), Color.green(color), Color.blue(color));
+ } else {
+ return color;
+ }
+ }
+
private void updateSuggestions() {
final SuggestedWords suggestions = mSuggestions;
+ final List<SuggestedWordInfo> suggestedWordInfoList = suggestions.mSuggestedWordInfoList;
+ final int paneWidth = getWidth();
+ final CandidateViewLayoutParams params = mParams;
+
clear();
- final int count = suggestions.size();
+ closeCandidatesPane();
+ if (suggestions.size() == 0)
+ return;
+
+ params.layoutStrip(suggestions, paneWidth, suggestions.isPunctuationSuggestions()
+ ? PUNCTUATIONS_IN_STRIP : mCandidateCountInStrip);
+
+ final int count = Math.min(mWords.size(), suggestions.size());
+ if (count <= params.mCountInStrip && !DBG) {
+ mCandidatesPaneControl.setVisibility(GONE);
+ } else {
+ mCandidatesPaneControl.setVisibility(VISIBLE);
+ mExpandCandidatesPane.setVisibility(VISIBLE);
+ mExpandCandidatesPane.setEnabled(true);
+ }
+
+ final int countInStrip = params.mCountInStrip;
+ View centeringFrom = null, lastView = null;
+ int x = 0, y = 0, infoX = 0;
for (int i = 0; i < count; i++) {
- CharSequence word = suggestions.getWord(i);
- if (word == null) continue;
- final int wordLength = word.length();
- final List<SuggestedWordInfo> suggestedWordInfoList =
- suggestions.mSuggestedWordInfoList;
-
- final View v = mWords.get(i);
- final TextView tv = (TextView)v.findViewById(R.id.candidate_word);
- final TextView dv = (TextView)v.findViewById(R.id.candidate_debug_info);
- tv.setTextColor(mColorNormal);
- // TODO: Needs safety net?
- if (suggestions.mHasMinimalSuggestion
- && ((i == 1 && !suggestions.mTypedWordValid)
- || (i == 0 && suggestions.mTypedWordValid))) {
- final CharacterStyle style;
- if (mConfigCandidateHighlightFontColorEnabled) {
- style = BOLD_SPAN;
- tv.setTextColor(mColorRecommended);
+ final int pos;
+ if (i <= 1) {
+ final boolean willAutoCorrect = !suggestions.mTypedWordValid
+ && suggestions.mHasMinimalSuggestion;
+ pos = willAutoCorrect ? 1 - i : i;
+ } else {
+ pos = i;
+ }
+ final CharSequence suggestion = suggestions.getWord(pos);
+ if (suggestion == null) continue;
+
+ final SuggestedWordInfo suggestionInfo = (suggestedWordInfoList != null)
+ ? suggestedWordInfoList.get(pos) : null;
+ final boolean isAutoCorrect = suggestions.mHasMinimalSuggestion
+ && ((pos == 1 && !suggestions.mTypedWordValid)
+ || (pos == 0 && suggestions.mTypedWordValid));
+ // HACK: even if i == 0, we use mColorOther when this suggestion's length is 1
+ // and there are multiple suggestions, such as the default punctuation list.
+ // TODO: Need to revisit this logic with bigram suggestions
+ final boolean isSuggestedCandidate = (pos != 0);
+ final boolean isPunctuationSuggestions = (suggestion.length() == 1 && count > 1);
+
+ final TextView word = mWords.get(pos);
+ final TextPaint paint = word.getPaint();
+ // TODO: Reorder candidates in strip as appropriate. The center candidate should hold
+ // the word when space is typed (valid typed word or auto corrected word).
+ word.setTextColor(getCandidateTextColor(isAutoCorrect,
+ isSuggestedCandidate || isPunctuationSuggestions, suggestionInfo));
+ final CharSequence styled = params.mTexts.get(pos);
+
+ final TextView info;
+ if (DBG && suggestionInfo != null
+ && !TextUtils.isEmpty(suggestionInfo.getDebugString())) {
+ info = mInfos.get(i);
+ info.setText(suggestionInfo.getDebugString());
+ } else {
+ info = null;
+ }
+
+ final CharSequence text;
+ final float scaleX;
+ if (i < countInStrip) {
+ if (i == 0 && params.mCountInStrip == 1) {
+ text = getEllipsizedText(styled, params.mMaxWidth, paint);
+ scaleX = paint.getTextScaleX();
} else {
- style = UNDERLINE_SPAN;
+ text = styled;
+ scaleX = params.mScaleX;
}
- final Spannable spannedWord = new SpannableString(word);
- spannedWord.setSpan(style, 0, wordLength, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
- word = spannedWord;
- } else if (i != 0 || (wordLength == 1 && count > 1)) {
- // HACK: even if i == 0, we use mColorOther when this
- // suggestion's length is 1
- // and there are multiple suggestions, such as the default
- // punctuation list.
- if (mConfigCandidateHighlightFontColorEnabled)
- tv.setTextColor(mColorOther);
- }
- tv.setText(word);
- tv.setClickable(true);
-
- if (suggestedWordInfoList != null && suggestedWordInfoList.get(i) != null) {
- final SuggestedWordInfo info = suggestedWordInfoList.get(i);
- if (info.isPreviousSuggestedWord()) {
- int color = tv.getCurrentTextColor();
- tv.setTextColor(Color.argb((int)(Color.alpha(color) * 0.5f), Color.red(color),
- Color.green(color), Color.blue(color)));
+ word.setText(text);
+ word.setTextScaleX(scaleX);
+ if (i != 0) {
+ // Add divider if this isn't the left most suggestion in candidate strip.
+ mCandidatesStrip.addView(mDividers.get(i));
}
- final String debugString = info.getDebugString();
- if (DBG) {
- if (TextUtils.isEmpty(debugString)) {
- dv.setVisibility(GONE);
- } else {
- dv.setText(debugString);
- dv.setVisibility(VISIBLE);
- }
+ mCandidatesStrip.addView(word);
+ if (params.mCanUseFixedWidthColumns) {
+ setLayoutWeight(word, 1.0f, mCandidateStripHeight);
} else {
- dv.setVisibility(GONE);
+ final int width = getTextWidth(text, paint) + params.mPadding;
+ setLayoutWeight(word, width, mCandidateStripHeight);
+ }
+ if (info != null) {
+ mCandidatesPane.addView(info);
+ info.measure(WRAP_CONTENT, WRAP_CONTENT);
+ final int width = info.getMeasuredWidth();
+ y = info.getMeasuredHeight();
+ FrameLayoutCompatUtils.placeViewAt(info, infoX, 0, width, y);
+ infoX += width * 2;
}
} else {
- dv.setVisibility(GONE);
+ paint.setTextScaleX(1.0f);
+ final int textWidth = getTextWidth(styled, paint);
+ int available = paneWidth - x - params.mPadding;
+ if (textWidth >= available) {
+ // Needs new row, centering previous row.
+ centeringCandidates(centeringFrom, lastView, x, paneWidth);
+ x = 0;
+ y += mCandidateStripHeight;
+ }
+ if (x != 0) {
+ // Add divider if this isn't the left most suggestion in current row.
+ final View divider = mDividers.get(i);
+ mCandidatesPane.addView(divider);
+ FrameLayoutCompatUtils.placeViewAt(
+ divider, x, y + (mCandidateStripHeight - params.mDividerHeight) / 2,
+ params.mDividerWidth, params.mDividerHeight);
+ x += params.mDividerWidth;
+ }
+ available = paneWidth - x - params.mPadding;
+ text = getEllipsizedText(styled, available, paint);
+ scaleX = paint.getTextScaleX();
+ word.setText(text);
+ word.setTextScaleX(scaleX);
+ mCandidatesPane.addView(word);
+ lastView = word;
+ if (x == 0) centeringFrom = word;
+ word.measure(WRAP_CONTENT,
+ MeasureSpec.makeMeasureSpec(mCandidateStripHeight, MeasureSpec.EXACTLY));
+ final int width = word.getMeasuredWidth();
+ final int height = word.getMeasuredHeight();
+ FrameLayoutCompatUtils.placeViewAt(
+ word, x, y + (mCandidateStripHeight - height) / 2, width, height);
+ x += width;
+ if (info != null) {
+ mCandidatesPane.addView(info);
+ lastView = info;
+ info.measure(WRAP_CONTENT, WRAP_CONTENT);
+ final int infoWidth = info.getMeasuredWidth();
+ FrameLayoutCompatUtils.placeViewAt(
+ info, x - infoWidth, y, infoWidth, info.getMeasuredHeight());
+ }
}
- addView(v);
}
+ if (x != 0) {
+ // Centering last candidates row.
+ centeringCandidates(centeringFrom, lastView, x, paneWidth);
+ }
+ }
- scrollTo(0, getScrollY());
- requestLayout();
+ 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 void centeringCandidates(View from, View to, int width, int paneWidth) {
+ final ViewGroup pane = mCandidatesPane;
+ final int fromIndex = pane.indexOfChild(from);
+ final int toIndex = pane.indexOfChild(to);
+ final int offset = (paneWidth - width) / 2;
+ for (int index = fromIndex; index <= toIndex; index++) {
+ offsetMargin(pane.getChildAt(index), offset, 0);
+ }
+ }
+
+ private static void offsetMargin(View v, int dx, int dy) {
+ if (v == null)
+ return;
+ final ViewGroup.LayoutParams lp = v.getLayoutParams();
+ if (lp instanceof ViewGroup.MarginLayoutParams) {
+ final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)lp;
+ mlp.setMargins(mlp.leftMargin + dx, mlp.topMargin + dy, 0, 0);
+ }
+ }
+
+ private static CharSequence getEllipsizedText(CharSequence text, int maxWidth,
+ TextPaint paint) {
+ paint.setTextScaleX(1.0f);
+ final int width = getTextWidth(text, paint);
+ final float scaleX = Math.min(maxWidth / (float)width, 1.0f);
+ 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 ellipsezed 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;
+ }
+ }
+
+ private void expandCandidatesPane() {
+ mExpandCandidatesPane.setVisibility(GONE);
+ mCloseCandidatesPane.setVisibility(VISIBLE);
+ mCandidatesPaneContainer.setMinimumHeight(mKeyboardView.getMeasuredHeight());
+ mCandidatesPaneContainer.setVisibility(VISIBLE);
+ mKeyboardView.setVisibility(GONE);
+ }
+
+ private void closeCandidatesPane() {
+ mExpandCandidatesPane.setVisibility(VISIBLE);
+ mCloseCandidatesPane.setVisibility(GONE);
+ mCandidatesPaneContainer.setVisibility(GONE);
+ mKeyboardView.setVisibility(VISIBLE);
}
public void onAutoCorrectionInverted(CharSequence autoCorrectedWord) {
- // Displaying auto corrected word as inverted is enabled only when highlighting candidate
- // with color is disabled.
- if (mConfigCandidateHighlightFontColorEnabled)
+ if ((mAutoCorrectHighlight & AUTO_CORRECT_INVERT) == 0)
return;
- final TextView tv = (TextView)mWords.get(1).findViewById(R.id.candidate_word);
+ final TextView tv = mWords.get(1);
final Spannable word = new SpannableString(autoCorrectedWord);
final int wordLength = word.length();
word.setSpan(mInvertedBackgroundColorSpan, 0, wordLength,
@@ -261,23 +677,16 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
mShowingAutoCorrectionInverted = true;
}
- public boolean isConfigCandidateHighlightFontColorEnabled() {
- return mConfigCandidateHighlightFontColorEnabled;
- }
-
public boolean isShowingAddToDictionaryHint() {
return mShowingAddToDictionary;
}
public void showAddToDictionaryHint(CharSequence word) {
- SuggestedWords.Builder builder = new SuggestedWords.Builder()
- .addWord(word)
- .addWord(getContext().getText(R.string.hint_add_to_dictionary));
- setSuggestions(builder.build());
+ mWordToSave.setText(word);
mShowingAddToDictionary = true;
- // Disable R.string.hint_add_to_dictionary button
- TextView tv = (TextView)getChildAt(1).findViewById(R.id.candidate_word);
- tv.setClickable(false);
+ mCandidatesStrip.setVisibility(GONE);
+ mCandidatesPaneControl.setVisibility(GONE);
+ mTouchToSave.setVisibility(VISIBLE);
}
public boolean dismissAddToDictionaryHint() {
@@ -293,7 +702,11 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
public void clear() {
mShowingAddToDictionary = false;
mShowingAutoCorrectionInverted = false;
- removeAllViews();
+ mTouchToSave.setVisibility(GONE);
+ mCandidatesStrip.setVisibility(VISIBLE);
+ mCandidatesStrip.removeAllViews();
+ mCandidatesPane.removeAllViews();
+ closeCandidatesPane();
}
private void hidePreview() {
@@ -305,11 +718,11 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
return;
final TextView previewText = mPreviewText;
- previewText.setTextColor(mColorNormal);
+ previewText.setTextColor(mColorTypedWord);
previewText.setText(word);
previewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- View v = getChildAt(index);
+ View v = mWords.get(index);
final int[] offsetInWindow = new int[2];
v.getLocationInWindow(offsetInWindow);
final int posX = offsetInWindow[0];
@@ -325,16 +738,20 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
private void addToDictionary(CharSequence word) {
- if (mService.addWordToDictionary(word.toString())) {
+ if (mListener.addWordToDictionary(word.toString())) {
showPreview(0, getContext().getString(R.string.added_word, word));
}
}
@Override
public boolean onLongClick(View view) {
- final int index = (Integer) view.getTag();
+ final Object tag = view.getTag();
+ if (!(tag instanceof Integer))
+ return true;
+ final int index = (Integer) tag;
if (index >= mSuggestions.size())
return true;
+
final CharSequence word = mSuggestions.getWord(index);
if (word.length() < 2)
return false;
@@ -344,15 +761,24 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
@Override
public void onClick(View view) {
- final int index = (Integer) view.getTag();
+ if (view == mWordToSave) {
+ addToDictionary(((TextView)view).getText());
+ clear();
+ return;
+ }
+
+ final Object tag = view.getTag();
+ if (!(tag instanceof Integer))
+ return;
+ final int index = (Integer) tag;
if (index >= mSuggestions.size())
return;
+
final CharSequence word = mSuggestions.getWord(index);
- if (mShowingAddToDictionary && index == 0) {
- addToDictionary(word);
- } else {
- mService.pickSuggestionManually(index, word);
- }
+ mListener.pickSuggestionManually(index, word);
+ // Because some punctuation letters are not treated as word separator depending on locale,
+ // {@link #setSuggestions} might not be called and candidates pane left opened.
+ closeCandidatesPane();
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
index 048f72dc5..66a041508 100644
--- a/java/src/com/android/inputmethod/latin/ContactsDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
@@ -26,6 +26,8 @@ import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.keyboard.Keyboard;
+
public class ContactsDictionary extends ExpandableDictionary {
private static final String[] PROJECTION = {
@@ -38,7 +40,7 @@ public class ContactsDictionary extends ExpandableDictionary {
/**
* Frequency for contacts information into the dictionary
*/
- private static final int FREQUENCY_FOR_CONTACTS = 128;
+ private static final int FREQUENCY_FOR_CONTACTS = 40;
private static final int FREQUENCY_FOR_CONTACTS_BIGRAM = 90;
private static final int INDEX_NAME = 1;
@@ -95,6 +97,14 @@ public class ContactsDictionary extends ExpandableDictionary {
mLastLoadedContacts = SystemClock.uptimeMillis();
}
+ @Override
+ public void getBigrams(final WordComposer codes, final CharSequence previousWord,
+ final WordCallback callback) {
+ // Do not return bigrams from Contacts when nothing was typed.
+ if (codes.size() <= 0) return;
+ super.getBigrams(codes, previousWord, callback);
+ }
+
private void addWords(Cursor cursor) {
clearDictionary();
@@ -104,7 +114,7 @@ public class ContactsDictionary extends ExpandableDictionary {
while (!cursor.isAfterLast()) {
String name = cursor.getString(INDEX_NAME);
- if (name != null) {
+ if (name != null && -1 == name.indexOf('@')) {
int len = name.length();
String prevWord = null;
@@ -115,8 +125,9 @@ public class ContactsDictionary extends ExpandableDictionary {
for (j = i + 1; j < len; j++) {
char c = name.charAt(j);
- if (!(c == '-' || c == '\'' ||
- Character.isLetter(c))) {
+ if (!(c == Keyboard.CODE_DASH
+ || c == Keyboard.CODE_SINGLE_QUOTE
+ || Character.isLetter(c))) {
break;
}
}
@@ -132,8 +143,6 @@ public class ContactsDictionary extends ExpandableDictionary {
if (wordLen < maxWordLength && wordLen > 1) {
super.addWord(word, FREQUENCY_FOR_CONTACTS);
if (!TextUtils.isEmpty(prevWord)) {
- // TODO Do not add email address
- // Not so critical
super.setBigram(prevWord, word,
FREQUENCY_FOR_CONTACTS_BIGRAM);
}
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index 2f1e7c2b8..fd62d61c3 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -33,6 +33,7 @@ public class DebugSettings extends PreferenceActivity
private boolean mServiceNeedsRestart = false;
private CheckBoxPreference mDebugMode;
+ private CheckBoxPreference mUseSpacebarLanguageSwitch;
@Override
protected void onCreate(Bundle icicle) {
@@ -60,6 +61,13 @@ public class DebugSettings extends PreferenceActivity
updateDebugMode();
mServiceNeedsRestart = true;
}
+ } else if (key.equals(SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCH_KEY)) {
+ if (mUseSpacebarLanguageSwitch != null) {
+ mUseSpacebarLanguageSwitch.setChecked(
+ prefs.getBoolean(SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCH_KEY,
+ getResources().getBoolean(
+ R.bool.config_use_spacebar_language_switcher)));
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 56f0cc503..c7737b9a2 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -29,7 +29,7 @@ public abstract class Dictionary {
/**
* The weight to give to a word if it's length is the same as the number of typed characters.
*/
- protected static final int FULL_WORD_FREQ_MULTIPLIER = 2;
+ protected static final int FULL_WORD_SCORE_MULTIPLIER = 2;
public static enum DataType {
UNIGRAM, BIGRAM
@@ -42,17 +42,17 @@ public abstract class Dictionary {
public interface WordCallback {
/**
* Adds a word to a list of suggestions. The word is expected to be ordered based on
- * the provided frequency.
+ * the provided score.
* @param word the character array containing the word
* @param wordOffset starting offset of the word in the character array
* @param wordLength length of valid characters in the character array
- * @param frequency the frequency of occurrence. This is normalized between 1 and 255, but
+ * @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
* @return true if the word was added, false if no more words are required
*/
- boolean addWord(char[] word, int wordOffset, int wordLength, int frequency, int dicTypeId,
+ boolean addWord(char[] word, int wordOffset, int wordLength, int score, int dicTypeId,
DataType dataType);
}
@@ -61,7 +61,7 @@ public abstract class Dictionary {
* words are added through the callback object.
* @param composer the key sequence to match
* @param callback the callback object to send matched words to as possible candidates
- * @see WordCallback#addWord(char[], int, int)
+ * @see WordCallback#addWord(char[], int, int, int, int, DataType)
*/
abstract public void getWords(final WordComposer composer, final WordCallback callback);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
new file mode 100644
index 000000000..5e7de3e6b
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -0,0 +1,71 @@
+/*
+ * 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 java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Class for a collection of dictionaries that behave like one dictionary.
+ */
+public class DictionaryCollection extends Dictionary {
+
+ protected final List<Dictionary> mDictionaries;
+
+ public DictionaryCollection() {
+ mDictionaries = new CopyOnWriteArrayList<Dictionary>();
+ }
+
+ public DictionaryCollection(Dictionary... dictionaries) {
+ mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries);
+ }
+
+ public DictionaryCollection(Collection<Dictionary> dictionaries) {
+ mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries);
+ }
+
+ @Override
+ public void getWords(final WordComposer composer, final WordCallback callback) {
+ for (final Dictionary dict : mDictionaries)
+ dict.getWords(composer, callback);
+ }
+
+ @Override
+ public void getBigrams(final WordComposer composer, final CharSequence previousWord,
+ final WordCallback callback) {
+ for (final Dictionary dict : mDictionaries)
+ dict.getBigrams(composer, previousWord, callback);
+ }
+
+ @Override
+ public boolean isValidWord(CharSequence word) {
+ for (int i = mDictionaries.size() - 1; i >= 0; --i)
+ if (mDictionaries.get(i).isValidWord(word)) return true;
+ return false;
+ }
+
+ @Override
+ public void close() {
+ for (final Dictionary dict : mDictionaries)
+ dict.close();
+ }
+
+ public void addDictionary(Dictionary newDict) {
+ mDictionaries.add(newDict);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
new file mode 100644
index 000000000..bba331868
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -0,0 +1,177 @@
+/*
+ * 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.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Factory for dictionary instances.
+ */
+public class DictionaryFactory {
+
+ private static String TAG = DictionaryFactory.class.getSimpleName();
+
+ /**
+ * Initializes a dictionary from a dictionary pack.
+ *
+ * This searches for a content provider providing a dictionary pack for the specified
+ * locale. If none is found, it falls back to using the resource passed as fallBackResId
+ * as a dictionary.
+ * @param context application context for reading resources
+ * @param locale the locale for which to create the dictionary
+ * @param fallbackResId the id of the resource to use as a fallback if no pack is found
+ * @return an initialized instance of Dictionary
+ */
+ public static Dictionary createDictionaryFromManager(Context context, Locale locale,
+ int fallbackResId) {
+ if (null == locale) {
+ Log.e(TAG, "No locale defined for dictionary");
+ return new DictionaryCollection(createBinaryDictionary(context, fallbackResId));
+ }
+
+ final List<Dictionary> dictList = new LinkedList<Dictionary>();
+ for (final AssetFileAddress f : BinaryDictionaryGetter.getDictionaryFiles(locale,
+ context, fallbackResId)) {
+ dictList.add(new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, null));
+ }
+
+ if (null == dictList) return null;
+ return new DictionaryCollection(dictList);
+ }
+
+ /**
+ * Initializes a dictionary from a raw resource file
+ * @param context application context for reading resources
+ * @param resId the resource containing the raw binary dictionary
+ * @return an initialized instance of BinaryDictionary
+ */
+ protected static BinaryDictionary createBinaryDictionary(Context context, int resId) {
+ AssetFileDescriptor afd = null;
+ try {
+ afd = context.getResources().openRawResourceFd(resId);
+ if (afd == null) {
+ Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
+ return null;
+ }
+ if (!isFullDictionary(afd)) return null;
+ final String sourceDir = context.getApplicationInfo().sourceDir;
+ final File packagePath = new File(sourceDir);
+ // TODO: Come up with a way to handle a directory.
+ if (!packagePath.isFile()) {
+ Log.e(TAG, "sourceDir is not a file: " + sourceDir);
+ return null;
+ }
+ return new BinaryDictionary(context,
+ sourceDir, afd.getStartOffset(), afd.getLength(), null);
+ } catch (android.content.res.Resources.NotFoundException e) {
+ Log.e(TAG, "Could not find the resource. resId=" + resId);
+ return null;
+ } finally {
+ if (null != afd) {
+ try {
+ afd.close();
+ } catch (java.io.IOException e) {
+ /* IOException on close ? What am I supposed to do ? */
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a dictionary from passed data. This is intended for unit tests only.
+ * @param context the test context to create this data from.
+ * @param dictionary the file to read
+ * @param startOffset the offset in the file where the data starts
+ * @param length the length of the data
+ * @param flagArray the flags to use with this data for testing
+ * @return the created dictionary, or null.
+ */
+ public static Dictionary createDictionaryForTest(Context context, File dictionary,
+ long startOffset, long length, Flag[] flagArray) {
+ if (dictionary.isFile()) {
+ return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length,
+ flagArray);
+ } else {
+ Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
+ return null;
+ }
+ }
+
+ /**
+ * Find out whether a dictionary is available for this locale.
+ * @param context the context on which to check resources.
+ * @param locale the locale to check for.
+ * @return whether a (non-placeholder) dictionary is available or not.
+ */
+ public static boolean isDictionaryAvailable(Context context, Locale locale) {
+ final Resources res = context.getResources();
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+
+ final int resourceId = Utils.getMainDictionaryResourceId(res);
+ final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
+ final boolean hasDictionary = isFullDictionary(afd);
+ try {
+ if (null != afd) afd.close();
+ } catch (java.io.IOException e) {
+ /* Um, what can we do here exactly? */
+ }
+
+ Utils.setSystemLocale(res, saveLocale);
+ return hasDictionary;
+ }
+
+ // TODO: Do not use the size of the dictionary as an unique dictionary ID.
+ public static Long getDictionaryId(Context context, Locale locale) {
+ final Resources res = context.getResources();
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+
+ final int resourceId = Utils.getMainDictionaryResourceId(res);
+ final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
+ final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH)
+ ? afd.getLength()
+ : null;
+ try {
+ if (null != afd) afd.close();
+ } catch (java.io.IOException e) {
+ }
+
+ Utils.setSystemLocale(res, saveLocale);
+ return size;
+ }
+
+ // TODO: Find the Right Way to find out whether the resource is a placeholder or not.
+ // Suggestion : strip the locale, open the placeholder file and store its offset.
+ // Upon opening the file, if it's the same offset, then it's the placeholder.
+ private static final long PLACEHOLDER_LENGTH = 34;
+ /**
+ * Finds out whether the data pointed out by an AssetFileDescriptor is a full
+ * dictionary (as opposed to null, or to a place holder).
+ * @param afd the file descriptor to test, or null
+ * @return true if the dictionary is a real full dictionary, false if it's null or a placeholder
+ */
+ protected static boolean isFullDictionary(final AssetFileDescriptor afd) {
+ return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
new file mode 100644
index 000000000..9d30af84b
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
@@ -0,0 +1,89 @@
+/*
+ * 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.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.net.Uri;
+
+/**
+ * Takes action to reload the necessary data when a dictionary pack was added/removed.
+ */
+public class DictionaryPackInstallBroadcastReceiver extends BroadcastReceiver {
+
+ final LatinIME mService;
+ /**
+ * The action of the intent for publishing that new dictionary data is available.
+ */
+ /* package */ static final String NEW_DICTIONARY_INTENT_ACTION =
+ "com.android.inputmethod.latin.dictionarypack.newdict";
+
+ public DictionaryPackInstallBroadcastReceiver(final LatinIME service) {
+ mService = service;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ final PackageManager manager = context.getPackageManager();
+
+ // We need to reread the dictionary if a new dictionary package is installed.
+ if (action.equals(Intent.ACTION_PACKAGE_ADDED)) {
+ final Uri packageUri = intent.getData();
+ if (null == packageUri) return; // No package name : we can't do anything
+ final String packageName = packageUri.getSchemeSpecificPart();
+ if (null == packageName) return;
+ final PackageInfo packageInfo;
+ try {
+ packageInfo = manager.getPackageInfo(packageName, PackageManager.GET_PROVIDERS);
+ } catch (android.content.pm.PackageManager.NameNotFoundException e) {
+ return; // No package info : we can't do anything
+ }
+ final ProviderInfo[] providers = packageInfo.providers;
+ if (null == providers) return; // No providers : it is not a dictionary.
+
+ // Search for some dictionary pack in the just-installed package. If found, reread.
+ for (ProviderInfo info : providers) {
+ if (BinaryDictionary.DICTIONARY_PACK_AUTHORITY.equals(info.authority)) {
+ mService.resetSuggestMainDict();
+ return;
+ }
+ }
+ // If we come here none of the authorities matched the one we searched for.
+ // We can exit safely.
+ return;
+ } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+ && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ // When the dictionary package is removed, we need to reread dictionary (to use the
+ // next-priority one, or stop using a dictionary at all if this was the only one,
+ // since this is the user request).
+ // If we are replacing the package, we will receive ADDED right away so no need to
+ // remove the dictionary at the moment, since we will do it when we receive the
+ // ADDED broadcast.
+
+ // TODO: Only reload dictionary on REMOVED when the removed package is the one we
+ // read dictionary from?
+ mService.resetSuggestMainDict();
+ } else if (action.equals(NEW_DICTIONARY_INTENT_ACTION)) {
+ mService.resetSuggestMainDict();
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index 90c250dcb..e56aa695d 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -16,13 +16,13 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.compat.InputConnectionCompatUtils;
+
import android.text.TextUtils;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.regex.Pattern;
/**
@@ -34,11 +34,6 @@ public class EditingUtils {
*/
private static final int LOOKBACK_CHARACTER_NUM = 15;
- // Cache Method pointers
- private static boolean sMethodsInitialized;
- private static Method sMethodGetSelectedText;
- private static Method sMethodSetComposingRegion;
-
private EditingUtils() {
// Unintentional empty constructor for singleton.
}
@@ -78,7 +73,7 @@ public class EditingUtils {
/**
* @param connection connection to the current text field.
- * @param sep characters which may separate words
+ * @param separators characters which may separate words
* @return the word that surrounds the cursor, including up to one trailing
* separator. For example, if the field contains "he|llo world", where |
* represents the cursor, then "hello " will be returned.
@@ -166,23 +161,62 @@ public class EditingUtils {
private static final Pattern spaceRegex = Pattern.compile("\\s+");
+
public static CharSequence getPreviousWord(InputConnection connection,
String sentenceSeperators) {
//TODO: Should fix this. This could be slow!
CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
- if (prev == null) {
- return null;
- }
+ return getPreviousWord(prev, sentenceSeperators);
+ }
+
+ // Get the word before the whitespace preceding the non-whitespace preceding the cursor.
+ // Also, it won't return words that end in a separator.
+ // Example :
+ // "abc def|" -> abc
+ // "abc def |" -> abc
+ // "abc def. |" -> abc
+ // "abc def . |" -> def
+ // "abc|" -> null
+ // "abc |" -> null
+ // "abc. def|" -> null
+ public static CharSequence getPreviousWord(CharSequence prev, String sentenceSeperators) {
+ if (prev == null) return null;
String[] w = spaceRegex.split(prev);
- if (w.length >= 2 && w[w.length-2].length() > 0) {
- char lastChar = w[w.length-2].charAt(w[w.length-2].length() -1);
- if (sentenceSeperators.contains(String.valueOf(lastChar))) {
- return null;
- }
- return w[w.length-2];
- } else {
- return null;
- }
+
+ // If we can't find two words, or we found an empty word, return null.
+ if (w.length < 2 || w[w.length - 2].length() <= 0) return null;
+
+ // If ends in a separator, return null
+ char lastChar = w[w.length - 2].charAt(w[w.length - 2].length() - 1);
+ if (sentenceSeperators.contains(String.valueOf(lastChar))) return null;
+
+ return w[w.length - 2];
+ }
+
+ public static CharSequence getThisWord(InputConnection connection, String sentenceSeperators) {
+ final CharSequence prev = connection.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
+ return getThisWord(prev, sentenceSeperators);
+ }
+
+ // Get the word immediately before the cursor, even if there is whitespace between it and
+ // the cursor - but not if there is punctuation.
+ // Example :
+ // "abc def|" -> def
+ // "abc def |" -> def
+ // "abc def. |" -> null
+ // "abc def . |" -> null
+ public static CharSequence getThisWord(CharSequence prev, String sentenceSeperators) {
+ if (prev == null) return null;
+ String[] w = spaceRegex.split(prev);
+
+ // No word : return null
+ if (w.length < 1 || w[w.length - 1].length() <= 0) return null;
+
+ // If ends in a separator, return null
+ char lastChar = w[w.length - 1].charAt(w[w.length - 1].length() - 1);
+ if (sentenceSeperators.contains(String.valueOf(lastChar))) return null;
+
+ return w[w.length - 1];
}
public static class SelectedWord {
@@ -241,7 +275,8 @@ public class EditingUtils {
}
// Extract the selection alone
- CharSequence touching = getSelectedText(ic, selStart, selEnd);
+ CharSequence touching = InputConnectionCompatUtils.getSelectedText(
+ ic, selStart, selEnd);
if (TextUtils.isEmpty(touching)) return null;
// Is any part of the selection a separator? If so, return null.
final int length = touching.length();
@@ -255,74 +290,4 @@ public class EditingUtils {
}
return null;
}
-
- /**
- * Cache method pointers for performance
- */
- private static void initializeMethodsForReflection() {
- try {
- // These will either both exist or not, so no need for separate try/catch blocks.
- // If other methods are added later, use separate try/catch blocks.
- sMethodGetSelectedText = InputConnection.class.getMethod("getSelectedText", int.class);
- sMethodSetComposingRegion = InputConnection.class.getMethod("setComposingRegion",
- int.class, int.class);
- } catch (NoSuchMethodException exc) {
- // Ignore
- }
- sMethodsInitialized = true;
- }
-
- /**
- * Returns the selected text between the selStart and selEnd positions.
- */
- private static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) {
- // Use reflection, for backward compatibility
- CharSequence result = null;
- if (!sMethodsInitialized) {
- initializeMethodsForReflection();
- }
- if (sMethodGetSelectedText != null) {
- try {
- result = (CharSequence) sMethodGetSelectedText.invoke(ic, 0);
- return result;
- } catch (InvocationTargetException exc) {
- // Ignore
- } catch (IllegalArgumentException e) {
- // Ignore
- } catch (IllegalAccessException e) {
- // Ignore
- }
- }
- // Reflection didn't work, try it the poor way, by moving the cursor to the start,
- // getting the text after the cursor and moving the text back to selected mode.
- // TODO: Verify that this works properly in conjunction with
- // LatinIME#onUpdateSelection
- ic.setSelection(selStart, selEnd);
- result = ic.getTextAfterCursor(selEnd - selStart, 0);
- ic.setSelection(selStart, selEnd);
- return result;
- }
-
- /**
- * Tries to set the text into composition mode if there is support for it in the framework.
- */
- public static void underlineWord(InputConnection ic, SelectedWord word) {
- // Use reflection, for backward compatibility
- // If method not found, there's nothing we can do. It still works but just wont underline
- // the word.
- if (!sMethodsInitialized) {
- initializeMethodsForReflection();
- }
- if (sMethodSetComposingRegion != null) {
- try {
- sMethodSetComposingRegion.invoke(ic, word.mStart, word.mEnd);
- } catch (InvocationTargetException exc) {
- // Ignore
- } catch (IllegalArgumentException e) {
- // Ignore
- } catch (IllegalAccessException e) {
- // Ignore
- }
- }
- }
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 0318175f6..97a4a1816 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -19,6 +19,8 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.os.AsyncTask;
+import com.android.inputmethod.keyboard.Keyboard;
+
import java.util.LinkedList;
/**
@@ -32,14 +34,14 @@ public class ExpandableDictionary extends Dictionary {
*/
protected static final int MAX_WORD_LENGTH = 32;
+ // Bigram frequency is a fixed point number with 1 meaning 1.2 and 255 meaning 1.8.
+ protected static final int BIGRAM_MAX_FREQUENCY = 255;
+
private Context mContext;
private char[] mWordBuilder = new char[MAX_WORD_LENGTH];
private int mDicTypeId;
private int mMaxDepth;
private int mInputLength;
- private StringBuilder sb = new StringBuilder(MAX_WORD_LENGTH);
-
- private static final char QUOTE = '\'';
private boolean mRequiresReload;
@@ -98,6 +100,7 @@ public class ExpandableDictionary extends Dictionary {
public int addFrequency(int add) {
mFrequency += add;
+ if (mFrequency > BIGRAM_MAX_FREQUENCY) mFrequency = BIGRAM_MAX_FREQUENCY;
return mFrequency;
}
}
@@ -226,6 +229,7 @@ public class ExpandableDictionary extends Dictionary {
* Returns the word's frequency or -1 if not found
*/
protected int getWordFrequency(CharSequence word) {
+ // Case-sensitive search
Node node = searchNode(mRoots, word, 0, word.length());
return (node == null) ? -1 : node.mFrequency;
}
@@ -301,7 +305,8 @@ public class ExpandableDictionary extends Dictionary {
getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex,
skipPos, callback);
}
- } else if ((c == QUOTE && currentChars[0] != QUOTE) || depth == skipPos) {
+ } else if ((c == Keyboard.CODE_SINGLE_QUOTE
+ && currentChars[0] != Keyboard.CODE_SINGLE_QUOTE) || depth == skipPos) {
// Skip the ' and continue deeper
word[depth] = c;
if (children != null) {
@@ -327,7 +332,7 @@ public class ExpandableDictionary extends Dictionary {
final int finalFreq;
if (skipPos < 0) {
finalFreq = freq * snr * addedAttenuation
- * FULL_WORD_FREQ_MULTIPLIER;
+ * FULL_WORD_SCORE_MULTIPLIER;
} else {
finalFreq = computeSkippedWordFinalFreq(freq,
snr * addedAttenuation, mInputLength);
@@ -362,12 +367,16 @@ public class ExpandableDictionary extends Dictionary {
/**
* Adds bigrams to the in-memory trie structure that is being used to retrieve any word
- * @param frequency frequency for this bigrams
- * @param addFrequency if true, it adds to current frequency
+ * @param frequency frequency for this bigram
+ * @param addFrequency if true, it adds to current frequency, else it overwrites the old value
* @return returns the final frequency
*/
private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) {
- Node firstWord = searchWord(mRoots, word1, 0, null);
+ // We don't want results to be different according to case of the looked up left hand side
+ // word. We do want however to return the correct case for the right hand side.
+ // So we want to squash the case of the left hand side, and preserve that of the right
+ // hand side word.
+ Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
Node secondWord = searchWord(mRoots, word2, 0, null);
LinkedList<NextWord> bigram = firstWord.mNGrams;
if (bigram == null || bigram.size() == 0) {
@@ -433,8 +442,12 @@ public class ExpandableDictionary extends Dictionary {
}
}
- private void runReverseLookUp(final CharSequence previousWord, final WordCallback callback) {
- Node prevWord = searchNode(mRoots, previousWord, 0, previousWord.length());
+ private void runBigramReverseLookUp(final CharSequence previousWord,
+ final WordCallback callback) {
+ // Search for the lowercase version of the word only, because that's where bigrams
+ // store their sons.
+ Node prevWord = searchNode(mRoots, previousWord.toString().toLowerCase(), 0,
+ previousWord.length());
if (prevWord != null && prevWord.mNGrams != null) {
reverseLookUp(prevWord.mNGrams, callback);
}
@@ -444,7 +457,7 @@ public class ExpandableDictionary extends Dictionary {
public void getBigrams(final WordComposer codes, final CharSequence previousWord,
final WordCallback callback) {
if (!reloadDictionaryIfRequired()) {
- runReverseLookUp(previousWord, callback);
+ runBigramReverseLookUp(previousWord, callback);
}
}
@@ -462,6 +475,9 @@ public class ExpandableDictionary extends Dictionary {
}
}
+ // Local to reverseLookUp, but do not allocate each time.
+ private final char[] mLookedUpString = new char[MAX_WORD_LENGTH];
+
/**
* reverseLookUp retrieves the full word given a list of terminal nodes and adds those words
* through callback.
@@ -474,30 +490,33 @@ public class ExpandableDictionary extends Dictionary {
for (NextWord nextWord : terminalNodes) {
node = nextWord.mWord;
freq = nextWord.getFrequency();
- // TODO Not the best way to limit suggestion threshold
- if (freq >= UserBigramDictionary.SUGGEST_THRESHOLD) {
- sb.setLength(0);
- do {
- sb.insert(0, node.mCode);
- node = node.mParent;
- } while(node != null);
-
- // TODO better way to feed char array?
- callback.addWord(sb.toString().toCharArray(), 0, sb.length(), freq, mDicTypeId,
- DataType.BIGRAM);
- }
+ int index = MAX_WORD_LENGTH;
+ do {
+ --index;
+ mLookedUpString[index] = node.mCode;
+ node = node.mParent;
+ } while (node != null);
+
+ callback.addWord(mLookedUpString, index, MAX_WORD_LENGTH - index, freq, mDicTypeId,
+ DataType.BIGRAM);
}
}
/**
- * Search for the terminal node of the word
+ * Recursively search for the terminal node of the word.
+ *
+ * One iteration takes the full word to search for and the current index of the recursion.
+ *
+ * @param children the node of the trie to search under.
+ * @param word the word to search for. Only read [offset..length] so there may be trailing chars
+ * @param offset the index in {@code word} this recursion should operate on.
+ * @param length the length of the input word.
* @return Returns the terminal node of the word if the word exists
*/
private Node searchNode(final NodeArray children, final CharSequence word, final int offset,
final int length) {
- // TODO Consider combining with addWordRec
final int count = children.mLength;
- char currentChar = word.charAt(offset);
+ final char currentChar = word.charAt(offset);
for (int j = 0; j < count; j++) {
final Node node = children.mData[j];
if (node.mCode == currentChar) {
diff --git a/java/src/com/android/inputmethod/latin/Flag.java b/java/src/com/android/inputmethod/latin/Flag.java
new file mode 100644
index 000000000..3cb8f7e17
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/Flag.java
@@ -0,0 +1,64 @@
+/*
+ * 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.res.Resources;
+
+public class Flag {
+ public final String mName;
+ public final int mResource;
+ public final int mMask;
+ public final int mSource;
+
+ static private final int SOURCE_CONFIG = 1;
+ static private final int SOURCE_EXTRAVALUE = 2;
+
+ public Flag(int resourceId, int mask) {
+ mName = null;
+ mResource = resourceId;
+ mSource = SOURCE_CONFIG;
+ mMask = mask;
+ }
+
+ public Flag(String name, int mask) {
+ mName = name;
+ mResource = 0;
+ mSource = SOURCE_EXTRAVALUE;
+ mMask = mask;
+ }
+
+ // If context/switcher are null, set all related flags in flagArray to on.
+ public static int initFlags(Flag[] flagArray, Context context, SubtypeSwitcher switcher) {
+ int flags = 0;
+ final Resources res = null == context ? null : context.getResources();
+ for (Flag entry : flagArray) {
+ switch (entry.mSource) {
+ case Flag.SOURCE_CONFIG:
+ if (res == null || res.getBoolean(entry.mResource))
+ flags |= entry.mMask;
+ break;
+ case Flag.SOURCE_EXTRAVALUE:
+ if (switcher == null ||
+ switcher.currentSubtypeContainsExtraValueKey(entry.mName))
+ flags |= entry.mMask;
+ break;
+ }
+ }
+ return flags;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java
deleted file mode 100644
index b58a57e42..000000000
--- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2008-2009 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.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
-import android.preference.PreferenceManager;
-import android.text.TextUtils;
-
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Locale;
-
-public class InputLanguageSelection extends PreferenceActivity {
-
- private SharedPreferences mPrefs;
- private String mSelectedLanguages;
- private ArrayList<Loc> mAvailableLanguages = new ArrayList<Loc>();
- private static final String[] BLACKLIST_LANGUAGES = {
- "ko", "ja", "zh", "el", "zz"
- };
-
- private static class Loc implements Comparable<Object> {
- private static Collator sCollator = Collator.getInstance();
-
- private String mLabel;
- public final Locale mLocale;
-
- public Loc(String label, Locale locale) {
- this.mLabel = label;
- this.mLocale = locale;
- }
-
- public void setLabel(String label) {
- this.mLabel = label;
- }
-
- @Override
- public String toString() {
- return this.mLabel;
- }
-
- @Override
- public int compareTo(Object o) {
- return sCollator.compare(this.mLabel, ((Loc) o).mLabel);
- }
- }
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- addPreferencesFromResource(R.xml.language_prefs);
- // Get the settings preferences
- mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, "");
- String[] languageList = mSelectedLanguages.split(",");
- mAvailableLanguages = getUniqueLocales();
- PreferenceGroup parent = getPreferenceScreen();
- for (int i = 0; i < mAvailableLanguages.size(); i++) {
- CheckBoxPreference pref = new CheckBoxPreference(this);
- Locale locale = mAvailableLanguages.get(i).mLocale;
- pref.setTitle(SubtypeSwitcher.getFullDisplayName(locale, true));
- boolean checked = isLocaleIn(locale, languageList);
- pref.setChecked(checked);
- if (hasDictionary(locale)) {
- pref.setSummary(R.string.has_dictionary);
- }
- parent.addPreference(pref);
- }
- }
-
- private boolean isLocaleIn(Locale locale, String[] list) {
- String lang = get5Code(locale);
- for (int i = 0; i < list.length; i++) {
- if (lang.equalsIgnoreCase(list[i])) return true;
- }
- return false;
- }
-
- private boolean hasDictionary(Locale locale) {
- final Resources res = getResources();
- final Configuration conf = res.getConfiguration();
- final Locale saveLocale = conf.locale;
- boolean haveDictionary = false;
- conf.locale = locale;
- res.updateConfiguration(conf, res.getDisplayMetrics());
-
- int mainDicResId = Utils.getMainDictionaryResourceId(res);
- BinaryDictionary bd = BinaryDictionary.initDictionary(this, mainDicResId, Suggest.DIC_MAIN);
-
- // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
- // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.
- if (bd.getSize() > Suggest.LARGE_DICTIONARY_THRESHOLD / 4) {
- haveDictionary = true;
- }
- bd.close();
- conf.locale = saveLocale;
- res.updateConfiguration(conf, res.getDisplayMetrics());
- return haveDictionary;
- }
-
- private String get5Code(Locale locale) {
- String country = locale.getCountry();
- return locale.getLanguage()
- + (TextUtils.isEmpty(country) ? "" : "_" + country);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- // Save the selected languages
- String checkedLanguages = "";
- PreferenceGroup parent = getPreferenceScreen();
- int count = parent.getPreferenceCount();
- for (int i = 0; i < count; i++) {
- CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i);
- if (pref.isChecked()) {
- Locale locale = mAvailableLanguages.get(i).mLocale;
- checkedLanguages += get5Code(locale) + ",";
- }
- }
- if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null
- Editor editor = mPrefs.edit();
- editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages);
- SharedPreferencesCompat.apply(editor);
- }
-
- public ArrayList<Loc> getUniqueLocales() {
- String[] locales = getAssets().getLocales();
- Arrays.sort(locales);
- ArrayList<Loc> uniqueLocales = new ArrayList<Loc>();
-
- final int origSize = locales.length;
- Loc[] preprocess = new Loc[origSize];
- int finalSize = 0;
- for (int i = 0 ; i < origSize; i++ ) {
- String s = locales[i];
- int len = s.length();
- if (len == 5) {
- String language = s.substring(0, 2);
- String country = s.substring(3, 5);
- Locale l = new Locale(language, country);
-
- // Exclude languages that are not relevant to LatinIME
- if (arrayContains(BLACKLIST_LANGUAGES, language)) continue;
-
- if (finalSize == 0) {
- preprocess[finalSize++] =
- new Loc(SubtypeSwitcher.getFullDisplayName(l, true), l);
- } else {
- // check previous entry:
- // same lang and a country -> upgrade to full name and
- // insert ours with full name
- // diff lang -> insert ours with lang-only name
- if (preprocess[finalSize-1].mLocale.getLanguage().equals(
- language)) {
- preprocess[finalSize-1].setLabel(SubtypeSwitcher.getFullDisplayName(
- preprocess[finalSize-1].mLocale, false));
- preprocess[finalSize++] =
- new Loc(SubtypeSwitcher.getFullDisplayName(l, false), l);
- } else {
- String displayName;
- if (s.equals("zz_ZZ")) {
- // ignore this locale
- } else {
- displayName = SubtypeSwitcher.getFullDisplayName(l, true);
- preprocess[finalSize++] = new Loc(displayName, l);
- }
- }
- }
- }
- }
- for (int i = 0; i < finalSize ; i++) {
- uniqueLocales.add(preprocess[i]);
- }
- return uniqueLocales;
- }
-
- private boolean arrayContains(String[] array, String value) {
- for (int i = 0; i < array.length; i++) {
- if (array[i].equalsIgnoreCase(value)) return true;
- }
- return false;
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index bf831bfbc..5304d830d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -29,11 +29,9 @@ import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Debug;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
-import android.os.Vibrator;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.text.InputType;
@@ -42,46 +40,45 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
-import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
-import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.FrameLayout;
-import android.widget.HorizontalScrollView;
-import android.widget.LinearLayout;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.compat.CompatUtils;
+import com.android.inputmethod.compat.EditorInfoCompatUtils;
+import com.android.inputmethod.compat.InputConnectionCompatUtils;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
+import com.android.inputmethod.compat.InputTypeCompatUtils;
+import com.android.inputmethod.compat.SuggestionSpanUtils;
+import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.deprecated.recorrection.Recorrection;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
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.Utils.RingCharBuffer;
-import com.android.inputmethod.voice.VoiceIMEConnector;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Locale;
/**
* Input method implementation for Qwerty'ish keyboard.
*/
-public class LatinIME extends InputMethodService implements KeyboardActionListener {
+public class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener,
+ CandidateView.Listener {
private static final String TAG = LatinIME.class.getSimpleName();
private static final boolean PERF_DEBUG = false;
private static final boolean TRACE = false;
@@ -94,6 +91,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*
* @deprecated Use {@link LatinIME#IME_OPTION_NO_MICROPHONE} with package name prefixed.
*/
+ @SuppressWarnings("dep-ann")
public static final String IME_OPTION_NO_MICROPHONE_COMPAT = "nm";
/**
@@ -109,9 +107,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey";
- private static final int DELAY_UPDATE_SUGGESTIONS = 180;
- private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300;
- private static final int DELAY_UPDATE_SHIFT_STATE = 300;
private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100;
// How many continuous deletes at which to start deleting at a higher speed.
@@ -119,6 +114,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Key events coming any faster than this are long-presses.
private static final int QUICK_PRESS = 200;
+ /**
+ * The name of the scheme used by the Package Manager to warn of a new package installation,
+ * replacement or removal.
+ */
+ private static final String SCHEME_PACKAGE = "package";
+
private int mSuggestionVisibility;
private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE
= R.string.prefs_suggestion_visibility_show_value;
@@ -133,55 +134,47 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
SUGGESTION_VISIBILILTY_HIDE_VALUE
};
+ private Settings.Values mSettingsValues;
+
private View mCandidateViewContainer;
+ private int mCandidateStripHeight;
private CandidateView mCandidateView;
private Suggest mSuggest;
private CompletionInfo[] mApplicationSpecifiedCompletions;
private AlertDialog mOptionsDialog;
- private InputMethodManager mImm;
+ private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
private String mInputMethodId;
private KeyboardSwitcher mKeyboardSwitcher;
private SubtypeSwitcher mSubtypeSwitcher;
- private VoiceIMEConnector mVoiceConnector;
+ private VoiceProxy mVoiceProxy;
+ private Recorrection mRecorrection;
private UserDictionary mUserDictionary;
private UserBigramDictionary mUserBigramDictionary;
- private ContactsDictionary mContactsDictionary;
private AutoDictionary mAutoDictionary;
+ // 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 mAutoSpace;
+ private boolean mShouldInsertMagicSpace;
private boolean mInputTypeNoAutoCorrect;
private boolean mIsSettingsSuggestionStripOn;
private boolean mApplicationSpecifiedCompletionOn;
- private AccessibilityUtils mAccessibilityUtils;
-
- private final StringBuilder mComposing = new StringBuilder();
- private WordComposer mWord = new WordComposer();
+ private final StringBuilder mComposingStringBuilder = new StringBuilder();
+ private WordComposer mWordComposer = new WordComposer();
private CharSequence mBestWord;
- private boolean mHasValidSuggestions;
+ private boolean mHasUncommittedTypedChars;
private boolean mHasDictionary;
- private boolean mJustAddedAutoSpace;
- private boolean mAutoCorrectEnabled;
- private boolean mRecorrectionEnabled;
- private boolean mBigramSuggestionEnabled;
- private boolean mAutoCorrectOn;
- private boolean mVibrateOn;
- private boolean mSoundOn;
- private boolean mPopupOn;
- private boolean mAutoCap;
- private boolean mQuickFixes;
- private boolean mConfigEnableShowSubtypeSettings;
- private boolean mConfigSwipeDownDismissKeyboardEnabled;
- private int mConfigDelayBeforeFadeoutLanguageOnSpacebar;
- private int mConfigDurationOfFadeoutLanguageOnSpacebar;
- private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar;
- private long mConfigDoubleSpacesTurnIntoPeriodTimeout;
+ // 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;
@@ -189,80 +182,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Keep track of the last selection range to decide if we need to show word alternatives
private int mLastSelectionStart;
private int mLastSelectionEnd;
- private SuggestedWords mSuggestPuncList;
- // Indicates whether the suggestion strip is to be on in landscape
- private boolean mJustAccepted;
+ // 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.
+ private boolean mExpectingUpdateSelection;
private int mDeleteCount;
private long mLastKeyTime;
private AudioManager mAudioManager;
// Align sound effect volume on music volume
private static final float FX_VOLUME = -1.0f;
- private boolean mSilentMode;
+ private boolean mSilentModeOn; // System-wide current configuration
- /* package */ String mWordSeparators;
- private String mSentenceSeparators;
- private String mSuggestPuncs;
- // TODO: Move this flag to VoiceIMEConnector
+ // TODO: Move this flag to VoiceProxy
private boolean mConfigurationChanging;
+ // Object for reacting to adding/removing a dictionary pack.
+ private BroadcastReceiver mDictionaryPackInstallReceiver =
+ new DictionaryPackInstallBroadcastReceiver(this);
+
// Keeps track of most recently inserted text (multi-character key) for reverting
private CharSequence mEnteredText;
- private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>();
-
- public abstract static class WordAlternatives {
- protected CharSequence mChosenWord;
- public WordAlternatives() {
- // Nothing
- }
+ public final UIHandler mHandler = new UIHandler(this);
- public WordAlternatives(CharSequence chosenWord) {
- mChosenWord = chosenWord;
- }
-
- @Override
- public int hashCode() {
- return mChosenWord.hashCode();
- }
-
- public abstract CharSequence getOriginalWord();
-
- public CharSequence getChosenWord() {
- return mChosenWord;
- }
-
- public abstract SuggestedWords.Builder getAlternatives();
- }
-
- public class TypedWordAlternatives extends WordAlternatives {
- private WordComposer word;
-
- public TypedWordAlternatives() {
- // Nothing
- }
-
- public TypedWordAlternatives(CharSequence chosenWord, WordComposer wordComposer) {
- super(chosenWord);
- word = wordComposer;
- }
-
- @Override
- public CharSequence getOriginalWord() {
- return word.getTypedWord();
- }
-
- @Override
- public SuggestedWords.Builder getAlternatives() {
- return getTypedSuggestions(word);
- }
- }
-
- public final UIHandler mHandler = new UIHandler();
-
- public class UIHandler extends Handler {
+ public static class UIHandler extends StaticInnerHandlerWrapper<LatinIME> {
private static final int MSG_UPDATE_SUGGESTIONS = 0;
private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1;
private static final int MSG_UPDATE_SHIFT_STATE = 2;
@@ -270,44 +215,62 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4;
private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5;
private static final int MSG_SPACE_TYPED = 6;
+ private static final int MSG_SET_BIGRAM_PREDICTIONS = 7;
+
+ public UIHandler(LatinIME outerInstance) {
+ super(outerInstance);
+ }
@Override
public void handleMessage(Message msg) {
- final KeyboardSwitcher switcher = mKeyboardSwitcher;
- final LatinKeyboardView inputView = switcher.getInputView();
+ final LatinIME latinIme = getOuterInstance();
+ final KeyboardSwitcher switcher = latinIme.mKeyboardSwitcher;
+ final LatinKeyboardView inputView = switcher.getKeyboardView();
switch (msg.what) {
case MSG_UPDATE_SUGGESTIONS:
- updateSuggestions();
+ latinIme.updateSuggestions();
break;
case MSG_UPDATE_OLD_SUGGESTIONS:
- setOldSuggestions();
+ latinIme.mRecorrection.fetchAndDisplayRecorrectionSuggestions(
+ latinIme.mVoiceProxy, latinIme.mCandidateView,
+ latinIme.mSuggest, latinIme.mKeyboardSwitcher, latinIme.mWordComposer,
+ latinIme.mHasUncommittedTypedChars, latinIme.mLastSelectionStart,
+ latinIme.mLastSelectionEnd, latinIme.mSettingsValues.mWordSeparators);
break;
case MSG_UPDATE_SHIFT_STATE:
switcher.updateShiftState();
break;
+ case MSG_SET_BIGRAM_PREDICTIONS:
+ latinIme.updateBigramPredictions();
+ break;
case MSG_VOICE_RESULTS:
- mVoiceConnector.handleVoiceResults(preferCapitalization()
+ latinIme.mVoiceProxy.handleVoiceResults(latinIme.preferCapitalization()
|| (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked()));
break;
case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR:
- if (inputView != null)
+ if (inputView != null) {
inputView.setSpacebarTextFadeFactor(
- (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2,
+ (1.0f + latinIme.mSettingsValues.
+ mFinalFadeoutFactorOfLanguageOnSpacebar) / 2,
(LatinKeyboard)msg.obj);
+ }
sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj),
- mConfigDurationOfFadeoutLanguageOnSpacebar);
+ latinIme.mSettingsValues.mDurationOfFadeoutLanguageOnSpacebar);
break;
case MSG_DISMISS_LANGUAGE_ON_SPACEBAR:
- if (inputView != null)
+ if (inputView != null) {
inputView.setSpacebarTextFadeFactor(
- mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj);
+ latinIme.mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar,
+ (LatinKeyboard)msg.obj);
+ }
break;
}
}
public void postUpdateSuggestions() {
removeMessages(MSG_UPDATE_SUGGESTIONS);
- sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), DELAY_UPDATE_SUGGESTIONS);
+ sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS),
+ getOuterInstance().mSettingsValues.mDelayUpdateSuggestions);
}
public void cancelUpdateSuggestions() {
@@ -321,7 +284,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void postUpdateOldSuggestions() {
removeMessages(MSG_UPDATE_OLD_SUGGESTIONS);
sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS),
- DELAY_UPDATE_OLD_SUGGESTIONS);
+ getOuterInstance().mSettingsValues.mDelayUpdateOldSuggestions);
}
public void cancelUpdateOldSuggestions() {
@@ -330,31 +293,49 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void postUpdateShiftKeyState() {
removeMessages(MSG_UPDATE_SHIFT_STATE);
- sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), DELAY_UPDATE_SHIFT_STATE);
+ sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE),
+ getOuterInstance().mSettingsValues.mDelayUpdateShiftState);
}
public void cancelUpdateShiftState() {
removeMessages(MSG_UPDATE_SHIFT_STATE);
}
+ public void postUpdateBigramPredictions() {
+ removeMessages(MSG_SET_BIGRAM_PREDICTIONS);
+ sendMessageDelayed(obtainMessage(MSG_SET_BIGRAM_PREDICTIONS),
+ getOuterInstance().mSettingsValues.mDelayUpdateSuggestions);
+ }
+
+ public void cancelUpdateBigramPredictions() {
+ removeMessages(MSG_SET_BIGRAM_PREDICTIONS);
+ }
+
public void updateVoiceResults() {
sendMessage(obtainMessage(MSG_VOICE_RESULTS));
}
public void startDisplayLanguageOnSpacebar(boolean localeChanged) {
+ final LatinIME latinIme = getOuterInstance();
removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR);
removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR);
- final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ final LatinKeyboardView inputView = latinIme.mKeyboardSwitcher.getKeyboardView();
if (inputView != null) {
- final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard();
- // The language is never displayed when the delay is zero.
- if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0)
- inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f
- : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard);
+ final LatinKeyboard keyboard = latinIme.mKeyboardSwitcher.getLatinKeyboard();
// The language is always displayed when the delay is negative.
- if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) {
+ final boolean needsToDisplayLanguage = localeChanged
+ || latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar < 0;
+ // The language is never displayed when the delay is zero.
+ if (latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar != 0) {
+ inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f
+ : latinIme.mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar,
+ keyboard);
+ }
+ // The fadeout animation will start when the delay is positive.
+ if (localeChanged
+ && latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar > 0) {
sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard),
- mConfigDelayBeforeFadeoutLanguageOnSpacebar);
+ latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar);
}
}
}
@@ -362,7 +343,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void startDoubleSpacesTimer() {
removeMessages(MSG_SPACE_TYPED);
sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED),
- mConfigDoubleSpacesTurnIntoPeriodTimeout);
+ getOuterInstance().mSettingsValues.mDoubleSpacesTurnIntoPeriodTimeout);
}
public void cancelDoubleSpacesTimer() {
@@ -379,44 +360,26 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
mPrefs = prefs;
LatinImeLogger.init(this, prefs);
+ LanguageSwitcherProxy.init(this, prefs);
SubtypeSwitcher.init(this, prefs);
KeyboardSwitcher.init(this, prefs);
+ Recorrection.init(this, prefs);
AccessibilityUtils.init(this, prefs);
super.onCreate();
- mImm = ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE));
+ mImm = InputMethodManagerCompatWrapper.getInstance(this);
mInputMethodId = Utils.getInputMethodId(mImm, getPackageName());
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
- mAccessibilityUtils = AccessibilityUtils.getInstance();
+ mRecorrection = Recorrection.getInstance();
DEBUG = LatinImeLogger.sDBG;
+ loadSettings();
+
final Resources res = getResources();
mResources = res;
- // If the option should not be shown, do not read the recorrection preference
- // but always use the default setting defined in the resources.
- if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
- mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
- res.getBoolean(R.bool.config_default_recorrection_enabled));
- } else {
- mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled);
- }
-
- mConfigEnableShowSubtypeSettings = res.getBoolean(
- R.bool.config_enable_show_subtype_settings);
- mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean(
- R.bool.config_swipe_down_dismiss_keyboard_enabled);
- mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger(
- R.integer.config_delay_before_fadeout_language_on_spacebar);
- mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger(
- R.integer.config_duration_of_fadeout_language_on_spacebar);
- mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger(
- R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f;
- mConfigDoubleSpacesTurnIntoPeriodTimeout = res.getInteger(
- R.integer.config_double_spaces_turn_into_period_timeout);
-
Utils.GCUtils.getInstance().reset();
boolean tryGC = true;
for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
@@ -429,49 +392,80 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mOrientation = res.getConfiguration().orientation;
- initSuggestPuncList();
- // register to receive ringer mode change and network state change.
+ // Register to receive ringer mode change and network state change.
+ // Also receive installation and removal of a dictionary pack.
final IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mReceiver, filter);
- mVoiceConnector = VoiceIMEConnector.init(this, prefs, mHandler);
+ mVoiceProxy = VoiceProxy.init(this, prefs, mHandler);
+
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ packageFilter.addDataScheme(SCHEME_PACKAGE);
+ registerReceiver(mDictionaryPackInstallReceiver, packageFilter);
+
+ final IntentFilter newDictFilter = new IntentFilter();
+ newDictFilter.addAction(
+ DictionaryPackInstallBroadcastReceiver.NEW_DICTIONARY_INTENT_ACTION);
+ registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
+ }
+
+ // Has to be package-visible for unit tests
+ /* package */ void loadSettings() {
+ if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ if (null == mSubtypeSwitcher) mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ mSettingsValues = new Settings.Values(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr());
+ resetContactsDictionary();
}
private void initSuggest() {
- String locale = mSubtypeSwitcher.getInputLocaleStr();
+ final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
+ final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
- Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(new Locale(locale));
+ final Resources res = mResources;
+ final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale);
if (mSuggest != null) {
mSuggest.close();
}
- final SharedPreferences prefs = mPrefs;
- mQuickFixes = isQuickFixesEnabled(prefs);
- final Resources res = mResources;
int mainDicResId = Utils.getMainDictionaryResourceId(res);
- mSuggest = new Suggest(this, mainDicResId);
- loadAndSetAutoCorrectionThreshold(prefs);
+ mSuggest = new Suggest(this, mainDicResId, keyboardLocale);
+ if (mSettingsValues.mAutoCorrectEnabled) {
+ mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold);
+ }
updateAutoTextEnabled();
- mUserDictionary = new UserDictionary(this, locale);
+ mUserDictionary = new UserDictionary(this, localeStr);
mSuggest.setUserDictionary(mUserDictionary);
- mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS);
- mSuggest.setContactsDictionary(mContactsDictionary);
+ resetContactsDictionary();
- mAutoDictionary = new AutoDictionary(this, this, locale, Suggest.DIC_AUTO);
+ mAutoDictionary = new AutoDictionary(this, this, localeStr, Suggest.DIC_AUTO);
mSuggest.setAutoDictionary(mAutoDictionary);
- mUserBigramDictionary = new UserBigramDictionary(this, this, locale, Suggest.DIC_USER);
+ mUserBigramDictionary = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER);
mSuggest.setUserBigramDictionary(mUserBigramDictionary);
updateCorrectionMode();
- mWordSeparators = res.getString(R.string.word_separators);
- mSentenceSeparators = res.getString(R.string.sentence_separators);
- mSubtypeSwitcher.changeSystemLocale(savedLocale);
+ Utils.setSystemLocale(res, savedLocale);
+ }
+
+ private void resetContactsDictionary() {
+ if (null == mSuggest) return;
+ ContactsDictionary contactsDictionary = mSettingsValues.mUseContactsDict
+ ? new ContactsDictionary(this, Suggest.DIC_CONTACTS) : null;
+ mSuggest.setContactsDictionary(contactsDictionary);
+ }
+
+ /* package private */ void resetSuggestMainDict() {
+ final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
+ final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
+ int mainDicResId = Utils.getMainDictionaryResourceId(mResources);
+ mSuggest.resetMainDict(this, mainDicResId, keyboardLocale);
}
@Override
@@ -481,7 +475,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSuggest = null;
}
unregisterReceiver(mReceiver);
- mVoiceConnector.destroy();
+ unregisterReceiver(mDictionaryPackInstallReceiver);
+ mVoiceProxy.destroy();
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
super.onDestroy();
@@ -502,8 +497,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mConfigurationChanging = true;
super.onConfigurationChanged(conf);
- mVoiceConnector.onConfigurationChanged(conf);
+ mVoiceProxy.onConfigurationChanged(conf);
mConfigurationChanging = false;
+
+ // This will work only when the subtype is not supported.
+ LanguageSwitcherProxy.onConfigurationChanged(conf);
}
@Override
@@ -512,30 +510,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public View onCreateCandidatesView() {
- LayoutInflater inflater = getLayoutInflater();
- LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null);
- mCandidateViewContainer = container;
- if (container.getPaddingRight() != 0) {
- HorizontalScrollView scrollView =
- (HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view);
- scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER);
- container.setGravity(Gravity.CENTER_HORIZONTAL);
- }
- mCandidateView = (CandidateView) container.findViewById(R.id.candidates);
- mCandidateView.setService(this);
- setCandidatesViewShown(true);
- return container;
+ public void setInputView(View view) {
+ super.setInputView(view);
+ mCandidateViewContainer = view.findViewById(R.id.candidates_container);
+ mCandidateView = (CandidateView) view.findViewById(R.id.candidates);
+ if (mCandidateView != null)
+ mCandidateView.setListener(this, view);
+ mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height);
+ }
+
+ @Override
+ public void setCandidatesView(View view) {
+ // To ensure that CandidatesView will never be set.
+ return;
}
@Override
public void onStartInputView(EditorInfo attribute, boolean restarting) {
final KeyboardSwitcher switcher = mKeyboardSwitcher;
- LatinKeyboardView inputView = switcher.getInputView();
+ LatinKeyboardView inputView = switcher.getKeyboardView();
if (DEBUG) {
- Log.d(TAG, "onStartInputView: inputType=" + ((attribute == null) ? "none"
- : String.format("0x%08x", attribute.inputType)));
+ Log.d(TAG, "onStartInputView: attribute:" + ((attribute == null) ? "none"
+ : String.format("inputType=0x%08x imeOptions=0x%08x",
+ attribute.inputType, attribute.imeOptions)));
}
// In landscape mode, this method gets called without the input view being created.
if (inputView == null) {
@@ -549,20 +547,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// 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 VoiceIMEConnector voiceIme = mVoiceConnector;
- voiceIme.resetVoiceStates(Utils.isPasswordInputType(attribute.inputType)
- || Utils.isVisiblePasswordInputType(attribute.inputType));
+ final VoiceProxy voiceIme = mVoiceProxy;
+ voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(attribute.inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(attribute.inputType));
initializeInputAttributes(attribute);
inputView.closing();
mEnteredText = null;
- mComposing.setLength(0);
- mHasValidSuggestions = false;
+ mComposingStringBuilder.setLength(0);
+ mHasUncommittedTypedChars = false;
mDeleteCount = 0;
- mJustAddedAutoSpace = false;
+ mJustAddedMagicSpace = false;
+ mJustReplacedDoubleSpace = false;
+
+ loadSettings();
+ updateCorrectionMode();
+ updateAutoTextEnabled();
+ updateSuggestionVisibility(mPrefs, mResources);
+
+ if (mSuggest != null && mSettingsValues.mAutoCorrectEnabled) {
+ mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold);
+ }
+ mVoiceProxy.loadSettings(attribute, mPrefs);
+ // This will work only when the subtype is not supported.
+ LanguageSwitcherProxy.loadSettings();
- loadSettings(attribute);
if (mSubtypeSwitcher.isKeyboardMode()) {
switcher.loadKeyboard(attribute,
mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(),
@@ -570,21 +580,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
switcher.updateShiftState();
}
- setCandidatesViewShownInternal(isCandidateStripVisible(),
- false /* needsInputViewShown */ );
+ if (mCandidateView != null)
+ mCandidateView.clear();
+ setSuggestionStripShownInternal(isCandidateStripVisible(), /* needsInputViewShown */ false);
// Delay updating suggestions because keyboard input view may not be shown at this point.
mHandler.postUpdateSuggestions();
updateCorrectionMode();
- final boolean accessibilityEnabled = mAccessibilityUtils.isAccessibilityEnabled();
-
- inputView.setPreviewEnabled(mPopupOn);
+ inputView.setKeyPreviewPopupEnabled(mSettingsValues.mKeyPreviewPopupOn,
+ mSettingsValues.mKeyPreviewPopupDismissDelay);
inputView.setProximityCorrectionEnabled(true);
- inputView.setAccessibilityEnabled(accessibilityEnabled);
// If we just entered a text field, maybe it has some old text that requires correction
- checkRecorrectionOnStart();
- inputView.setForeground(true);
+ mRecorrection.checkRecorrectionOnStart();
voiceIme.onStartInputView(inputView.getWindowToken());
@@ -596,7 +604,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
final int inputType = attribute.inputType;
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
- mAutoSpace = false;
+ mShouldInsertMagicSpace = false;
mInputTypeNoAutoCorrect = false;
mIsSettingsSuggestionStripOn = false;
mApplicationSpecifiedCompletionOn = false;
@@ -605,17 +613,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) {
mIsSettingsSuggestionStripOn = true;
// Make sure that passwords are not displayed in candidate view
- if (Utils.isPasswordInputType(inputType)
- || Utils.isVisiblePasswordInputType(inputType)) {
+ if (InputTypeCompatUtils.isPasswordInputType(inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)) {
mIsSettingsSuggestionStripOn = false;
}
- if (Utils.isEmailVariation(variation)
+ if (InputTypeCompatUtils.isEmailVariation(variation)
|| variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
- mAutoSpace = false;
+ mShouldInsertMagicSpace = false;
} else {
- mAutoSpace = true;
+ mShouldInsertMagicSpace = true;
}
- if (Utils.isEmailVariation(variation)) {
+ if (InputTypeCompatUtils.isEmailVariation(variation)) {
mIsSettingsSuggestionStripOn = false;
} else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
mIsSettingsSuggestionStripOn = false;
@@ -646,32 +654,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void checkRecorrectionOnStart() {
- if (!mRecorrectionEnabled) return;
-
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- // There could be a pending composing span. Clean it up first.
- ic.finishComposingText();
-
- if (isShowingSuggestionsStrip() && isSuggestionsRequested()) {
- // First get the cursor position. This is required by setOldSuggestions(), so that
- // it can pass the correct range to setComposingRegion(). At this point, we don't
- // have valid values for mLastSelectionStart/End because onUpdateSelection() has
- // not been called yet.
- ExtractedTextRequest etr = new ExtractedTextRequest();
- etr.token = 0; // anything is fine here
- ExtractedText et = ic.getExtractedText(etr, 0);
- if (et == null) return;
-
- mLastSelectionStart = et.startOffset + et.selectionStart;
- mLastSelectionEnd = et.startOffset + et.selectionEnd;
-
- // Then look for possible corrections in a delayed fashion
- if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) {
- mHandler.postUpdateOldSuggestions();
- }
- }
+ @Override
+ public void onWindowHidden() {
+ super.onWindowHidden();
+ KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
+ if (inputView != null) inputView.closing();
}
@Override
@@ -681,9 +668,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
LatinImeLogger.commit();
mKeyboardSwitcher.onAutoCorrectionStateChanged(false);
- mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging);
+ mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
- KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.closing();
if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites();
if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites();
@@ -692,8 +679,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onFinishInputView(boolean finishingInput) {
super.onFinishInputView(finishingInput);
- KeyboardView inputView = mKeyboardSwitcher.getInputView();
- if (inputView != null) inputView.setForeground(false);
+ KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
+ if (inputView != null) inputView.cancelAllMessages();
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestions();
mHandler.cancelUpdateOldSuggestions();
@@ -702,7 +689,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onUpdateExtractedText(int token, ExtractedText text) {
super.onUpdateExtractedText(token, text);
- mVoiceConnector.showPunctuationHintIfNecessary();
+ mVoiceProxy.showPunctuationHintIfNecessary();
}
@Override
@@ -723,67 +710,60 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
+ ", ce=" + candidatesEnd);
}
- mVoiceConnector.setCursorAndSelection(newSelEnd, newSelStart);
+ mVoiceProxy.setCursorAndSelection(newSelEnd, newSelStart);
// If the current selection in the text view changes, we should
// clear whatever candidate text we have.
final boolean selectionChanged = (newSelStart != candidatesEnd
|| newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart;
final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1;
- if (((mComposing.length() > 0 && mHasValidSuggestions)
- || mVoiceConnector.isVoiceInputHighlighted())
+ if (((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars)
+ || mVoiceProxy.isVoiceInputHighlighted())
&& (selectionChanged || candidatesCleared)) {
if (candidatesCleared) {
// If the composing span has been cleared, save the typed word in the history for
// recorrection before we reset the candidate strip. Then, we'll be able to show
// suggestions for recorrection right away.
- saveWordInHistory(mComposing);
+ mRecorrection.saveRecorrectionSuggestion(mWordComposer, mComposingStringBuilder);
+ }
+ mComposingStringBuilder.setLength(0);
+ mHasUncommittedTypedChars = false;
+ if (isCursorTouchingWord()) {
+ mHandler.cancelUpdateBigramPredictions();
+ mHandler.postUpdateSuggestions();
+ } else {
+ setPunctuationSuggestions();
}
- mComposing.setLength(0);
- mHasValidSuggestions = false;
- mHandler.postUpdateSuggestions();
TextEntryState.reset();
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.finishComposingText();
}
- mVoiceConnector.setVoiceInputHighlighted(false);
- } else if (!mHasValidSuggestions && !mJustAccepted) {
- if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) {
- if (TextEntryState.isAcceptedDefault())
- TextEntryState.reset();
- mJustAddedAutoSpace = false; // The user moved the cursor.
- }
+ mVoiceProxy.setVoiceInputHighlighted(false);
+ } else if (!mHasUncommittedTypedChars && !mExpectingUpdateSelection
+ && TextEntryState.isAcceptedDefault()) {
+ TextEntryState.reset();
+ }
+ if (!mExpectingUpdateSelection) {
+ mJustAddedMagicSpace = false; // The user moved the cursor.
+ mJustReplacedDoubleSpace = false;
}
- mJustAccepted = false;
+ mExpectingUpdateSelection = false;
mHandler.postUpdateShiftKeyState();
// Make a note of the cursor position
mLastSelectionStart = newSelStart;
mLastSelectionEnd = newSelEnd;
- if (mRecorrectionEnabled && isShowingSuggestionsStrip()) {
- // Don't look for corrections if the keyboard is not visible
- if (mKeyboardSwitcher.isInputViewShown()) {
- // Check if we should go in or out of correction mode.
- if (isSuggestionsRequested()
- && (candidatesStart == candidatesEnd || newSelStart != oldSelStart
- || TextEntryState.isRecorrecting())
- && (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) {
- if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) {
- mHandler.postUpdateOldSuggestions();
- } else {
- abortRecorrection(false);
- // Show the punctuation suggestions list if the current one is not
- // and if not showing "Touch again to save".
- if (mCandidateView != null && !isShowingPunctuationList()
- && !mCandidateView.isShowingAddToDictionaryHint()) {
- setPunctuationSuggestions();
- }
- }
- }
- }
- }
+ mRecorrection.updateRecorrectionSelection(mKeyboardSwitcher,
+ mCandidateView, candidatesStart, candidatesEnd, newSelStart,
+ newSelEnd, oldSelStart, mLastSelectionStart,
+ mLastSelectionEnd, mHasUncommittedTypedChars);
+ }
+
+ public void setLastSelection(int start, int end) {
+ mLastSelectionStart = start;
+ mLastSelectionEnd = end;
}
/**
@@ -796,7 +776,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
@Override
public void onExtractedTextClicked() {
- if (mRecorrectionEnabled && isSuggestionsRequested()) return;
+ if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return;
super.onExtractedTextClicked();
}
@@ -812,7 +792,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
@Override
public void onExtractedCursorMovement(int dx, int dy) {
- if (mRecorrectionEnabled && isSuggestionsRequested()) return;
+ if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return;
super.onExtractedCursorMovement(dx, dy);
}
@@ -827,8 +807,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mOptionsDialog.dismiss();
mOptionsDialog = null;
}
- mVoiceConnector.hideVoiceWindow(mConfigurationChanging);
- mWordHistory.clear();
+ mVoiceProxy.hideVoiceWindow(mConfigurationChanging);
+ mRecorrection.clearWordsInHistory();
super.hideWindow();
}
@@ -851,62 +831,63 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
SuggestedWords.Builder builder = new SuggestedWords.Builder()
.setApplicationSpecifiedCompletions(applicationSpecifiedCompletions)
- .setTypedWordValid(true)
- .setHasMinimalSuggestion(true);
+ .setTypedWordValid(false)
+ .setHasMinimalSuggestion(false);
// When in fullscreen mode, show completions generated by the application
setSuggestions(builder.build());
mBestWord = null;
- setCandidatesViewShown(true);
+ setSuggestionStripShown(true);
}
}
- private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) {
- // TODO: Remove this if we support candidates with hard keyboard
- if (onEvaluateInputViewShown()) {
- super.setCandidatesViewShown(shown
- && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true));
+ private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) {
+ // TODO: Modify this if we support candidates with hard keyboard
+ if (onEvaluateInputViewShown() && mCandidateViewContainer != null) {
+ final boolean shouldShowCandidates = shown
+ && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true);
+ if (isExtractViewShown()) {
+ // No need to have extra space to show the key preview.
+ mCandidateViewContainer.setMinimumHeight(0);
+ mCandidateViewContainer.setVisibility(
+ shouldShowCandidates ? View.VISIBLE : View.GONE);
+ } else {
+ // We must control the visibility of the suggestion strip in order to avoid clipped
+ // key previews, even when we don't show the suggestion strip.
+ mCandidateViewContainer.setVisibility(
+ shouldShowCandidates ? View.VISIBLE : View.INVISIBLE);
+ }
}
}
- @Override
- public void setCandidatesViewShown(boolean shown) {
- setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ );
+ private void setSuggestionStripShown(boolean shown) {
+ setSuggestionStripShownInternal(shown, /* needsInputViewShown */true);
}
@Override
public void onComputeInsets(InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
- if (!isFullscreenMode()) {
- outInsets.contentTopInsets = outInsets.visibleTopInsets;
- }
- KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ final KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
+ if (inputView == null || mCandidateViewContainer == null)
+ return;
+ final int containerHeight = mCandidateViewContainer.getHeight();
+ int touchY = containerHeight;
// Need to set touchable region only if input view is being shown
- if (inputView != null && mKeyboardSwitcher.isInputViewShown()) {
- final int x = 0;
- int y = 0;
- final int width = inputView.getWidth();
- int height = inputView.getHeight() + EXTENDED_TOUCHABLE_REGION_HEIGHT;
- if (mCandidateViewContainer != null) {
- ViewParent candidateParent = mCandidateViewContainer.getParent();
- if (candidateParent instanceof FrameLayout) {
- FrameLayout fl = (FrameLayout) candidateParent;
- if (fl != null) {
- // Check frame layout's visibility
- if (fl.getVisibility() == View.INVISIBLE) {
- y = fl.getHeight();
- height += y;
- } else if (fl.getVisibility() == View.VISIBLE) {
- height += fl.getHeight();
- }
- }
- }
+ if (mKeyboardSwitcher.isInputViewShown()) {
+ if (mCandidateViewContainer.getVisibility() == View.VISIBLE) {
+ touchY -= mCandidateStripHeight;
}
+ final int touchWidth = inputView.getWidth();
+ final int touchHeight = inputView.getHeight() + containerHeight
+ // Extend touchable region below the keyboard.
+ + EXTENDED_TOUCHABLE_REGION_HEIGHT;
if (DEBUG) {
- Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height);
+ Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth
+ + " height=" + touchHeight);
}
- outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
- outInsets.touchableRegion.set(x, y, width, height);
+ setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight);
}
+ outInsets.contentTopInsets = touchY;
+ outInsets.visibleTopInsets = touchY;
}
@Override
@@ -927,8 +908,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
- if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) {
- if (mKeyboardSwitcher.getInputView().handleBack()) {
+ if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getKeyboardView() != null) {
+ if (mKeyboardSwitcher.getKeyboardView().handleBack()) {
return true;
}
}
@@ -962,62 +943,46 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void commitTyped(InputConnection inputConnection) {
- if (mHasValidSuggestions) {
- mHasValidSuggestions = false;
- if (mComposing.length() > 0) {
- if (inputConnection != null) {
- inputConnection.commitText(mComposing, 1);
- }
- mCommittedLength = mComposing.length();
- TextEntryState.acceptedTyped(mComposing);
- addToAutoAndUserBigramDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED);
+ if (!mHasUncommittedTypedChars) return;
+ mHasUncommittedTypedChars = false;
+ if (mComposingStringBuilder.length() > 0) {
+ if (inputConnection != null) {
+ inputConnection.commitText(mComposingStringBuilder, 1);
}
- updateSuggestions();
+ mCommittedLength = mComposingStringBuilder.length();
+ TextEntryState.acceptedTyped(mComposingStringBuilder);
+ addToAutoAndUserBigramDictionaries(mComposingStringBuilder,
+ AutoDictionary.FREQUENCY_FOR_TYPED);
}
+ updateSuggestions();
}
public boolean getCurrentAutoCapsState() {
InputConnection ic = getCurrentInputConnection();
EditorInfo ei = getCurrentInputEditorInfo();
- if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) {
+ if (mSettingsValues.mAutoCap && ic != null && ei != null
+ && ei.inputType != InputType.TYPE_NULL) {
return ic.getCursorCapsMode(ei.inputType) != 0;
}
return false;
}
- private void swapPunctuationAndSpace() {
+ private void swapSwapperAndSpace() {
final InputConnection ic = getCurrentInputConnection();
if (ic == null) 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
- && isSentenceSeparator(lastTwo.charAt(1))) {
+ && lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0);
ic.commitText(lastTwo.charAt(1) + " ", 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
- mJustAddedAutoSpace = true;
- }
- }
-
- private void reswapPeriodAndSpace() {
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
- if (lastThree != null && lastThree.length() == 3
- && lastThree.charAt(0) == Keyboard.CODE_PERIOD
- && lastThree.charAt(1) == Keyboard.CODE_SPACE
- && lastThree.charAt(2) == Keyboard.CODE_PERIOD) {
- ic.beginBatchEdit();
- ic.deleteSurroundingText(3, 0);
- ic.commitText(" ..", 1);
- ic.endBatchEdit();
- mKeyboardSwitcher.updateShiftState();
}
}
- private void doubleSpace() {
+ private void maybeDoubleSpace() {
if (mCorrectionMode == Suggest.CORRECTION_NONE) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
@@ -1033,7 +998,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ic.commitText(". ", 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
- mJustAddedAutoSpace = true;
+ mJustReplacedDoubleSpace = true;
} else {
mHandler.startDoubleSpacesTimer();
}
@@ -1064,6 +1029,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
+ @Override
public boolean addWordToDictionary(String word) {
mUserDictionary.addWord(word, 128);
// Suggestion strip should be updated after the operation of adding word to the
@@ -1081,14 +1047,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void onSettingsKeyPressed() {
- if (!isShowingOptionDialog()) {
- if (!mConfigEnableShowSubtypeSettings) {
- showSubtypeSelectorAndSettings();
- } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) {
- showOptionsMenu();
- } else {
- launchSettings();
- }
+ if (isShowingOptionDialog())
+ return;
+ if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
+ showSubtypeSelectorAndSettings();
+ } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) {
+ showOptionsMenu();
+ } else {
+ launchSettings();
}
}
@@ -1115,22 +1081,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mLastKeyTime = when;
KeyboardSwitcher switcher = mKeyboardSwitcher;
- final boolean accessibilityEnabled = switcher.isAccessibilityEnabled();
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
+ final boolean lastStateOfJustReplacedDoubleSpace = mJustReplacedDoubleSpace;
+ mJustReplacedDoubleSpace = false;
switch (primaryCode) {
case Keyboard.CODE_DELETE:
- handleBackspace();
+ handleBackspace(lastStateOfJustReplacedDoubleSpace);
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 || accessibilityEnabled)
+ if (!distinctMultiTouch)
switcher.toggleShift();
break;
case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
// Symbol key is handled in onPress() when device has distinct multi-touch panel.
- if (!distinctMultiTouch || accessibilityEnabled)
+ if (!distinctMultiTouch)
switcher.changeKeyboardMode();
break;
case Keyboard.CODE_CANCEL:
@@ -1144,32 +1112,37 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case Keyboard.CODE_SETTINGS_LONGPRESS:
onSettingsKeyLongPressed();
break;
- case Keyboard.CODE_NEXT_LANGUAGE:
- toggleLanguage(false, true);
+ case LatinKeyboard.CODE_NEXT_LANGUAGE:
+ toggleLanguage(true);
break;
- case Keyboard.CODE_PREV_LANGUAGE:
- toggleLanguage(false, false);
+ case LatinKeyboard.CODE_PREV_LANGUAGE:
+ toggleLanguage(false);
break;
case Keyboard.CODE_CAPSLOCK:
switcher.toggleCapsLock();
break;
- case Keyboard.CODE_VOICE:
+ case Keyboard.CODE_SHORTCUT:
mSubtypeSwitcher.switchToShortcutIME();
break;
case Keyboard.CODE_TAB:
handleTab();
+ // There are two cases for tab. Either we send a "next" event, that may change the
+ // focus but will never move the cursor. Or, we send a real tab keycode, which some
+ // applications may accept or ignore, and we don't know whether this will move the
+ // cursor or not. So actually, we don't really know.
+ // So to go with the safer option, we'd rather behave as if the user moved the
+ // cursor when they didn't than the opposite. We also expect that most applications
+ // will actually use tab only for focus movement.
+ // To sum it up: do not update mExpectingUpdateSelection here.
break;
default:
- if (primaryCode != Keyboard.CODE_ENTER) {
- mJustAddedAutoSpace = false;
- }
- RingCharBuffer.getInstance().push((char)primaryCode, x, y);
- LatinImeLogger.logOnInputChar();
- if (isWordSeparator(primaryCode)) {
- handleSeparator(primaryCode);
+ if (mSettingsValues.isWordSeparator(primaryCode)) {
+ handleSeparator(primaryCode, x, y);
} else {
handleCharacter(primaryCode, keyCodes, x, y);
}
+ mExpectingUpdateSelection = true;
+ break;
}
switcher.onKey(primaryCode);
// Reset after any single keystroke
@@ -1178,10 +1151,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onTextInput(CharSequence text) {
- mVoiceConnector.commitVoiceInput();
+ mVoiceProxy.commitVoiceInput();
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
- abortRecorrection(false);
+ mRecorrection.abortRecorrection(false);
ic.beginBatchEdit();
commitTyped(ic);
maybeRemovePreviousPeriod(text);
@@ -1189,7 +1162,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY);
- mJustAddedAutoSpace = false;
+ mJustAddedMagicSpace = false;
mEnteredText = text;
}
@@ -1199,31 +1172,36 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mKeyboardSwitcher.onCancelInput();
}
- private void handleBackspace() {
- if (mVoiceConnector.logAndRevertVoiceInput()) return;
+ private void handleBackspace(boolean justReplacedDoubleSpace) {
+ if (mVoiceProxy.logAndRevertVoiceInput()) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
- mVoiceConnector.handleBackspace();
+ mVoiceProxy.handleBackspace();
- boolean deleteChar = false;
- if (mHasValidSuggestions) {
- final int length = mComposing.length();
+ final boolean deleteChar = !mHasUncommittedTypedChars;
+ if (mHasUncommittedTypedChars) {
+ final int length = mComposingStringBuilder.length();
if (length > 0) {
- mComposing.delete(length - 1, length);
- mWord.deleteLast();
- ic.setComposingText(mComposing, 1);
- if (mComposing.length() == 0) {
- mHasValidSuggestions = false;
+ mComposingStringBuilder.delete(length - 1, length);
+ mWordComposer.deleteLast();
+ ic.setComposingText(mComposingStringBuilder, 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.
+ mHandler.postUpdateBigramPredictions();
+ } else {
+ // length > 1, so we still have letters to deduce a suggestion from.
+ mHandler.postUpdateSuggestions();
}
- mHandler.postUpdateSuggestions();
} else {
ic.deleteSurroundingText(1, 0);
}
- } else {
- deleteChar = true;
}
mHandler.postUpdateShiftKeyState();
@@ -1233,6 +1211,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ic.endBatchEdit();
return;
}
+ if (justReplacedDoubleSpace) {
+ if (revertDoubleSpace()) {
+ ic.endBatchEdit();
+ return;
+ }
+ }
if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
ic.deleteSurroundingText(mEnteredText.length(), 0);
@@ -1245,7 +1229,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// 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(deleteChar);
+ revertLastWord(true /* deleteChar */);
} else {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
if (mDeleteCount > DELETE_ACCELERATE_AT) {
@@ -1258,9 +1242,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void handleTab() {
final int imeOptions = getCurrentInputEditorInfo().imeOptions;
- final int navigationFlags =
- EditorInfo.IME_FLAG_NAVIGATE_NEXT | EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS;
- if ((imeOptions & navigationFlags) == 0) {
+ if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
+ && !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB);
return;
}
@@ -1271,42 +1254,37 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// True if keyboard is in either chording shift or manual temporary upper case mode.
final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase();
- if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0
+ if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
&& !isManualTemporaryUpperCase) {
- ic.performEditorAction(EditorInfo.IME_ACTION_NEXT);
- } else if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0
+ EditorInfoCompatUtils.performEditorActionNext(ic);
+ } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)
&& isManualTemporaryUpperCase) {
- ic.performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
- }
- }
-
- private void abortRecorrection(boolean force) {
- if (force || TextEntryState.isRecorrecting()) {
- TextEntryState.onAbortRecorrection();
- setCandidatesViewShown(isCandidateStripVisible());
- getCurrentInputConnection().finishComposingText();
- clearSuggestions();
+ EditorInfoCompatUtils.performEditorActionPrevious(ic);
}
}
private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) {
- mVoiceConnector.handleCharacter();
+ mVoiceProxy.handleCharacter();
+
+ if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceStripper(primaryCode)) {
+ removeTrailingSpace();
+ }
- if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) {
- abortRecorrection(false);
+ if (mLastSelectionStart == mLastSelectionEnd) {
+ mRecorrection.abortRecorrection(false);
}
int code = primaryCode;
if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) {
- if (!mHasValidSuggestions) {
- mHasValidSuggestions = true;
- mComposing.setLength(0);
- saveWordInHistory(mBestWord);
- mWord.reset();
+ if (!mHasUncommittedTypedChars) {
+ mHasUncommittedTypedChars = true;
+ mComposingStringBuilder.setLength(0);
+ mRecorrection.saveRecorrectionSuggestion(mWordComposer, mBestWord);
+ mWordComposer.reset();
clearSuggestions();
}
}
- KeyboardSwitcher switcher = mKeyboardSwitcher;
+ final KeyboardSwitcher switcher = mKeyboardSwitcher;
if (switcher.isShiftedOrShiftLocked()) {
if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
|| keyCodes[0] > Character.MAX_CODE_POINT) {
@@ -1314,46 +1292,55 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
code = keyCodes[0];
if (switcher.isAlphabetMode() && Character.isLowerCase(code)) {
- int upperCaseCode = Character.toUpperCase(code);
- if (upperCaseCode != code) {
- code = upperCaseCode;
+ // 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.
- String upperCase = new String(new int[] {code}, 0, 1).toUpperCase();
- onTextInput(upperCase);
+ onTextInput(upperCaseString);
return;
}
}
}
- if (mHasValidSuggestions) {
- if (mComposing.length() == 0 && switcher.isAlphabetMode()
+ if (mHasUncommittedTypedChars) {
+ if (mComposingStringBuilder.length() == 0 && switcher.isAlphabetMode()
&& switcher.isShiftedOrShiftLocked()) {
- mWord.setFirstCharCapitalized(true);
+ mWordComposer.setFirstCharCapitalized(true);
}
- mComposing.append((char) code);
- mWord.add(code, keyCodes, x, y);
+ mComposingStringBuilder.append((char) code);
+ mWordComposer.add(code, keyCodes, x, y);
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
// If it's the first letter, make note of auto-caps state
- if (mWord.size() == 1) {
- mWord.setAutoCapitalized(getCurrentAutoCapsState());
+ if (mWordComposer.size() == 1) {
+ mWordComposer.setAutoCapitalized(getCurrentAutoCapsState());
}
- ic.setComposingText(mComposing, 1);
+ ic.setComposingText(mComposingStringBuilder, 1);
}
mHandler.postUpdateSuggestions();
} else {
sendKeyChar((char)code);
}
+ if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceSwapper(primaryCode)) {
+ swapSwapperAndSpace();
+ } else {
+ mJustAddedMagicSpace = false;
+ }
+
switcher.updateShiftState();
if (LatinIME.PERF_DEBUG) measureCps();
- TextEntryState.typedCharacter((char) code, isWordSeparator(code));
+ TextEntryState.typedCharacter((char) code, mSettingsValues.isWordSeparator(code), x, y);
}
- private void handleSeparator(int primaryCode) {
- mVoiceConnector.handleSeparator();
+ private void handleSeparator(int primaryCode, int x, int y) {
+ mVoiceProxy.handleSeparator();
// Should dismiss the "Touch again to save" message when handling separator
if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) {
+ mHandler.cancelUpdateBigramPredictions();
mHandler.postUpdateSuggestions();
}
@@ -1362,54 +1349,61 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.beginBatchEdit();
- abortRecorrection(false);
+ mRecorrection.abortRecorrection(false);
}
- if (mHasValidSuggestions) {
+ if (mHasUncommittedTypedChars) {
// 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.
- if (mAutoCorrectOn && primaryCode != '\'') {
- pickedDefault = pickDefaultSuggestion();
- // Picked the suggestion by the space key. We consider this
- // as "added an auto space".
- if (primaryCode == Keyboard.CODE_SPACE) {
- mJustAddedAutoSpace = true;
- }
+ final boolean shouldAutoCorrect =
+ (mSettingsValues.mAutoCorrectEnabled || mSettingsValues.mQuickFixes)
+ && !mInputTypeNoAutoCorrect && mHasDictionary;
+ if (shouldAutoCorrect && primaryCode != Keyboard.CODE_SINGLE_QUOTE) {
+ pickedDefault = pickDefaultSuggestion(primaryCode);
} else {
commitTyped(ic);
}
}
- if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) {
- removeTrailingSpace();
- mJustAddedAutoSpace = false;
- }
- sendKeyChar((char)primaryCode);
- // Handle the case of ". ." -> " .." with auto-space if necessary
- // before changing the TextEntryState.
- if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) {
- reswapPeriodAndSpace();
+ 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);
}
- TextEntryState.typedCharacter((char) primaryCode, true);
- if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) {
- swapPunctuationAndSpace();
- } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
- doubleSpace();
+ if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
+ maybeDoubleSpace();
}
+
+ TextEntryState.typedCharacter((char) primaryCode, true, x, y);
+
if (pickedDefault) {
- CharSequence typedWord = mWord.getTypedWord();
+ CharSequence typedWord = mWordComposer.getTypedWord();
TextEntryState.backToAcceptedDefault(typedWord);
if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) {
- if (ic != null) {
- CorrectionInfo correctionInfo = new CorrectionInfo(
- mLastSelectionEnd - typedWord.length(), typedWord, mBestWord);
- ic.commitCorrection(correctionInfo);
- }
+ InputConnectionCompatUtils.commitCorrection(
+ ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord);
if (mCandidateView != null)
mCandidateView.onAutoCorrectionInverted(mBestWord);
}
+ }
+ if (Keyboard.CODE_SPACE == primaryCode) {
+ if (!isCursorTouchingWord()) {
+ mHandler.cancelUpdateSuggestions();
+ mHandler.cancelUpdateOldSuggestions();
+ mHandler.postUpdateBigramPredictions();
+ }
+ } else {
+ // Set punctuation right away. onUpdateSelection will fire but tests whether it is
+ // already displayed or not, so it's okay.
setPunctuationSuggestions();
}
mKeyboardSwitcher.updateShiftState();
@@ -1420,45 +1414,29 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void handleClose() {
commitTyped(getCurrentInputConnection());
- mVoiceConnector.handleClose();
+ mVoiceProxy.handleClose();
requestHideSelf(0);
- LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null)
inputView.closing();
}
- private void saveWordInHistory(CharSequence result) {
- if (mWord.size() <= 1) {
- return;
- }
- // Skip if result is null. It happens in some edge case.
- if (TextUtils.isEmpty(result)) {
- return;
- }
-
- // Make a copy of the CharSequence, since it is/could be a mutable CharSequence
- final String resultCopy = result.toString();
- TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy,
- new WordComposer(mWord));
- mWordHistory.add(entry);
- }
-
- private boolean isSuggestionsRequested() {
+ public boolean isSuggestionsRequested() {
return mIsSettingsSuggestionStripOn
&& (mCorrectionMode > 0 || isShowingSuggestionsStrip());
}
- private boolean isShowingPunctuationList() {
- return mSuggestPuncList == mCandidateView.getSuggestions();
+ public boolean isShowingPunctuationList() {
+ return mSettingsValues.mSuggestPuncList == mCandidateView.getSuggestions();
}
- private boolean isShowingSuggestionsStrip() {
+ public boolean isShowingSuggestionsStrip() {
return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE)
|| (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE
&& mOrientation == Configuration.ORIENTATION_PORTRAIT);
}
- private boolean isCandidateStripVisible() {
+ public boolean isCandidateStripVisible() {
if (mCandidateView == null)
return false;
if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting())
@@ -1474,7 +1452,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (DEBUG) {
Log.d(TAG, "Switch to keyboard view.");
}
- View v = mKeyboardSwitcher.getInputView();
+ View v = mKeyboardSwitcher.getKeyboardView();
if (v != null) {
// Confirms that the keyboard view doesn't have parent view.
ViewParent p = v.getParent();
@@ -1483,7 +1461,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
setInputView(v);
}
- setCandidatesViewShown(isCandidateStripVisible());
+ setSuggestionStripShown(isCandidateStripVisible());
updateInputViewShown();
mHandler.postUpdateSuggestions();
}
@@ -1493,62 +1471,44 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void setSuggestions(SuggestedWords words) {
- if (mVoiceConnector.getAndResetIsShowingHint()) {
- setCandidatesView(mCandidateViewContainer);
- }
-
if (mCandidateView != null) {
mCandidateView.setSuggestions(words);
- if (mCandidateView.isConfigCandidateHighlightFontColorEnabled()) {
- mKeyboardSwitcher.onAutoCorrectionStateChanged(
- words.hasWordAboveAutoCorrectionScoreThreshold());
- }
+ mKeyboardSwitcher.onAutoCorrectionStateChanged(
+ words.hasWordAboveAutoCorrectionScoreThreshold());
}
}
public void updateSuggestions() {
// Check if we have a suggestion engine attached.
if ((mSuggest == null || !isSuggestionsRequested())
- && !mVoiceConnector.isVoiceInputHighlighted()) {
+ && !mVoiceProxy.isVoiceInputHighlighted()) {
return;
}
- if (!mHasValidSuggestions) {
+ if (!mHasUncommittedTypedChars) {
setPunctuationSuggestions();
return;
}
- showSuggestions(mWord);
- }
- private SuggestedWords.Builder getTypedSuggestions(WordComposer word) {
- return mSuggest.getSuggestedWordBuilder(mKeyboardSwitcher.getInputView(), word, null);
- }
-
- private void showCorrections(WordAlternatives alternatives) {
- SuggestedWords.Builder builder = alternatives.getAlternatives();
- builder.setTypedWordValid(false).setHasMinimalSuggestion(false);
- showSuggestions(builder.build(), alternatives.getOriginalWord());
- }
-
- private void showSuggestions(WordComposer word) {
+ final WordComposer wordComposer = mWordComposer;
// TODO: May need a better way of retrieving previous word
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
- mWordSeparators);
+ mSettingsValues.mWordSeparators);
SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
- mKeyboardSwitcher.getInputView(), word, prevWord);
+ mKeyboardSwitcher.getKeyboardView(), wordComposer, prevWord);
- boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection();
- final CharSequence typedWord = word.getTypedWord();
+ boolean autoCorrectionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection();
+ final CharSequence typedWord = wordComposer.getTypedWord();
// Here, we want to promote a whitelisted word if exists.
final boolean typedWordValid = AutoCorrection.isValidWordForAutoCorrection(
mSuggest.getUnigramDictionaries(), typedWord, preferCapitalization());
if (mCorrectionMode == Suggest.CORRECTION_FULL
|| mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) {
- correctionAvailable |= typedWordValid;
+ autoCorrectionAvailable |= typedWordValid;
}
// Don't auto-correct words with multiple capital letter
- correctionAvailable &= !word.isMostlyCaps();
- correctionAvailable &= !TextEntryState.isRecorrecting();
+ autoCorrectionAvailable &= !wordComposer.isMostlyCaps();
+ autoCorrectionAvailable &= !TextEntryState.isRecorrecting();
// 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
@@ -1556,19 +1516,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// in most cases, suggestion count is 1 when typed word's length is 1, but we do always
// need to clear the previous state when the user starts typing a word (i.e. typed word's
// length == 1).
- if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid
- || mCandidateView.isShowingAddToDictionaryHint()) {
- builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable);
- } else {
- final SuggestedWords previousSuggestions = mCandidateView.getSuggestions();
- if (previousSuggestions == mSuggestPuncList)
- return;
- builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+ if (typedWord != null) {
+ if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid
+ || mCandidateView.isShowingAddToDictionaryHint()) {
+ builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(
+ autoCorrectionAvailable);
+ } else {
+ final SuggestedWords previousSuggestions = mCandidateView.getSuggestions();
+ if (previousSuggestions == mSettingsValues.mSuggestPuncList)
+ return;
+ builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+ }
}
showSuggestions(builder.build(), typedWord);
}
- private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) {
+ public void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) {
setSuggestions(suggestedWords);
if (suggestedWords.size() > 0) {
if (Utils.shouldBlockedBySafetyNetForAutoCorrection(suggestedWords, mSuggest)) {
@@ -1581,30 +1544,31 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
mBestWord = null;
}
- setCandidatesViewShown(isCandidateStripVisible());
+ setSuggestionStripShown(isCandidateStripVisible());
}
- private boolean pickDefaultSuggestion() {
+ private boolean pickDefaultSuggestion(int separatorCode) {
// Complete any pending candidate query first
if (mHandler.hasPendingUpdateSuggestions()) {
mHandler.cancelUpdateSuggestions();
updateSuggestions();
}
if (mBestWord != null && mBestWord.length() > 0) {
- TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord);
- mJustAccepted = true;
- pickSuggestion(mBestWord);
+ TextEntryState.acceptedDefault(mWordComposer.getTypedWord(), mBestWord, separatorCode);
+ mExpectingUpdateSelection = true;
+ commitBestWord(mBestWord);
// Add the word to the auto dictionary if it's not a known word
addToAutoAndUserBigramDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED);
return true;
-
}
return false;
}
+ @Override
public void pickSuggestionManually(int index, CharSequence suggestion) {
SuggestedWords suggestions = mCandidateView.getSuggestions();
- mVoiceConnector.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators);
+ mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion,
+ mSettingsValues.mWordSeparators);
final boolean recorrecting = TextEntryState.isRecorrecting();
InputConnection ic = getCurrentInputConnection();
@@ -1629,36 +1593,50 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// If this is a punctuation, apply it through the normal key press
- if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0))
- || isSuggestedPunctuation(suggestion.charAt(0)))) {
+ if (suggestion.length() == 1 && (mSettingsValues.isWordSeparator(suggestion.charAt(0))
+ || mSettingsValues.isSuggestedPunctuation(suggestion.charAt(0)))) {
// 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 char primaryCode = suggestion.charAt(0);
+ 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;
onCodeInput(primaryCode, new int[] { primaryCode },
KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
+ mJustAddedMagicSpace = oldMagicSpace;
if (ic != null) {
ic.endBatchEdit();
}
return;
}
- mJustAccepted = true;
- pickSuggestion(suggestion);
+ 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();
+ }
+ mExpectingUpdateSelection = true;
+ commitBestWord(suggestion);
// Add the word to the auto dictionary if it's not a known word
if (index == 0) {
addToAutoAndUserBigramDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED);
} else {
addToOnlyBigramDictionary(suggestion, 1);
}
- LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(),
- index, suggestions.mWords);
- TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
+ LatinImeLogger.logOnManualSuggestion(mComposingStringBuilder.toString(),
+ suggestion.toString(), index, suggestions.mWords);
+ TextEntryState.acceptedSuggestion(mComposingStringBuilder.toString(), suggestion);
// Follow it with a space
- if (mAutoSpace && !recorrecting) {
- sendSpace();
- mJustAddedAutoSpace = true;
+ if (mShouldInsertMagicSpace && !recorrecting) {
+ sendMagicSpace();
}
// We should show the hint if the user pressed the first entry AND either:
@@ -1680,13 +1658,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// 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);
- setPunctuationSuggestions();
- } else if (!showingAddToDictionaryHint) {
+ TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true,
+ 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.
- clearSuggestions();
- mHandler.postUpdateOldSuggestions();
+ updateBigramPredictions();
+ // 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) {
mCandidateView.showAddToDictionaryHint(suggestion);
@@ -1697,109 +1678,51 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
/**
- * Commits the chosen word to the text field and saves it for later
- * retrieval.
- * @param suggestion the suggestion picked by the user to be committed to
- * the text field
+ * Commits the chosen word to the text field and saves it for later retrieval.
*/
- private void pickSuggestion(CharSequence suggestion) {
+ private void commitBestWord(CharSequence bestWord) {
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
- mVoiceConnector.rememberReplacedWord(suggestion, mWordSeparators);
- ic.commitText(suggestion, 1);
+ mVoiceProxy.rememberReplacedWord(bestWord, mSettingsValues.mWordSeparators);
+ SuggestedWords suggestedWords = mCandidateView.getSuggestions();
+ ic.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
+ this, bestWord, suggestedWords), 1);
}
- saveWordInHistory(suggestion);
- mHasValidSuggestions = false;
- mCommittedLength = suggestion.length();
+ mRecorrection.saveRecorrectionSuggestion(mWordComposer, bestWord);
+ mHasUncommittedTypedChars = false;
+ mCommittedLength = bestWord.length();
}
- /**
- * Tries to apply any typed alternatives for the word if we have any cached alternatives,
- * otherwise tries to find new corrections and completions for the word.
- * @param touching The word that the cursor is touching, with position information
- * @return true if an alternative was found, false otherwise.
- */
- private boolean applyTypedAlternatives(EditingUtils.SelectedWord touching) {
- // If we didn't find a match, search for result in typed word history
- WordComposer foundWord = null;
- WordAlternatives alternatives = null;
- // Search old suggestions to suggest re-corrected suggestions.
- for (WordAlternatives entry : mWordHistory) {
- if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) {
- if (entry instanceof TypedWordAlternatives) {
- foundWord = ((TypedWordAlternatives) entry).word;
- }
- alternatives = entry;
- break;
- }
- }
- // If we didn't find a match, at least suggest corrections as re-corrected suggestions.
- if (foundWord == null
- && (AutoCorrection.isValidWord(
- mSuggest.getUnigramDictionaries(), touching.mWord, true))) {
- foundWord = new WordComposer();
- for (int i = 0; i < touching.mWord.length(); i++) {
- foundWord.add(touching.mWord.charAt(i), new int[] {
- touching.mWord.charAt(i)
- }, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
- }
- foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0)));
- }
- // Found a match, show suggestions
- if (foundWord != null || alternatives != null) {
- if (alternatives == null) {
- alternatives = new TypedWordAlternatives(touching.mWord, foundWord);
- }
- showCorrections(alternatives);
- if (foundWord != null) {
- mWord = new WordComposer(foundWord);
- } else {
- mWord.reset();
- }
- return true;
- }
- return false;
- }
+ private static final WordComposer sEmptyWordComposer = new WordComposer();
+ public void updateBigramPredictions() {
+ if (mSuggest == null || !isSuggestionsRequested())
+ return;
- private void setOldSuggestions() {
- mVoiceConnector.setShowingVoiceSuggestions(false);
- if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) {
+ if (!mSettingsValues.mBigramPredictionEnabled) {
+ setPunctuationSuggestions();
return;
}
- InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- if (!mHasValidSuggestions) {
- // Extract the selected or touching text
- EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic,
- mLastSelectionStart, mLastSelectionEnd, mWordSeparators);
-
- if (touching != null && touching.mWord.length() > 1) {
- ic.beginBatchEdit();
- if (!mVoiceConnector.applyVoiceAlternatives(touching)
- && !applyTypedAlternatives(touching)) {
- abortRecorrection(true);
- } else {
- TextEntryState.selectedForRecorrection();
- EditingUtils.underlineWord(ic, touching);
- }
+ final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(),
+ mSettingsValues.mWordSeparators);
+ SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
+ mKeyboardSwitcher.getKeyboardView(), sEmptyWordComposer, prevWord);
- ic.endBatchEdit();
- } else {
- abortRecorrection(true);
- setPunctuationSuggestions(); // Show the punctuation suggestions list
- }
+ if (builder.size() > 0) {
+ // Explicitly supply an empty typed word (the no-second-arg version of
+ // showSuggestions will retrieve the word near the cursor, we don't want that here)
+ showSuggestions(builder.build(), "");
} else {
- abortRecorrection(true);
+ if (!isShowingPunctuationList()) setPunctuationSuggestions();
}
}
- private void setPunctuationSuggestions() {
- setSuggestions(mSuggestPuncList);
- setCandidatesViewShown(isCandidateStripVisible());
+ public void setPunctuationSuggestions() {
+ setSuggestions(mSettingsValues.mSuggestPuncList);
+ setSuggestionStripShown(isCandidateStripVisible());
}
private void addToAutoAndUserBigramDictionaries(CharSequence suggestion, int frequencyDelta) {
@@ -1837,27 +1760,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
if (mUserBigramDictionary != null) {
+ // We don't want to register as bigrams words separated by a separator.
+ // For example "I will, and you too" : we don't want the pair ("will" "and") to be
+ // a bigram.
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
- mSentenceSeparators);
+ mSettingsValues.mWordSeparators);
if (!TextUtils.isEmpty(prevWord)) {
mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString());
}
}
}
- private boolean isCursorTouchingWord() {
+ public boolean isCursorTouchingWord() {
InputConnection ic = getCurrentInputConnection();
if (ic == null) return false;
CharSequence toLeft = ic.getTextBeforeCursor(1, 0);
CharSequence toRight = ic.getTextAfterCursor(1, 0);
if (!TextUtils.isEmpty(toLeft)
- && !isWordSeparator(toLeft.charAt(0))
- && !isSuggestedPunctuation(toLeft.charAt(0))) {
+ && !mSettingsValues.isWordSeparator(toLeft.charAt(0))
+ && !mSettingsValues.isSuggestedPunctuation(toLeft.charAt(0))) {
return true;
}
if (!TextUtils.isEmpty(toRight)
- && !isWordSeparator(toRight.charAt(0))
- && !isSuggestedPunctuation(toRight.charAt(0))) {
+ && !mSettingsValues.isWordSeparator(toRight.charAt(0))
+ && !mSettingsValues.isSuggestedPunctuation(toRight.charAt(0))) {
return true;
}
return false;
@@ -1868,85 +1794,98 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return TextUtils.equals(text, beforeText);
}
- public void revertLastWord(boolean deleteChar) {
- final int length = mComposing.length();
- if (!mHasValidSuggestions && length > 0) {
- final InputConnection ic = getCurrentInputConnection();
- final CharSequence punctuation = ic.getTextBeforeCursor(1, 0);
- if (deleteChar) ic.deleteSurroundingText(1, 0);
- int toDelete = mCommittedLength;
- final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
- if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) {
- toDelete--;
- }
- ic.deleteSurroundingText(toDelete, 0);
- // Re-insert punctuation only when the deleted character was word separator and the
- // composing text wasn't equal to the auto-corrected text.
- if (deleteChar
- && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0))
- && !TextUtils.equals(mComposing, toTheLeft)) {
- ic.commitText(mComposing, 1);
- TextEntryState.acceptedTyped(mComposing);
- ic.commitText(punctuation, 1);
- TextEntryState.typedCharacter(punctuation.charAt(0), true);
- // Clear composing text
- mComposing.setLength(0);
- } else {
- mHasValidSuggestions = true;
- ic.setComposingText(mComposing, 1);
- TextEntryState.backspace();
- }
- mHandler.postUpdateSuggestions();
- } else {
+ private void revertLastWord(boolean deleteChar) {
+ if (mHasUncommittedTypedChars || mComposingStringBuilder.length() <= 0) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ return;
}
- }
- protected String getWordSeparators() {
- return mWordSeparators;
+ final InputConnection ic = getCurrentInputConnection();
+ final CharSequence punctuation = ic.getTextBeforeCursor(1, 0);
+ if (deleteChar) ic.deleteSurroundingText(1, 0);
+ final CharSequence textToTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
+ final int toDeleteLength = (!TextUtils.isEmpty(textToTheLeft)
+ && mSettingsValues.isWordSeparator(textToTheLeft.charAt(0)))
+ ? mCommittedLength - 1 : mCommittedLength;
+ ic.deleteSurroundingText(toDeleteLength, 0);
+
+ // Re-insert punctuation only when the deleted character was word separator and the
+ // composing text wasn't equal to the auto-corrected text.
+ if (deleteChar
+ && !TextUtils.isEmpty(punctuation)
+ && mSettingsValues.isWordSeparator(punctuation.charAt(0))
+ && !TextUtils.equals(mComposingStringBuilder, textToTheLeft)) {
+ ic.commitText(mComposingStringBuilder, 1);
+ TextEntryState.acceptedTyped(mComposingStringBuilder);
+ ic.commitText(punctuation, 1);
+ TextEntryState.typedCharacter(punctuation.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();
+ }
+ mHandler.cancelUpdateBigramPredictions();
+ mHandler.postUpdateSuggestions();
}
- public boolean isWordSeparator(int code) {
- String separators = getWordSeparators();
- return separators.contains(String.valueOf((char)code));
+ private boolean revertDoubleSpace() {
+ mHandler.cancelDoubleSpacesTimer();
+ final InputConnection ic = getCurrentInputConnection();
+ // 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))
+ return false;
+ ic.beginBatchEdit();
+ ic.deleteSurroundingText(2, 0);
+ ic.commitText(" ", 1);
+ ic.endBatchEdit();
+ return true;
}
- private boolean isSentenceSeparator(int code) {
- return mSentenceSeparators.contains(String.valueOf((char)code));
+ public boolean isWordSeparator(int code) {
+ return mSettingsValues.isWordSeparator(code);
}
- private void sendSpace() {
+ private void sendMagicSpace() {
sendKeyChar((char)Keyboard.CODE_SPACE);
+ mJustAddedMagicSpace = true;
mKeyboardSwitcher.updateShiftState();
}
public boolean preferCapitalization() {
- return mWord.isFirstCharCapitalized();
+ return mWordComposer.isFirstCharCapitalized();
}
- // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID
+ // Notify that language or mode have been changed and toggleLanguage will update KeyboardID
// according to new language or mode.
public void onRefreshKeyboard() {
- toggleLanguage(true, true);
- }
-
- // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER.
- private void toggleLanguage(boolean reset, boolean next) {
- if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) {
- mSubtypeSwitcher.toggleLanguage(reset, next);
+ if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
+ // Before Honeycomb, Voice IME is in LatinIME and it changes the current input view,
+ // so that we need to re-create the keyboard input view here.
+ setInputView(mKeyboardSwitcher.onCreateInputView());
}
// Reload keyboard because the current language has been changed.
mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(),
- mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceConnector.isVoiceButtonEnabled(),
- mVoiceConnector.isVoiceButtonOnPrimary());
+ mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(),
+ mVoiceProxy.isVoiceButtonOnPrimary());
initSuggest();
+ loadSettings();
mKeyboardSwitcher.updateShiftState();
}
- @Override
- public void onSwipeDown() {
- if (mConfigSwipeDownDismissKeyboardEnabled)
- handleClose();
+ // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER.
+ private void toggleLanguage(boolean next) {
+ if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) {
+ mSubtypeSwitcher.toggleLanguage(next);
+ }
+ // The following is necessary because on API levels < 10, we don't get notified when
+ // subtype changes.
+ if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED)
+ onRefreshKeyboard();
}
@Override
@@ -1964,21 +1903,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
switcher.onOtherKeyPressed();
}
- mAccessibilityUtils.onPress(primaryCode, switcher);
}
@Override
public void onRelease(int primaryCode, boolean withSliding) {
KeyboardSwitcher switcher = mKeyboardSwitcher;
// Reset any drag flags in the keyboard
- switcher.keyReleased();
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();
}
- mAccessibilityUtils.onRelease(primaryCode, switcher);
}
@@ -2001,7 +1937,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
if (mAudioManager != null) {
- mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL);
+ mSilentModeOn = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL);
}
}
@@ -2009,11 +1945,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// if mAudioManager is null, we don't have the ringer state yet
// mAudioManager will be set by updateRingerMode
if (mAudioManager == null) {
- if (mKeyboardSwitcher.getInputView() != null) {
+ if (mKeyboardSwitcher.getKeyboardView() != null) {
updateRingerMode();
}
}
- if (mSoundOn && !mSilentMode) {
+ if (isSoundOn()) {
// FIXME: Volume and enable should come from UI settings
// FIXME: These should be triggered after auto-repeat logic
int sound = AudioManager.FX_KEYPRESS_STANDARD;
@@ -2033,10 +1969,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void vibrate() {
- if (!mVibrateOn) {
+ if (!mSettingsValues.mVibrateOn) {
return;
}
- LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) {
inputView.performHapticFeedback(
HapticFeedbackConstants.KEYBOARD_TAP,
@@ -2044,28 +1980,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- public void promoteToUserDictionary(String word, int frequency) {
- if (mUserDictionary.isValidWord(word)) return;
- mUserDictionary.addWord(word, frequency);
- }
-
public WordComposer getCurrentWord() {
- return mWord;
+ return mWordComposer;
}
- public boolean getPopupOn() {
- return mPopupOn;
+ boolean isSoundOn() {
+ return mSettingsValues.mSoundOn && !mSilentModeOn;
}
private void updateCorrectionMode() {
// TODO: cleanup messy flags
mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false;
- mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
- && !mInputTypeNoAutoCorrect && mHasDictionary;
- mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled)
+ final boolean shouldAutoCorrect = (mSettingsValues.mAutoCorrectEnabled
+ || mSettingsValues.mQuickFixes) && !mInputTypeNoAutoCorrect && mHasDictionary;
+ mCorrectionMode = (shouldAutoCorrect && mSettingsValues.mAutoCorrectEnabled)
? Suggest.CORRECTION_FULL
- : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
- mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled)
+ : (shouldAutoCorrect ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
+ mCorrectionMode = (mSettingsValues.mBigramSuggestionEnabled && shouldAutoCorrect
+ && mSettingsValues.mAutoCorrectEnabled)
? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode;
if (mSuggest != null) {
mSuggest.setCorrectionMode(mCorrectionMode);
@@ -2074,12 +2006,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void updateAutoTextEnabled() {
if (mSuggest == null) return;
- mSuggest.setQuickFixesEnabled(mQuickFixes
+ mSuggest.setQuickFixesEnabled(mSettingsValues.mQuickFixes
&& SubtypeSwitcher.getInstance().isSystemLanguageSameAsInputLanguage());
}
- private void updateSuggestionVisibility(SharedPreferences prefs) {
- final Resources res = mResources;
+ 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));
@@ -2107,121 +2038,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
startActivity(intent);
}
- private void loadSettings(EditorInfo attribute) {
- // Get the settings preferences
- final SharedPreferences prefs = mPrefs;
- Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
- mVibrateOn = vibrator != null && vibrator.hasVibrator()
- && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false);
- mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
- mResources.getBoolean(R.bool.config_default_sound_enabled));
-
- mPopupOn = isPopupEnabled(prefs);
- mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
- mQuickFixes = isQuickFixesEnabled(prefs);
-
- mAutoCorrectEnabled = isAutoCorrectEnabled(prefs);
- mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs);
- loadAndSetAutoCorrectionThreshold(prefs);
-
- mVoiceConnector.loadSettings(attribute, prefs);
-
- updateCorrectionMode();
- updateAutoTextEnabled();
- updateSuggestionVisibility(prefs);
- SubtypeSwitcher.getInstance().loadSettings();
- }
-
- /**
- * Load Auto correction threshold from SharedPreferences, and modify mSuggest's threshold.
- */
- private void loadAndSetAutoCorrectionThreshold(SharedPreferences sp) {
- // When mSuggest is not initialized, cannnot modify mSuggest's threshold.
- if (mSuggest == null) return;
- // When auto correction setting is turned off, the threshold is ignored.
- if (!isAutoCorrectEnabled(sp)) return;
-
- final String currentAutoCorrectionSetting = sp.getString(
- Settings.PREF_AUTO_CORRECTION_THRESHOLD,
- mResources.getString(R.string.auto_correction_threshold_mode_index_modest));
- final String[] autoCorrectionThresholdValues = mResources.getStringArray(
- R.array.auto_correction_threshold_values);
- // When autoCrrectionThreshold is greater than 1.0, auto correction is virtually turned 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));
- }
- // TODO: This should be refactored :
- // setAutoCorrectionThreshold should be called outside of this method.
- mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold);
- }
-
- private boolean isPopupEnabled(SharedPreferences sp) {
- final boolean showPopupOption = getResources().getBoolean(
- R.bool.config_enable_show_popup_on_keypress_option);
- if (!showPopupOption) return mResources.getBoolean(R.bool.config_default_popup_preview);
- return sp.getBoolean(Settings.PREF_POPUP_ON,
- mResources.getBoolean(R.bool.config_default_popup_preview));
- }
-
- private boolean isQuickFixesEnabled(SharedPreferences sp) {
- final boolean showQuickFixesOption = mResources.getBoolean(
- R.bool.config_enable_quick_fixes_option);
- if (!showQuickFixesOption) {
- return isAutoCorrectEnabled(sp);
- }
- return sp.getBoolean(Settings.PREF_QUICK_FIXES, mResources.getBoolean(
- R.bool.config_default_quick_fixes));
- }
-
- private boolean isAutoCorrectEnabled(SharedPreferences sp) {
- final String currentAutoCorrectionSetting = sp.getString(
- Settings.PREF_AUTO_CORRECTION_THRESHOLD,
- mResources.getString(R.string.auto_correction_threshold_mode_index_modest));
- final String autoCorrectionOff = mResources.getString(
- R.string.auto_correction_threshold_mode_index_off);
- return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
- }
-
- private boolean isBigramSuggestionEnabled(SharedPreferences sp) {
- final boolean showBigramSuggestionsOption = mResources.getBoolean(
- R.bool.config_enable_bigram_suggestions_option);
- if (!showBigramSuggestionsOption) {
- return isAutoCorrectEnabled(sp);
- }
- return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, mResources.getBoolean(
- R.bool.config_default_bigram_suggestions));
- }
-
- private void initSuggestPuncList() {
- if (mSuggestPuncs != null || mSuggestPuncList != null)
- return;
- SuggestedWords.Builder builder = new SuggestedWords.Builder();
- String puncs = mResources.getString(R.string.suggested_punctuations);
- if (puncs != null) {
- for (int i = 0; i < puncs.length(); i++) {
- builder.addWord(puncs.subSequence(i, i + 1));
- }
- }
- mSuggestPuncList = builder.build();
- mSuggestPuncs = puncs;
- }
-
- private boolean isSuggestedPunctuation(int code) {
- return mSuggestPuncs.contains(String.valueOf((char)code));
- }
-
private void showSubtypeSelectorAndSettings() {
final CharSequence title = getString(R.string.english_ime_input_options);
final CharSequence[] items = new CharSequence[] {
@@ -2235,13 +2051,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
di.dismiss();
switch (position) {
case 0:
- Intent intent = new Intent(
- android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ Intent intent = CompatUtils.getInputLanguageSelectionIntent(
+ mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(android.provider.Settings.EXTRA_INPUT_METHOD_ID,
- mInputMethodId);
startActivity(intent);
break;
case 1:
@@ -2278,7 +2091,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void showOptionsMenuInternal(CharSequence title, CharSequence[] items,
DialogInterface.OnClickListener listener) {
- final IBinder windowToken = mKeyboardSwitcher.getInputView().getWindowToken();
+ final IBinder windowToken = mKeyboardSwitcher.getKeyboardView().getWindowToken();
if (windowToken == null) return;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
@@ -2304,17 +2117,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final Printer p = new PrintWriterPrinter(fout);
p.println("LatinIME state :");
p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode());
- p.println(" mComposing=" + mComposing.toString());
+ p.println(" mComposingStringBuilder=" + mComposingStringBuilder.toString());
p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn);
p.println(" mCorrectionMode=" + mCorrectionMode);
- p.println(" mHasValidSuggestions=" + mHasValidSuggestions);
- p.println(" mAutoCorrectOn=" + mAutoCorrectOn);
- p.println(" mAutoSpace=" + mAutoSpace);
+ p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars);
+ p.println(" mAutoCorrectEnabled=" + mSettingsValues.mAutoCorrectEnabled);
+ p.println(" mShouldInsertMagicSpace=" + mShouldInsertMagicSpace);
p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn);
p.println(" TextEntryState.state=" + TextEntryState.getState());
- p.println(" mSoundOn=" + mSoundOn);
- p.println(" mVibrateOn=" + mVibrateOn);
- p.println(" mPopupOn=" + mPopupOn);
+ p.println(" mSoundOn=" + mSettingsValues.mSoundOn);
+ p.println(" mVibrateOn=" + mSettingsValues.mVibrateOn);
+ p.println(" mKeyPreviewPopupOn=" + mSettingsValues.mKeyPreviewPopupOn);
}
// Characters per second measurement
@@ -2334,9 +2147,4 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i];
System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total));
}
-
- @Override
- public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
- SubtypeSwitcher.getInstance().updateSubtype(subtype);
- }
}
diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
index aaecfffdd..ae8eb374b 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -27,6 +27,7 @@ import java.util.List;
public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
public static boolean sDBG = false;
+ public static boolean sVISUALDEBUG = false;
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
@@ -45,10 +46,10 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
String before, String after, int position, List<CharSequence> suggestions) {
}
- public static void logOnAutoSuggestion(String before, String after) {
+ public static void logOnAutoCorrection(String before, String after, int separatorCode) {
}
- public static void logOnAutoSuggestionCanceled() {
+ public static void logOnAutoCorrectionCancelled() {
}
public static void logOnDelete() {
@@ -57,6 +58,9 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang
public static void logOnInputChar() {
}
+ public static void logOnInputSeparator() {
+ }
+
public static void logOnException(String metaData, Throwable e) {
}
diff --git a/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java
new file mode 100644
index 000000000..eb740e111
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java
@@ -0,0 +1,29 @@
+/*
+ * 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 java.util.List;
+import java.util.Locale;
+
+class PrivateBinaryDictionaryGetter {
+ private PrivateBinaryDictionaryGetter() {}
+ public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context) {
+ return null;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 341d5add0..33e9bc35f 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -16,34 +16,40 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.voice.VoiceIMEConnector;
-import com.android.inputmethod.voice.VoiceInputLogger;
-
+import com.android.inputmethod.compat.CompatUtils;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.compat.VibratorCompatWrapper;
+import com.android.inputmethodcommon.InputMethodSettingsActivity;
+
+import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.Fragment;
import android.app.backup.BackupManager;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.os.Bundle;
-import android.os.Vibrator;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.speech.SpeechRecognizer;
-import android.text.AutoText;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.widget.TextView;
+import java.util.Arrays;
import java.util.Locale;
-public class Settings extends PreferenceActivity
+public class Settings extends InputMethodSettingsActivity
implements SharedPreferences.OnSharedPreferenceChangeListener,
DialogInterface.OnDismissListener, OnPreferenceClickListener {
private static final String TAG = "Settings";
@@ -51,7 +57,7 @@ public class Settings extends PreferenceActivity
public static final String PREF_GENERAL_SETTINGS_KEY = "general_settings";
public static final String PREF_VIBRATE_ON = "vibrate_on";
public static final String PREF_SOUND_ON = "sound_on";
- public static final String PREF_POPUP_ON = "popup_on";
+ public static final String PREF_KEY_PREVIEW_POPUP_ON = "popup_on";
public static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled";
public static final String PREF_AUTO_CAP = "auto_cap";
public static final String PREF_SETTINGS_KEY = "settings_key";
@@ -60,29 +66,245 @@ public class Settings extends PreferenceActivity
public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
public static final String PREF_SUBTYPES = "subtype_settings";
- public static final String PREF_PREDICTION_SETTINGS_KEY = "prediction_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_QUICK_FIXES = "quick_fixes";
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_NGRAM_SETTINGS_KEY = "ngram_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_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_USABILITY_STUDY_MODE = "usability_study_mode";
// Dialog ids
private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
+ public static class Values {
+ // From resources:
+ public final int mDelayBeforeFadeoutLanguageOnSpacebar;
+ public final int mDelayUpdateSuggestions;
+ public final int mDelayUpdateOldSuggestions;
+ public final int mDelayUpdateShiftState;
+ public final int mDurationOfFadeoutLanguageOnSpacebar;
+ public final float mFinalFadeoutFactorOfLanguageOnSpacebar;
+ public final long mDoubleSpacesTurnIntoPeriodTimeout;
+ public final String mWordSeparators;
+ public final String mMagicSpaceStrippers;
+ public final String mMagicSpaceSwappers;
+ public final String mSuggestPuncs;
+ public final SuggestedWords mSuggestPuncList;
+
+ // 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 mQuickFixes;
+ 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 Values(final SharedPreferences prefs, final Context context,
+ final String localeStr) {
+ final Resources res = context.getResources();
+ final Locale savedLocale;
+ if (null != localeStr) {
+ final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
+ savedLocale = Utils.setSystemLocale(res, keyboardLocale);
+ } else {
+ savedLocale = null;
+ }
+
+ // Get the resources
+ mDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger(
+ R.integer.config_delay_before_fadeout_language_on_spacebar);
+ mDelayUpdateSuggestions =
+ res.getInteger(R.integer.config_delay_update_suggestions);
+ mDelayUpdateOldSuggestions = res.getInteger(
+ R.integer.config_delay_update_old_suggestions);
+ mDelayUpdateShiftState =
+ res.getInteger(R.integer.config_delay_update_shift_state);
+ mDurationOfFadeoutLanguageOnSpacebar = res.getInteger(
+ R.integer.config_duration_of_fadeout_language_on_spacebar);
+ mFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger(
+ R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f;
+ mDoubleSpacesTurnIntoPeriodTimeout = res.getInteger(
+ R.integer.config_double_spaces_turn_into_period_timeout);
+ 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 notWordSeparators = res.getString(R.string.non_word_separator_symbols);
+ for (int i = notWordSeparators.length() - 1; i >= 0; --i) {
+ wordSeparators = wordSeparators.replace(notWordSeparators.substring(i, i + 1), "");
+ }
+ 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, false);
+ 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);
+ mQuickFixes = isQuickFixesEnabled(prefs, res);
+
+ 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);
+
+ Utils.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 isMagicSpaceStripper(int code) {
+ return mMagicSpaceStrippers.contains(String.valueOf((char)code));
+ }
+
+ public boolean isMagicSpaceSwapper(int code) {
+ return mMagicSpaceSwappers.contains(String.valueOf((char)code));
+ }
+
+ // Helper methods
+ private static boolean isQuickFixesEnabled(SharedPreferences sp, Resources resources) {
+ final boolean showQuickFixesOption = resources.getBoolean(
+ R.bool.config_enable_quick_fixes_option);
+ if (!showQuickFixesOption) {
+ return isAutoCorrectEnabled(sp, resources);
+ }
+ return sp.getBoolean(Settings.PREF_QUICK_FIXES, resources.getBoolean(
+ R.bool.config_default_quick_fixes));
+ }
+
+ 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();
+ }
+ }
+
private PreferenceScreen mInputLanguageSelection;
- private CheckBoxPreference mQuickFixes;
private ListPreference mVoicePreference;
private ListPreference mSettingsKeyPreference;
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThreshold;
+ private ListPreference mKeyPreviewPopupDismissDelay;
+ // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
private CheckBoxPreference mBigramSuggestion;
+ // Prediction: use bigrams to predict the next word when there is no input for it yet
+ private CheckBoxPreference mBigramPrediction;
+ private Preference mDebugSettingsPreference;
private boolean mVoiceOn;
private AlertDialog mDialog;
- private VoiceInputLogger mLogger;
+ private VoiceProxy.VoiceLoggerWrapper mVoiceLogger;
private boolean mOkClicked = false;
private String mVoiceModeOff;
@@ -92,15 +314,31 @@ public class Settings extends PreferenceActivity
R.string.auto_correction_threshold_mode_index_off);
final String currentSetting = mAutoCorrectionThreshold.getValue();
mBigramSuggestion.setEnabled(!currentSetting.equals(autoCorrectionOff));
+ mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
+ }
+
+ public Activity getActivityInternal() {
+ Object thisObject = (Object) this;
+ if (thisObject instanceof Activity) {
+ return (Activity) thisObject;
+ } else if (thisObject instanceof Fragment) {
+ return ((Fragment) thisObject).getActivity();
+ } else {
+ return null;
+ }
}
@Override
- protected void onCreate(Bundle icicle) {
+ public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ setInputMethodSettingsCategoryTitle(R.string.language_selection_title);
+ setSubtypeEnablerTitle(R.string.select_language);
+ final Resources res = getResources();
+ final Context context = getActivityInternal();
+
addPreferencesFromResource(R.xml.prefs);
mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES);
mInputLanguageSelection.setOnPreferenceClickListener(this);
- mQuickFixes = (CheckBoxPreference) findPreference(PREF_QUICK_FIXES);
mVoicePreference = (ListPreference) findPreference(PREF_VOICE_SETTINGS_KEY);
mSettingsKeyPreference = (ListPreference) findPreference(PREF_SETTINGS_KEY);
mShowCorrectionSuggestionsPreference =
@@ -111,91 +349,120 @@ public class Settings extends PreferenceActivity
mVoiceModeOff = getString(R.string.voice_mode_off);
mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
.equals(mVoiceModeOff));
- mLogger = VoiceInputLogger.getLogger(this);
+ mVoiceLogger = VoiceProxy.VoiceLoggerWrapper.getInstance(context);
mAutoCorrectionThreshold = (ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD);
mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTIONS);
+ mBigramPrediction = (CheckBoxPreference) findPreference(PREF_BIGRAM_PREDICTIONS);
+ mDebugSettingsPreference = findPreference(PREF_DEBUG_SETTINGS);
+ if (mDebugSettingsPreference != null) {
+ final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
+ debugSettingsIntent.setClassName(
+ context.getPackageName(), DebugSettings.class.getName());
+ mDebugSettingsPreference.setIntent(debugSettingsIntent);
+ }
+
ensureConsistencyOfAutoCorrectionSettings();
final PreferenceGroup generalSettings =
(PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS_KEY);
final PreferenceGroup textCorrectionGroup =
- (PreferenceGroup) findPreference(PREF_PREDICTION_SETTINGS_KEY);
+ (PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY);
- final boolean showSettingsKeyOption = getResources().getBoolean(
+ final boolean showSettingsKeyOption = res.getBoolean(
R.bool.config_enable_show_settings_key_option);
if (!showSettingsKeyOption) {
generalSettings.removePreference(mSettingsKeyPreference);
}
- final boolean showVoiceKeyOption = getResources().getBoolean(
+ final boolean showVoiceKeyOption = res.getBoolean(
R.bool.config_enable_show_voice_key_option);
if (!showVoiceKeyOption) {
generalSettings.removePreference(mVoicePreference);
}
- Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
- if (vibrator == null || !vibrator.hasVibrator()) {
+ if (!VibratorCompatWrapper.getInstance(context).hasVibrator()) {
generalSettings.removePreference(findPreference(PREF_VIBRATE_ON));
}
- final boolean showSubtypeSettings = getResources().getBoolean(
- R.bool.config_enable_show_subtype_settings);
- if (!showSubtypeSettings) {
+ if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
generalSettings.removePreference(findPreference(PREF_SUBTYPES));
}
- final boolean showPopupOption = getResources().getBoolean(
+ final boolean showPopupOption = res.getBoolean(
R.bool.config_enable_show_popup_on_keypress_option);
if (!showPopupOption) {
- generalSettings.removePreference(findPreference(PREF_POPUP_ON));
+ generalSettings.removePreference(findPreference(PREF_KEY_PREVIEW_POPUP_ON));
}
- final boolean showRecorrectionOption = getResources().getBoolean(
+ final boolean showRecorrectionOption = res.getBoolean(
R.bool.config_enable_show_recorrection_option);
if (!showRecorrectionOption) {
generalSettings.removePreference(findPreference(PREF_RECORRECTION_ENABLED));
}
- final boolean showQuickFixesOption = getResources().getBoolean(
+ final boolean showQuickFixesOption = res.getBoolean(
R.bool.config_enable_quick_fixes_option);
if (!showQuickFixesOption) {
textCorrectionGroup.removePreference(findPreference(PREF_QUICK_FIXES));
}
- final boolean showBigramSuggestionsOption = getResources().getBoolean(
+ final boolean showBigramSuggestionsOption = res.getBoolean(
R.bool.config_enable_bigram_suggestions_option);
if (!showBigramSuggestionsOption) {
textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_SUGGESTIONS));
+ textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_PREDICTIONS));
}
- final boolean showUsabilityModeStudyOption = getResources().getBoolean(
+ final boolean showUsabilityModeStudyOption = res.getBoolean(
R.bool.config_enable_usability_study_mode_option);
if (!showUsabilityModeStudyOption) {
getPreferenceScreen().removePreference(findPreference(PREF_USABILITY_STUDY_MODE));
}
+
+ mKeyPreviewPopupDismissDelay =
+ (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
+ final String[] entries = new String[] {
+ res.getString(R.string.key_preview_popup_dismiss_no_delay),
+ res.getString(R.string.key_preview_popup_dismiss_default_delay),
+ };
+ final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
+ R.integer.config_delay_after_preview));
+ mKeyPreviewPopupDismissDelay.setEntries(entries);
+ mKeyPreviewPopupDismissDelay.setEntryValues(
+ new String[] { "0", popupDismissDelayDefaultValue });
+ if (null == mKeyPreviewPopupDismissDelay.getValue()) {
+ mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
+ }
+ mKeyPreviewPopupDismissDelay.setEnabled(
+ Settings.Values.isKeyPreviewPopupEnabled(prefs, res));
+
+ final PreferenceScreen dictionaryLink =
+ (PreferenceScreen) findPreference(PREF_CONFIGURE_DICTIONARIES_KEY);
+ final Intent intent = dictionaryLink.getIntent();
+
+ final int number = context.getPackageManager().queryIntentActivities(intent, 0).size();
+ if (0 >= number) {
+ textCorrectionGroup.removePreference(dictionaryLink);
+ }
}
@Override
- protected void onResume() {
+ public void onResume() {
super.onResume();
- int autoTextSize = AutoText.getSize(getListView());
- if (autoTextSize < 1) {
- ((PreferenceGroup) findPreference(PREF_PREDICTION_SETTINGS_KEY))
- .removePreference(mQuickFixes);
- }
- if (!VoiceIMEConnector.VOICE_INSTALLED
- || !SpeechRecognizer.isRecognitionAvailable(this)) {
+ if (!VoiceProxy.VOICE_INSTALLED
+ || !SpeechRecognizer.isRecognitionAvailable(getActivityInternal())) {
getPreferenceScreen().removePreference(mVoicePreference);
} else {
updateVoiceModeSummary();
}
updateSettingsKeySummary();
updateShowCorrectionSuggestionsSummary();
+ updateKeyPreviewPopupDelaySummary();
}
@Override
- protected void onDestroy() {
+ public void onDestroy() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
this);
super.onDestroy();
@@ -203,13 +470,19 @@ public class Settings extends PreferenceActivity
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- (new BackupManager(this)).dataChanged();
+ (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)
.equals(mVoiceModeOff)) {
showVoiceConfirmation();
}
+ } else if (key.equals(PREF_KEY_PREVIEW_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));
+ }
}
ensureConsistencyOfAutoCorrectionSettings();
mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
@@ -217,21 +490,16 @@ public class Settings extends PreferenceActivity
updateVoiceModeSummary();
updateSettingsKeySummary();
updateShowCorrectionSuggestionsSummary();
+ updateKeyPreviewPopupDelaySummary();
}
@Override
public boolean onPreferenceClick(Preference pref) {
if (pref == mInputLanguageSelection) {
- final String action;
- if (android.os.Build.VERSION.SDK_INT
- >= /* android.os.Build.VERSION_CODES.HONEYCOMB */ 11) {
- // Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS
- // TODO: Can this be a constant instead of literal String constant?
- action = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
- } else {
- action = "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION";
- }
- startActivity(new Intent(action));
+ startActivity(CompatUtils.getInputLanguageSelectionIntent(
+ Utils.getInputMethodId(
+ InputMethodManagerCompatWrapper.getInstance(getActivityInternal()),
+ getActivityInternal().getApplicationInfo().packageName), 0));
return true;
}
return false;
@@ -250,9 +518,14 @@ public class Settings extends PreferenceActivity
[mSettingsKeyPreference.findIndexOfValue(mSettingsKeyPreference.getValue())]);
}
+ private void updateKeyPreviewPopupDelaySummary() {
+ final ListPreference lp = mKeyPreviewPopupDismissDelay;
+ lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]);
+ }
+
private void showVoiceConfirmation() {
mOkClicked = false;
- showDialog(VOICE_INPUT_CONFIRM_DIALOG);
+ getActivityInternal().showDialog(VOICE_INPUT_CONFIRM_DIALOG);
// Make URL in the dialog message clickable
if (mDialog != null) {
TextView textView = (TextView) mDialog.findViewById(android.R.id.message);
@@ -268,7 +541,6 @@ public class Settings extends PreferenceActivity
[mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]);
}
- @Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case VOICE_INPUT_CONFIRM_DIALOG:
@@ -277,15 +549,15 @@ public class Settings extends PreferenceActivity
public void onClick(DialogInterface dialog, int whichButton) {
if (whichButton == DialogInterface.BUTTON_NEGATIVE) {
mVoicePreference.setValue(mVoiceModeOff);
- mLogger.settingsWarningDialogCancel();
+ mVoiceLogger.settingsWarningDialogCancel();
} else if (whichButton == DialogInterface.BUTTON_POSITIVE) {
mOkClicked = true;
- mLogger.settingsWarningDialogOk();
+ mVoiceLogger.settingsWarningDialogOk();
}
updateVoicePreference();
}
};
- AlertDialog.Builder builder = new AlertDialog.Builder(this)
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivityInternal())
.setTitle(R.string.voice_warning_title)
.setPositiveButton(android.R.string.ok, listener)
.setNegativeButton(android.R.string.cancel, listener);
@@ -311,7 +583,7 @@ public class Settings extends PreferenceActivity
AlertDialog dialog = builder.create();
mDialog = dialog;
dialog.setOnDismissListener(this);
- mLogger.settingsWarningDialogShown();
+ mVoiceLogger.settingsWarningDialogShown();
return dialog;
default:
Log.e(TAG, "unknown dialog " + id);
@@ -321,7 +593,7 @@ public class Settings extends PreferenceActivity
@Override
public void onDismiss(DialogInterface dialog) {
- mLogger.settingsWarningDialogDismissed();
+ mVoiceLogger.settingsWarningDialogDismissed();
if (!mOkClicked) {
// This assumes that onPreferenceClick gets called first, and this if the user
// agreed after the warning, we set the mOkClicked value to true.
@@ -331,10 +603,6 @@ public class Settings extends PreferenceActivity
private void updateVoicePreference() {
boolean isChecked = !mVoicePreference.getValue().equals(mVoiceModeOff);
- if (isChecked) {
- mLogger.voiceInputSettingEnabled();
- } else {
- mLogger.voiceInputSettingDisabled();
- }
+ mVoiceLogger.voiceInputSettingEnabled(isChecked);
}
}
diff --git a/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java b/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java
new file mode 100644
index 000000000..89d9ea844
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java
@@ -0,0 +1,42 @@
+/*
+ * 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.os.Handler;
+import android.os.Looper;
+
+import java.lang.ref.WeakReference;
+
+public class StaticInnerHandlerWrapper<T> extends Handler {
+ final private WeakReference<T> mOuterInstanceRef;
+
+ public StaticInnerHandlerWrapper(T outerInstance) {
+ super();
+ if (outerInstance == null) throw new NullPointerException("outerInstance is null");
+ mOuterInstanceRef = new WeakReference<T>(outerInstance);
+ }
+
+ public StaticInnerHandlerWrapper(T outerInstance, Looper looper) {
+ super(looper);
+ if (outerInstance == null) throw new NullPointerException("outerInstance is null");
+ mOuterInstanceRef = new WeakReference<T>(outerInstance);
+ }
+
+ public T getOuterInstance() {
+ return mOuterInstanceRef.get();
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index dc14d770a..8fc19ae87 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -16,11 +16,12 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
+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 com.android.inputmethod.voice.SettingsUtil;
-import com.android.inputmethod.voice.VoiceIMEConnector;
-import com.android.inputmethod.voice.VoiceInput;
import android.content.Context;
import android.content.Intent;
@@ -31,12 +32,10 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import android.os.AsyncTask;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
import java.util.ArrayList;
import java.util.Arrays;
@@ -53,32 +52,37 @@ public class SubtypeSwitcher {
private static final String VOICE_MODE = "voice";
private static final String SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY =
"requireNetworkConnectivity";
+ public static final String USE_SPACEBAR_LANGUAGE_SWITCH_KEY = "use_spacebar_language_switch";
+
private final TextUtils.SimpleStringSplitter mLocaleSplitter =
new TextUtils.SimpleStringSplitter(LOCALE_SEPARATER);
private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
private /* final */ LatinIME mService;
- private /* final */ SharedPreferences mPrefs;
- private /* final */ InputMethodManager mImm;
+ private /* final */ InputMethodManagerCompatWrapper mImm;
private /* final */ Resources mResources;
private /* final */ ConnectivityManager mConnectivityManager;
private /* final */ boolean mConfigUseSpacebarLanguageSwitcher;
- private final ArrayList<InputMethodSubtype> mEnabledKeyboardSubtypesOfCurrentInputMethod =
- new ArrayList<InputMethodSubtype>();
+ private /* final */ SharedPreferences mPrefs;
+ private final ArrayList<InputMethodSubtypeCompatWrapper>
+ mEnabledKeyboardSubtypesOfCurrentInputMethod =
+ new ArrayList<InputMethodSubtypeCompatWrapper>();
private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>();
+ private final LanguageBarInfo mLanguageBarInfo = new LanguageBarInfo();
/*-----------------------------------------------------------*/
// Variants which should be changed only by reload functions.
private boolean mNeedsToDisplayLanguage;
private boolean mIsSystemLanguageSameAsInputLanguage;
- private InputMethodInfo mShortcutInputMethodInfo;
- private InputMethodSubtype mShortcutSubtype;
- private List<InputMethodSubtype> mAllEnabledSubtypesOfCurrentInputMethod;
- private InputMethodSubtype mCurrentSubtype;
+ private InputMethodInfoCompatWrapper mShortcutInputMethodInfo;
+ private InputMethodSubtypeCompatWrapper mShortcutSubtype;
+ private List<InputMethodSubtypeCompatWrapper> mAllEnabledSubtypesOfCurrentInputMethod;
+ private InputMethodSubtypeCompatWrapper mCurrentSubtype;
private Locale mSystemLocale;
private Locale mInputLocale;
private String mInputLocaleStr;
- private VoiceInput mVoiceInput;
+ private String mInputMethodId;
+ private VoiceProxy.VoiceInputWrapper mVoiceInputWrapper;
/*-----------------------------------------------------------*/
private boolean mIsNetworkConnected;
@@ -88,10 +92,9 @@ public class SubtypeSwitcher {
}
public static void init(LatinIME service, SharedPreferences prefs) {
+ SubtypeLocale.init(service);
sInstance.initialize(service, prefs);
sInstance.updateAllParameters();
-
- SubtypeLocale.init(service);
}
private SubtypeSwitcher() {
@@ -100,9 +103,8 @@ public class SubtypeSwitcher {
private void initialize(LatinIME service, SharedPreferences prefs) {
mService = service;
- mPrefs = prefs;
mResources = service.getResources();
- mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE);
+ mImm = InputMethodManagerCompatWrapper.getInstance(service);
mConnectivityManager = (ConnectivityManager) service.getSystemService(
Context.CONNECTIVITY_SERVICE);
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear();
@@ -112,15 +114,12 @@ public class SubtypeSwitcher {
mInputLocaleStr = null;
mCurrentSubtype = null;
mAllEnabledSubtypesOfCurrentInputMethod = null;
- // TODO: Voice input should be created here
- mVoiceInput = null;
- mConfigUseSpacebarLanguageSwitcher = mResources.getBoolean(
- R.bool.config_use_spacebar_language_switcher);
- if (mConfigUseSpacebarLanguageSwitcher)
- initLanguageSwitcher(service);
+ mVoiceInputWrapper = null;
+ mPrefs = prefs;
final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
mIsNetworkConnected = (info != null && info.isConnected());
+ mInputMethodId = Utils.getInputMethodId(mImm, service.getPackageName());
}
// Update all parameters stored in SubtypeSwitcher.
@@ -134,11 +133,10 @@ public class SubtypeSwitcher {
// Update parameters which are changed outside LatinIME. This parameters affect UI so they
// should be updated every time onStartInputview.
public void updateParametersOnStartInputView() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- updateForSpacebarLanguageSwitch();
- } else {
- updateEnabledSubtypes();
- }
+ mConfigUseSpacebarLanguageSwitcher = mPrefs.getBoolean(USE_SPACEBAR_LANGUAGE_SWITCH_KEY,
+ mService.getResources().getBoolean(
+ R.bool.config_use_spacebar_language_switcher));
+ updateEnabledSubtypes();
updateShortcutIME();
}
@@ -150,7 +148,7 @@ public class SubtypeSwitcher {
null, true);
mEnabledLanguagesOfCurrentInputMethod.clear();
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear();
- for (InputMethodSubtype ims: mAllEnabledSubtypesOfCurrentInputMethod) {
+ for (InputMethodSubtypeCompatWrapper ims : mAllEnabledSubtypesOfCurrentInputMethod) {
final String locale = ims.getLocale();
final String mode = ims.getMode();
mLocaleSplitter.setString(locale);
@@ -172,6 +170,10 @@ public class SubtypeSwitcher {
Log.w(TAG, "Last subtype was disabled. Update to the current one.");
}
updateSubtype(mImm.getCurrentInputMethodSubtype());
+ } else {
+ // mLanguageBarInfo.update() will be called in updateSubtype so there is no need
+ // to call this in the if-clause above.
+ mLanguageBarInfo.update();
}
}
@@ -184,10 +186,12 @@ public class SubtypeSwitcher {
+ ", " + mShortcutSubtype.getMode())));
}
// TODO: Update an icon for shortcut IME
- Map<InputMethodInfo, List<InputMethodSubtype>> shortcuts =
+ final Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcuts =
mImm.getShortcutInputMethodsAndSubtypes();
- for (InputMethodInfo imi: shortcuts.keySet()) {
- List<InputMethodSubtype> subtypes = shortcuts.get(imi);
+ mShortcutInputMethodInfo = null;
+ mShortcutSubtype = null;
+ for (InputMethodInfoCompatWrapper imi : shortcuts.keySet()) {
+ List<InputMethodSubtypeCompatWrapper> subtypes = shortcuts.get(imi);
// TODO: Returns the first found IMI for now. Should handle all shortcuts as
// appropriate.
mShortcutInputMethodInfo = imi;
@@ -206,7 +210,7 @@ public class SubtypeSwitcher {
}
// Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
- public void updateSubtype(InputMethodSubtype newSubtype) {
+ public void updateSubtype(InputMethodSubtypeCompatWrapper newSubtype) {
final String newLocale;
final String newMode;
final String oldMode = getCurrentSubtypeMode();
@@ -243,32 +247,33 @@ public class SubtypeSwitcher {
// We cancel its status when we change mode, while we reset otherwise.
if (isKeyboardMode()) {
if (modeChanged) {
- if (VOICE_MODE.equals(oldMode) && mVoiceInput != null) {
- mVoiceInput.cancel();
+ if (VOICE_MODE.equals(oldMode) && mVoiceInputWrapper != null) {
+ mVoiceInputWrapper.cancel();
}
}
if (modeChanged || languageChanged) {
updateShortcutIME();
mService.onRefreshKeyboard();
}
- } else if (isVoiceMode() && mVoiceInput != null) {
+ } else if (isVoiceMode() && mVoiceInputWrapper != null) {
if (VOICE_MODE.equals(oldMode)) {
- mVoiceInput.reset();
+ mVoiceInputWrapper.reset();
}
// If needsToShowWarningDialog is true, voice input need to show warning before
// show recognition view.
if (languageChanged || modeChanged
- || VoiceIMEConnector.getInstance().needsToShowWarningDialog()) {
+ || VoiceProxy.getInstance().needsToShowWarningDialog()) {
triggerVoiceIME();
}
} else {
Log.w(TAG, "Unknown subtype mode: " + newMode);
- if (VOICE_MODE.equals(oldMode) && mVoiceInput != null) {
+ if (VOICE_MODE.equals(oldMode) && mVoiceInputWrapper != null) {
// We need to reset the voice input to release the resources and to reset its status
// as it is not the current input mode.
- mVoiceInput.reset();
+ mVoiceInputWrapper.reset();
}
}
+ mLanguageBarInfo.update();
}
// Update the current input locale from Locale string.
@@ -277,14 +282,8 @@ public class SubtypeSwitcher {
// "en_US" --> language: en & country: US
// "en" --> language: en
// "" --> the system locale
- mLocaleSplitter.setString(inputLocaleStr);
- if (mLocaleSplitter.hasNext()) {
- String language = mLocaleSplitter.next();
- if (mLocaleSplitter.hasNext()) {
- mInputLocale = new Locale(language, mLocaleSplitter.next());
- } else {
- mInputLocale = new Locale(language);
- }
+ if (!TextUtils.isEmpty(inputLocaleStr)) {
+ mInputLocale = Utils.constructLocaleFromString(inputLocaleStr);
mInputLocaleStr = inputLocaleStr;
} else {
mInputLocale = mSystemLocale;
@@ -303,25 +302,47 @@ public class SubtypeSwitcher {
////////////////////////////
public void switchToShortcutIME() {
- final IBinder token = mService.getWindow().getWindow().getAttributes().token;
- if (token == null || mShortcutInputMethodInfo == null) {
+ if (mShortcutInputMethodInfo == null) {
return;
}
+
final String imiId = mShortcutInputMethodInfo.getId();
- final InputMethodSubtype subtype = mShortcutSubtype;
- new Thread("SwitchToShortcutIME") {
+ final InputMethodSubtypeCompatWrapper subtype = mShortcutSubtype;
+ switchToTargetIME(imiId, subtype);
+ }
+
+ private void switchToTargetIME(
+ final String imiId, final InputMethodSubtypeCompatWrapper subtype) {
+ final IBinder token = mService.getWindow().getWindow().getAttributes().token;
+ if (token == null) {
+ return;
+ }
+ new AsyncTask<Void, Void, Void>() {
@Override
- public void run() {
+ protected Void doInBackground(Void... params) {
mImm.setInputMethodAndSubtype(token, imiId, subtype);
+ return null;
}
- }.start();
+
+ @Override
+ protected void onPostExecute(Void result) {
+ // Calls in this method need to be done in the same thread as the thread which
+ // called switchToShortcutIME().
+
+ // Notify an event that the current subtype was changed. This event will be
+ // handled if "onCurrentInputMethodSubtypeChanged" can't be implemented
+ // when the API level is 10 or previous.
+ mService.notifyOnCurrentInputMethodSubtypeChanged(subtype);
+ }
+ }.execute();
}
public Drawable getShortcutIcon() {
return getSubtypeIcon(mShortcutInputMethodInfo, mShortcutSubtype);
}
- private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) {
+ private Drawable getSubtypeIcon(
+ InputMethodInfoCompatWrapper imi, InputMethodSubtypeCompatWrapper subtype) {
final PackageManager pm = mService.getPackageManager();
if (imi != null) {
final String imiPackageName = imi.getPackageName();
@@ -360,11 +381,16 @@ public class SubtypeSwitcher {
return false;
if (mShortcutSubtype == null)
return true;
+ // For compatibility, if the shortcut subtype is dummy, we assume the shortcut IME
+ // (built-in voice dummy subtype) is available.
+ if (!mShortcutSubtype.hasOriginalObject()) return true;
final boolean allowsImplicitlySelectedSubtypes = true;
- for (final InputMethodSubtype enabledSubtype : mImm.getEnabledInputMethodSubtypeList(
- mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) {
- if (enabledSubtype.equals(mShortcutSubtype))
+ for (final InputMethodSubtypeCompatWrapper enabledSubtype :
+ mImm.getEnabledInputMethodSubtypeList(
+ mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) {
+ if (enabledSubtype.equals(mShortcutSubtype)) {
return true;
+ }
}
return false;
}
@@ -389,7 +415,7 @@ public class SubtypeSwitcher {
final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
final LatinKeyboard keyboard = switcher.getLatinKeyboard();
if (keyboard != null) {
- keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getInputView());
+ keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getKeyboardView());
}
}
@@ -398,11 +424,7 @@ public class SubtypeSwitcher {
//////////////////////////////////
public int getEnabledKeyboardLocaleCount() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return mLanguageSwitcher.getLocaleCount();
- } else {
- return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
- }
+ return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
}
public boolean useSpacebarLanguageSwitcher() {
@@ -414,90 +436,40 @@ public class SubtypeSwitcher {
}
public Locale getInputLocale() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return mLanguageSwitcher.getInputLocale();
- } else {
- return mInputLocale;
- }
+ return mInputLocale;
}
public String getInputLocaleStr() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- String inputLanguage = null;
- inputLanguage = mLanguageSwitcher.getInputLanguage();
- // Should return system locale if there is no Language available.
- if (inputLanguage == null) {
- inputLanguage = getSystemLocale().getLanguage();
- }
- return inputLanguage;
- } else {
- return mInputLocaleStr;
- }
+ return mInputLocaleStr;
}
public String[] getEnabledLanguages() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return mLanguageSwitcher.getEnabledLanguages();
- } else {
- int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size();
- // Workaround for explicitly specifying the voice language
- if (enabledLanguageCount == 1) {
- mEnabledLanguagesOfCurrentInputMethod.add(
- mEnabledLanguagesOfCurrentInputMethod.get(0));
- ++enabledLanguageCount;
- }
- return mEnabledLanguagesOfCurrentInputMethod.toArray(
- new String[enabledLanguageCount]);
+ int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size();
+ // Workaround for explicitly specifying the voice language
+ if (enabledLanguageCount == 1) {
+ mEnabledLanguagesOfCurrentInputMethod.add(mEnabledLanguagesOfCurrentInputMethod
+ .get(0));
+ ++enabledLanguageCount;
}
+ return mEnabledLanguagesOfCurrentInputMethod.toArray(new String[enabledLanguageCount]);
}
public Locale getSystemLocale() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return mLanguageSwitcher.getSystemLocale();
- } else {
- return mSystemLocale;
- }
+ return mSystemLocale;
}
public boolean isSystemLanguageSameAsInputLanguage() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return getSystemLocale().getLanguage().equalsIgnoreCase(
- getInputLocaleStr().substring(0, 2));
- } else {
- return mIsSystemLanguageSameAsInputLanguage;
- }
+ return mIsSystemLanguageSameAsInputLanguage;
}
public void onConfigurationChanged(Configuration conf) {
final Locale systemLocale = conf.locale;
// If system configuration was changed, update all parameters.
if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) {
- if (mConfigUseSpacebarLanguageSwitcher) {
- // If the system locale changes and is different from the saved
- // locale (mSystemLocale), then reload the input locale list from the
- // latin ime settings (shared prefs) and reset the input locale
- // to the first one.
- mLanguageSwitcher.loadLocales(mPrefs);
- mLanguageSwitcher.setSystemLocale(systemLocale);
- } else {
- updateAllParameters();
- }
+ updateAllParameters();
}
}
- /**
- * Change system locale for this application
- * @param newLocale
- * @return oldLocale
- */
- public Locale changeSystemLocale(Locale newLocale) {
- Configuration conf = mResources.getConfiguration();
- Locale oldLocale = conf.locale;
- conf.locale = newLocale;
- mResources.updateConfiguration(conf, mResources.getDisplayMetrics());
- return oldLocale;
- }
-
public boolean isKeyboardMode() {
return KEYBOARD_MODE.equals(getCurrentSubtypeMode());
}
@@ -507,9 +479,9 @@ public class SubtypeSwitcher {
// Voice Input functions //
///////////////////////////
- public boolean setVoiceInput(VoiceInput vi) {
- if (mVoiceInput == null && vi != null) {
- mVoiceInput = vi;
+ public boolean setVoiceInputWrapper(VoiceProxy.VoiceInputWrapper vi) {
+ if (mVoiceInputWrapper == null && vi != null) {
+ mVoiceInputWrapper = vi;
if (isVoiceMode()) {
if (DBG) {
Log.d(TAG, "Set and call voice input.: " + getInputLocaleStr());
@@ -525,47 +497,112 @@ public class SubtypeSwitcher {
return null == mCurrentSubtype ? false : VOICE_MODE.equals(getCurrentSubtypeMode());
}
+ public boolean isDummyVoiceMode() {
+ return mCurrentSubtype != null && mCurrentSubtype.getOriginalObject() == null
+ && VOICE_MODE.equals(getCurrentSubtypeMode());
+ }
+
private void triggerVoiceIME() {
if (!mService.isInputViewShown()) return;
- VoiceIMEConnector.getInstance().startListening(false,
- KeyboardSwitcher.getInstance().getInputView().getWindowToken());
+ VoiceProxy.getInstance().startListening(false,
+ KeyboardSwitcher.getInstance().getKeyboardView().getWindowToken());
}
//////////////////////////////////////
// Spacebar Language Switch support //
//////////////////////////////////////
- private LanguageSwitcher mLanguageSwitcher;
+ private class LanguageBarInfo {
+ private int mCurrentKeyboardSubtypeIndex;
+ private InputMethodSubtypeCompatWrapper mNextKeyboardSubtype;
+ private InputMethodSubtypeCompatWrapper mPreviousKeyboardSubtype;
+ private String mNextLanguage;
+ private String mPreviousLanguage;
+ public LanguageBarInfo() {
+ update();
+ }
+
+ private String getNextLanguage() {
+ return mNextLanguage;
+ }
+
+ private String getPreviousLanguage() {
+ return mPreviousLanguage;
+ }
+
+ public InputMethodSubtypeCompatWrapper getNextKeyboardSubtype() {
+ return mNextKeyboardSubtype;
+ }
+
+ public InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtype() {
+ return mPreviousKeyboardSubtype;
+ }
+
+ public void update() {
+ if (!mConfigUseSpacebarLanguageSwitcher
+ || mEnabledKeyboardSubtypesOfCurrentInputMethod == null
+ || mEnabledKeyboardSubtypesOfCurrentInputMethod.size() == 0) return;
+ mCurrentKeyboardSubtypeIndex = getCurrentIndex();
+ mNextKeyboardSubtype = getNextKeyboardSubtypeInternal(mCurrentKeyboardSubtypeIndex);
+ Locale locale = Utils.constructLocaleFromString(mNextKeyboardSubtype.getLocale());
+ mNextLanguage = getFullDisplayName(locale, true);
+ mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal(
+ mCurrentKeyboardSubtypeIndex);
+ locale = Utils.constructLocaleFromString(mPreviousKeyboardSubtype.getLocale());
+ mPreviousLanguage = getFullDisplayName(locale, true);
+ }
+
+ private int normalize(int index) {
+ final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
+ final int ret = index % N;
+ return ret < 0 ? ret + N : ret;
+ }
+
+ private int getCurrentIndex() {
+ final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
+ for (int i = 0; i < N; ++i) {
+ if (mEnabledKeyboardSubtypesOfCurrentInputMethod.get(i).equals(mCurrentSubtype)) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+ private InputMethodSubtypeCompatWrapper getNextKeyboardSubtypeInternal(int index) {
+ return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index + 1));
+ }
+
+ private InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtypeInternal(int index) {
+ return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index - 1));
+ }
+ }
public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) {
if (returnsNameInThisLocale) {
- return toTitleCase(SubtypeLocale.getFullDisplayName(locale));
+ return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale);
} else {
- return toTitleCase(locale.getDisplayName());
+ return toTitleCase(locale.getDisplayName(), locale);
}
}
public static String getDisplayLanguage(Locale locale) {
- return toTitleCase(locale.getDisplayLanguage(locale));
+ return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale);
+ }
+
+ public static String getMiddleDisplayLanguage(Locale locale) {
+ return toTitleCase((Utils.constructLocaleFromString(
+ locale.getLanguage()).getDisplayLanguage(locale)), locale);
}
public static String getShortDisplayLanguage(Locale locale) {
- return toTitleCase(locale.getLanguage());
+ return toTitleCase(locale.getLanguage(), locale);
}
- private static String toTitleCase(String s) {
+ private static String toTitleCase(String s, Locale locale) {
if (s.length() == 0) {
return s;
}
- return Character.toUpperCase(s.charAt(0)) + s.substring(1);
- }
-
- private void updateForSpacebarLanguageSwitch() {
- // We need to update mNeedsToDisplayLanguage in onStartInputView because
- // getEnabledKeyboardLocaleCount could have been changed.
- mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1
- && getSystemLocale().getLanguage().equalsIgnoreCase(
- getInputLocale().getLanguage()));
+ return s.toUpperCase(locale).charAt(0) + s.substring(1);
}
public String getInputLanguageName() {
@@ -573,19 +610,11 @@ public class SubtypeSwitcher {
}
public String getNextInputLanguageName() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale());
- } else {
- return "";
- }
+ return mLanguageBarInfo.getNextLanguage();
}
public String getPreviousInputLanguageName() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale());
- } else {
- return "";
- }
+ return mLanguageBarInfo.getPreviousLanguage();
}
/////////////////////////////
@@ -612,60 +641,36 @@ public class SubtypeSwitcher {
}
- // A list of locales which are supported by default for voice input, unless we get a
- // different list from Gservices.
- private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES =
- "en " +
- "en_US " +
- "en_GB " +
- "en_AU " +
- "en_CA " +
- "en_IE " +
- "en_IN " +
- "en_NZ " +
- "en_SG " +
- "en_ZA ";
-
public boolean isVoiceSupported(String locale) {
// Get the current list of supported locales and check the current locale against that
// list. We cache this value so as not to check it every time the user starts a voice
// input. Because this method is called by onStartInputView, this should mean that as
// long as the locale doesn't change while the user is keeping the IME open, the
// value should never be stale.
- String supportedLocalesString = SettingsUtil.getSettingsString(
- mService.getContentResolver(),
- SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
- DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
+ String supportedLocalesString = VoiceProxy.getSupportedLocalesString(
+ mService.getContentResolver());
List<String> voiceInputSupportedLocales = Arrays.asList(
supportedLocalesString.split("\\s+"));
return voiceInputSupportedLocales.contains(locale);
}
- public void loadSettings() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- mLanguageSwitcher.loadLocales(mPrefs);
- }
+ private void changeToNextSubtype() {
+ final InputMethodSubtypeCompatWrapper subtype =
+ mLanguageBarInfo.getNextKeyboardSubtype();
+ switchToTargetIME(mInputMethodId, subtype);
}
- public void toggleLanguage(boolean reset, boolean next) {
- if (mConfigUseSpacebarLanguageSwitcher) {
- if (reset) {
- mLanguageSwitcher.reset();
- } else {
- if (next) {
- mLanguageSwitcher.next();
- } else {
- mLanguageSwitcher.prev();
- }
- }
- mLanguageSwitcher.persist(mPrefs);
- }
+ private void changeToPreviousSubtype() {
+ final InputMethodSubtypeCompatWrapper subtype =
+ mLanguageBarInfo.getPreviousKeyboardSubtype();
+ switchToTargetIME(mInputMethodId, subtype);
}
- private void initLanguageSwitcher(LatinIME service) {
- final Configuration conf = service.getResources().getConfiguration();
- mLanguageSwitcher = new LanguageSwitcher(service);
- mLanguageSwitcher.loadLocales(mPrefs);
- mLanguageSwitcher.setSystemLocale(conf.locale);
+ public void toggleLanguage(boolean next) {
+ if (next) {
+ changeToNextSubtype();
+ } else {
+ changeToPreviousSubtype();
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 0de474e59..eb5ed5a65 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -47,7 +48,7 @@ public class Suggest implements Dictionary.WordCallback {
/**
* Words that appear in both bigram and unigram data gets multiplier ranging from
- * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the frequency score from
+ * BIGRAM_MULTIPLIER_MIN to BIGRAM_MULTIPLIER_MAX depending on the score from
* bigram data.
*/
public static final double BIGRAM_MULTIPLIER_MIN = 1.2;
@@ -55,7 +56,7 @@ public class Suggest implements Dictionary.WordCallback {
/**
* Maximum possible bigram frequency. Will depend on how many bits are being used in data
- * structure. Maximum bigram freqeuncy will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
+ * structure. Maximum bigram frequency will get the BIGRAM_MULTIPLIER_MAX as the multiplier.
*/
public static final int MAXIMUM_BIGRAM_FREQUENCY = 127;
@@ -74,31 +75,29 @@ public class Suggest implements Dictionary.WordCallback {
public static final String DICT_KEY_USER_BIGRAM = "user_bigram";
public static final String DICT_KEY_WHITELIST ="whitelist";
- static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
-
private static final boolean DBG = LatinImeLogger.sDBG;
private AutoCorrection mAutoCorrection;
- private BinaryDictionary mMainDict;
+ private Dictionary mMainDict;
private WhitelistDictionary mWhiteListDictionary;
private final Map<String, Dictionary> mUnigramDictionaries = new HashMap<String, Dictionary>();
private final Map<String, Dictionary> mBigramDictionaries = new HashMap<String, Dictionary>();
- private int mPrefMaxSuggestions = 12;
+ private int mPrefMaxSuggestions = 18;
private static final int PREF_MAX_BIGRAMS = 60;
private boolean mQuickFixesEnabled;
private double mAutoCorrectionThreshold;
- private int[] mPriorities = new int[mPrefMaxSuggestions];
- private int[] mBigramPriorities = new int[PREF_MAX_BIGRAMS];
+ private int[] mScores = new int[mPrefMaxSuggestions];
+ private int[] mBigramScores = new int[PREF_MAX_BIGRAMS];
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
- private String mLowerOriginalWord;
+ private CharSequence mTypedWord;
// TODO: Remove these member variables by passing more context to addWord() callback method
private boolean mIsFirstCharCapitalized;
@@ -106,28 +105,45 @@ public class Suggest implements Dictionary.WordCallback {
private int mCorrectionMode = CORRECTION_BASIC;
- public Suggest(Context context, int dictionaryResId) {
- init(context, BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN));
+ public Suggest(Context context, int dictionaryResId, Locale locale) {
+ init(context, DictionaryFactory.createDictionaryFromManager(context, locale,
+ dictionaryResId));
}
- /* package for test */ Suggest(File dictionary, long startOffset, long length) {
- init(null, BinaryDictionary.initDictionary(dictionary, startOffset, length, DIC_MAIN));
+ /* package for test */ Suggest(Context context, File dictionary, long startOffset, long length,
+ Flag[] flagArray) {
+ init(null, DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset,
+ length, flagArray));
}
- private void init(Context context, BinaryDictionary mainDict) {
- if (mainDict != null) {
- mMainDict = mainDict;
- mUnigramDictionaries.put(DICT_KEY_MAIN, mainDict);
- mBigramDictionaries.put(DICT_KEY_MAIN, mainDict);
- }
+ private void init(Context context, Dictionary mainDict) {
+ mMainDict = mainDict;
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
+ addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
mWhiteListDictionary = WhitelistDictionary.init(context);
- if (mWhiteListDictionary != null) {
- mUnigramDictionaries.put(DICT_KEY_WHITELIST, mWhiteListDictionary);
- }
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary);
mAutoCorrection = new AutoCorrection();
initPool();
}
+ private void addOrReplaceDictionary(Map<String, Dictionary> dictionaries, String key,
+ Dictionary dict) {
+ final Dictionary oldDict = (dict == null)
+ ? dictionaries.remove(key)
+ : dictionaries.put(key, dict);
+ if (oldDict != null && dict != oldDict) {
+ oldDict.close();
+ }
+ }
+
+ public void resetMainDict(Context context, int dictionaryResId, Locale locale) {
+ final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager(
+ context, locale, dictionaryResId);
+ mMainDict = newMainDict;
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict);
+ addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict);
+ }
+
private void initPool() {
for (int i = 0; i < mPrefMaxSuggestions; i++) {
StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
@@ -148,7 +164,7 @@ public class Suggest implements Dictionary.WordCallback {
}
public boolean hasMainDictionary() {
- return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
+ return mMainDict != null;
}
public Map<String, Dictionary> getUnigramDictionaries() {
@@ -164,28 +180,25 @@ public class Suggest implements Dictionary.WordCallback {
* before the main dictionary, if set.
*/
public void setUserDictionary(Dictionary userDictionary) {
- if (userDictionary != null)
- mUnigramDictionaries.put(DICT_KEY_USER, userDictionary);
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER, userDictionary);
}
/**
- * Sets an optional contacts dictionary resource to be loaded.
+ * Sets an optional contacts dictionary resource to be loaded. It is also possible to remove
+ * the contacts dictionary by passing null to this method. In this case no contacts dictionary
+ * won't be used.
*/
public void setContactsDictionary(Dictionary contactsDictionary) {
- if (contactsDictionary != null) {
- mUnigramDictionaries.put(DICT_KEY_CONTACTS, contactsDictionary);
- mBigramDictionaries.put(DICT_KEY_CONTACTS, contactsDictionary);
- }
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary);
+ addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary);
}
public void setAutoDictionary(Dictionary autoDictionary) {
- if (autoDictionary != null)
- mUnigramDictionaries.put(DICT_KEY_AUTO, autoDictionary);
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_AUTO, autoDictionary);
}
public void setUserBigramDictionary(Dictionary userBigramDictionary) {
- if (userBigramDictionary != null)
- mBigramDictionaries.put(DICT_KEY_USER_BIGRAM, userBigramDictionary);
+ addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_USER_BIGRAM, userBigramDictionary);
}
public void setAutoCorrectionThreshold(double threshold) {
@@ -207,8 +220,8 @@ public class Suggest implements Dictionary.WordCallback {
throw new IllegalArgumentException("maxSuggestions must be between 1 and 100");
}
mPrefMaxSuggestions = maxSuggestions;
- mPriorities = new int[mPrefMaxSuggestions];
- mBigramPriorities = new int[PREF_MAX_BIGRAMS];
+ mScores = new int[mPrefMaxSuggestions];
+ mBigramScores = new int[PREF_MAX_BIGRAMS];
collectGarbage(mSuggestions, mPrefMaxSuggestions);
while (mStringPool.size() < mPrefMaxSuggestions) {
StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
@@ -237,6 +250,7 @@ public class Suggest implements Dictionary.WordCallback {
poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1)
: new StringBuilder(getApproxMaxWordLength());
sb.setLength(0);
+ // TODO: Must pay attention to locale when changing case.
if (all) {
sb.append(word.toString().toUpperCase());
} else if (first) {
@@ -248,6 +262,16 @@ public class Suggest implements Dictionary.WordCallback {
return sb;
}
+ protected void addBigramToSuggestions(CharSequence bigram) {
+ final int poolSize = mStringPool.size();
+ final StringBuilder sb = poolSize > 0 ?
+ (StringBuilder) mStringPool.remove(poolSize - 1)
+ : new StringBuilder(getApproxMaxWordLength());
+ sb.setLength(0);
+ sb.append(bigram);
+ mSuggestions.add(sb);
+ }
+
// TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder
public SuggestedWords.Builder getSuggestedWordBuilder(View view, WordComposer wordComposer,
CharSequence prevWordForBigram) {
@@ -256,25 +280,23 @@ public class Suggest implements Dictionary.WordCallback {
mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
mIsAllUpperCase = wordComposer.isAllUpperCase();
collectGarbage(mSuggestions, mPrefMaxSuggestions);
- Arrays.fill(mPriorities, 0);
+ Arrays.fill(mScores, 0);
// Save a lowercase version of the original word
CharSequence typedWord = wordComposer.getTypedWord();
if (typedWord != null) {
final String typedWordString = typedWord.toString();
typedWord = typedWordString;
- mLowerOriginalWord = typedWordString.toLowerCase();
// Treating USER_TYPED as UNIGRAM suggestion for logging now.
LatinImeLogger.onAddSuggestedWord(typedWordString, Suggest.DIC_USER_TYPED,
Dictionary.DataType.UNIGRAM);
- } else {
- mLowerOriginalWord = "";
}
+ mTypedWord = typedWord;
- if (wordComposer.size() == 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM
+ if (wordComposer.size() <= 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM
|| mCorrectionMode == CORRECTION_BASIC)) {
// At first character typed, search only the bigrams
- Arrays.fill(mBigramPriorities, 0);
+ Arrays.fill(mBigramScores, 0);
collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS);
if (!TextUtils.isEmpty(prevWordForBigram)) {
@@ -285,21 +307,27 @@ public class Suggest implements Dictionary.WordCallback {
for (final Dictionary dictionary : mBigramDictionaries.values()) {
dictionary.getBigrams(wordComposer, prevWordForBigram, this);
}
- char currentChar = wordComposer.getTypedWord().charAt(0);
- char currentCharUpper = Character.toUpperCase(currentChar);
- int count = 0;
- int bigramSuggestionSize = mBigramSuggestions.size();
- for (int i = 0; i < bigramSuggestionSize; i++) {
- if (mBigramSuggestions.get(i).charAt(0) == currentChar
- || mBigramSuggestions.get(i).charAt(0) == currentCharUpper) {
- int poolSize = mStringPool.size();
- StringBuilder sb = poolSize > 0 ?
- (StringBuilder) mStringPool.remove(poolSize - 1)
- : new StringBuilder(getApproxMaxWordLength());
- sb.setLength(0);
- sb.append(mBigramSuggestions.get(i));
- mSuggestions.add(count++, sb);
- if (count > mPrefMaxSuggestions) break;
+ if (TextUtils.isEmpty(typedWord)) {
+ // Nothing entered: return all bigrams for the previous word
+ int insertCount = Math.min(mBigramSuggestions.size(), mPrefMaxSuggestions);
+ for (int i = 0; i < insertCount; ++i) {
+ addBigramToSuggestions(mBigramSuggestions.get(i));
+ }
+ } else {
+ // Word entered: return only bigrams that match the first char of the typed word
+ final char currentChar = typedWord.charAt(0);
+ // TODO: Must pay attention to locale when changing case.
+ final char currentCharUpper = Character.toUpperCase(currentChar);
+ int count = 0;
+ final int bigramSuggestionSize = mBigramSuggestions.size();
+ for (int i = 0; i < bigramSuggestionSize; i++) {
+ final CharSequence bigramSuggestion = mBigramSuggestions.get(i);
+ final char bigramSuggestionFirstChar = bigramSuggestion.charAt(0);
+ if (bigramSuggestionFirstChar == currentChar
+ || bigramSuggestionFirstChar == currentCharUpper) {
+ addBigramToSuggestions(bigramSuggestion);
+ if (++count > mPrefMaxSuggestions) break;
+ }
}
}
}
@@ -346,7 +374,7 @@ public class Suggest implements Dictionary.WordCallback {
mWhiteListDictionary.getWhiteListedWord(typedWordString));
mAutoCorrection.updateAutoCorrectionStatus(mUnigramDictionaries, wordComposer,
- mSuggestions, mPriorities, typedWord, mAutoCorrectionThreshold, mCorrectionMode,
+ mSuggestions, mScores, typedWord, mAutoCorrectionThreshold, mCorrectionMode,
autoText, whitelistedWord);
if (autoText != null) {
@@ -364,26 +392,25 @@ public class Suggest implements Dictionary.WordCallback {
if (DBG) {
double normalizedScore = mAutoCorrection.getNormalizedScore();
- ArrayList<SuggestedWords.SuggestedWordInfo> frequencyInfoList =
+ ArrayList<SuggestedWords.SuggestedWordInfo> scoreInfoList =
new ArrayList<SuggestedWords.SuggestedWordInfo>();
- frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo("+", false));
- final int priorityLength = mPriorities.length;
- for (int i = 0; i < priorityLength; ++i) {
+ scoreInfoList.add(new SuggestedWords.SuggestedWordInfo("+", false));
+ for (int i = 0; i < mScores.length; ++i) {
if (normalizedScore > 0) {
- final String priorityThreshold = Integer.toString(mPriorities[i]) + " (" +
- normalizedScore + ")";
- frequencyInfoList.add(
- new SuggestedWords.SuggestedWordInfo(priorityThreshold, false));
+ final String scoreThreshold = String.format("%d (%4.2f)", mScores[i],
+ normalizedScore);
+ scoreInfoList.add(
+ new SuggestedWords.SuggestedWordInfo(scoreThreshold, false));
normalizedScore = 0.0;
} else {
- final String priority = Integer.toString(mPriorities[i]);
- frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo(priority, false));
+ final String score = Integer.toString(mScores[i]);
+ scoreInfoList.add(new SuggestedWords.SuggestedWordInfo(score, false));
}
}
- for (int i = priorityLength; i < mSuggestions.size(); ++i) {
- frequencyInfoList.add(new SuggestedWords.SuggestedWordInfo("--", false));
+ for (int i = mScores.length; i < mSuggestions.size(); ++i) {
+ scoreInfoList.add(new SuggestedWords.SuggestedWordInfo("--", false));
}
- return new SuggestedWords.Builder().addWords(mSuggestions, frequencyInfoList);
+ return new SuggestedWords.Builder().addWords(mSuggestions, scoreInfoList);
}
return new SuggestedWords.Builder().addWords(mSuggestions, null);
}
@@ -419,52 +446,37 @@ public class Suggest implements Dictionary.WordCallback {
return mAutoCorrection.hasAutoCorrection();
}
- private static boolean compareCaseInsensitive(final String lowerOriginalWord,
- final char[] word, final int offset, final int length) {
- final int originalLength = lowerOriginalWord.length();
- if (originalLength == length && Character.isUpperCase(word[offset])) {
- for (int i = 0; i < originalLength; i++) {
- if (lowerOriginalWord.charAt(i) != Character.toLowerCase(word[offset+i])) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
-
@Override
- public boolean addWord(final char[] word, final int offset, final int length, int freq,
+ 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;
- ArrayList<CharSequence> suggestions;
- int[] priorities;
- int prefMaxSuggestions;
+ final ArrayList<CharSequence> suggestions;
+ final int[] sortedScores;
+ final int prefMaxSuggestions;
if(dataType == Dictionary.DataType.BIGRAM) {
suggestions = mBigramSuggestions;
- priorities = mBigramPriorities;
+ sortedScores = mBigramScores;
prefMaxSuggestions = PREF_MAX_BIGRAMS;
} else {
suggestions = mSuggestions;
- priorities = mPriorities;
+ sortedScores = mScores;
prefMaxSuggestions = mPrefMaxSuggestions;
}
int pos = 0;
// Check if it's the same word, only caps are different
- if (compareCaseInsensitive(mLowerOriginalWord, word, offset, length)) {
+ if (Utils.equalsIgnoreCase(mTypedWord, word, offset, length)) {
// TODO: remove this surrounding if clause and move this logic to
// getSuggestedWordBuilder.
if (suggestions.size() > 0) {
- final String currentHighestWordLowerCase =
- suggestions.get(0).toString().toLowerCase();
+ final String currentHighestWord = suggestions.get(0).toString();
// If the current highest word is also equal to typed word, we need to compare
// frequency to determine the insertion position. This does not ensure strictly
// correct ordering, but ensures the top score is on top which is enough for
// removing duplicates correctly.
- if (compareCaseInsensitive(currentHighestWordLowerCase, word, offset, length)
- && freq <= priorities[0]) {
+ if (Utils.equalsIgnoreCase(currentHighestWord, word, offset, length)
+ && score <= sortedScores[0]) {
pos = 1;
}
}
@@ -475,24 +487,24 @@ public class Suggest implements Dictionary.WordCallback {
if(bigramSuggestion >= 0) {
dataTypeForLog = Dictionary.DataType.BIGRAM;
// turn freq from bigram into multiplier specified above
- double multiplier = (((double) mBigramPriorities[bigramSuggestion])
+ double multiplier = (((double) mBigramScores[bigramSuggestion])
/ MAXIMUM_BIGRAM_FREQUENCY)
* (BIGRAM_MULTIPLIER_MAX - BIGRAM_MULTIPLIER_MIN)
+ BIGRAM_MULTIPLIER_MIN;
/* Log.d(TAG,"bigram num: " + bigramSuggestion
+ " wordB: " + mBigramSuggestions.get(bigramSuggestion).toString()
- + " currentPriority: " + freq + " bigramPriority: "
- + mBigramPriorities[bigramSuggestion]
+ + " currentScore: " + score + " bigramScore: "
+ + mBigramScores[bigramSuggestion]
+ " multiplier: " + multiplier); */
- freq = (int)Math.round((freq * multiplier));
+ score = (int)Math.round((score * multiplier));
}
}
- // Check the last one's priority and bail
- if (priorities[prefMaxSuggestions - 1] >= freq) return true;
+ // Check the last one's score and bail
+ if (sortedScores[prefMaxSuggestions - 1] >= score) return true;
while (pos < prefMaxSuggestions) {
- if (priorities[pos] < freq
- || (priorities[pos] == freq && length < suggestions.get(pos).length())) {
+ if (sortedScores[pos] < score
+ || (sortedScores[pos] == score && length < suggestions.get(pos).length())) {
break;
}
pos++;
@@ -502,12 +514,13 @@ public class Suggest implements Dictionary.WordCallback {
return true;
}
- System.arraycopy(priorities, pos, priorities, pos + 1, prefMaxSuggestions - pos - 1);
- priorities[pos] = freq;
+ System.arraycopy(sortedScores, pos, sortedScores, pos + 1, prefMaxSuggestions - pos - 1);
+ sortedScores[pos] = score;
int poolSize = mStringPool.size();
StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1)
: new StringBuilder(getApproxMaxWordLength());
sb.setLength(0);
+ // TODO: Must pay attention to locale when changing case.
if (mIsAllUpperCase) {
sb.append(new String(word, offset, length).toUpperCase());
} else if (mIsFirstCharCapitalized) {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index fe7aac7c2..84db17504 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -24,22 +24,25 @@ import java.util.HashSet;
import java.util.List;
public class SuggestedWords {
- public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, null);
+ public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, null);
public final List<CharSequence> mWords;
public final boolean mTypedWordValid;
public final boolean mHasMinimalSuggestion;
+ public final boolean mIsPunctuationSuggestions;
public final List<SuggestedWordInfo> mSuggestedWordInfoList;
private SuggestedWords(List<CharSequence> words, boolean typedWordValid,
- boolean hasMinamlSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) {
+ boolean hasMinimalSuggestion, boolean isPunctuationSuggestions,
+ List<SuggestedWordInfo> suggestedWordInfoList) {
if (words != null) {
mWords = words;
} else {
mWords = Collections.emptyList();
}
mTypedWordValid = typedWordValid;
- mHasMinimalSuggestion = hasMinamlSuggestion;
+ mHasMinimalSuggestion = hasMinimalSuggestion;
+ mIsPunctuationSuggestions = isPunctuationSuggestions;
mSuggestedWordInfoList = suggestedWordInfoList;
}
@@ -59,10 +62,15 @@ public class SuggestedWords {
return mHasMinimalSuggestion && ((size() > 1 && !mTypedWordValid) || mTypedWordValid);
}
+ public boolean isPunctuationSuggestions() {
+ return mIsPunctuationSuggestions;
+ }
+
public static class Builder {
private List<CharSequence> mWords = new ArrayList<CharSequence>();
private boolean mTypedWordValid;
private boolean mHasMinimalSuggestion;
+ private boolean mIsPunctuationSuggestions;
private List<SuggestedWordInfo> mSuggestedWordInfoList =
new ArrayList<SuggestedWordInfo>();
@@ -113,8 +121,13 @@ public class SuggestedWords {
return this;
}
- public Builder setHasMinimalSuggestion(boolean hasMinamlSuggestion) {
- mHasMinimalSuggestion = hasMinamlSuggestion;
+ public Builder setHasMinimalSuggestion(boolean hasMinimalSuggestion) {
+ mHasMinimalSuggestion = hasMinimalSuggestion;
+ return this;
+ }
+
+ public Builder setIsPunctuationSuggestions() {
+ mIsPunctuationSuggestions = true;
return this;
}
@@ -143,7 +156,7 @@ public class SuggestedWords {
public SuggestedWords build() {
return new SuggestedWords(mWords, mTypedWordValid, mHasMinimalSuggestion,
- mSuggestedWordInfoList);
+ mIsPunctuationSuggestions, mSuggestedWordInfoList);
}
public int size() {
diff --git a/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java b/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java
new file mode 100644
index 000000000..4a3f42d5d
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.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.latin;
+
+import com.android.inputmethod.compat.SuggestionSpanUtils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class SuggestionSpanPickedNotificationReceiver extends BroadcastReceiver {
+ private static final boolean DBG = LatinImeLogger.sDBG;
+ private static final String TAG =
+ SuggestionSpanPickedNotificationReceiver.class.getSimpleName();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (SuggestionSpanUtils.ACTION_SUGGESTION_PICKED.equals(intent.getAction())) {
+ if (DBG) {
+ final String before = intent.getStringExtra(
+ SuggestionSpanUtils.SUGGESTION_SPAN_PICKED_BEFORE);
+ final String after = intent.getStringExtra(
+ SuggestionSpanUtils.SUGGESTION_SPAN_PICKED_AFTER);
+ Log.d(TAG, "Received notification picked: " + before + "," + after);
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java
index 63196430b..79b3bdebb 100644
--- a/java/src/com/android/inputmethod/latin/TextEntryState.java
+++ b/java/src/com/android/inputmethod/latin/TextEntryState.java
@@ -16,6 +16,9 @@
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 {
@@ -43,10 +46,12 @@ public class TextEntryState {
sState = newState;
}
- public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) {
+ public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord,
+ int separatorCode) {
if (typedWord == null) return;
setState(ACCEPTED_DEFAULT);
- LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString());
+ LatinImeLogger.logOnAutoCorrection(
+ typedWord.toString(), actualWord.toString(), separatorCode);
if (DEBUG)
displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord);
}
@@ -95,8 +100,8 @@ public class TextEntryState {
if (DEBUG) displayState("onAbortRecorrection");
}
- public static void typedCharacter(char c, boolean isSeparator) {
- final boolean isSpace = (c == ' ');
+ 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) {
@@ -140,7 +145,7 @@ public class TextEntryState {
break;
case UNDO_COMMIT:
if (isSpace || isSeparator) {
- setState(ACCEPTED_DEFAULT);
+ setState(START);
} else {
setState(IN_WORD);
}
@@ -149,13 +154,19 @@ public class TextEntryState {
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.logOnAutoSuggestionCanceled();
+ LatinImeLogger.logOnAutoCorrectionCancelled();
} else if (sState == UNDO_COMMIT) {
setState(IN_WORD);
}
diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
index 656e6f8e0..5b615ca29 100644
--- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
@@ -44,12 +44,6 @@ public class UserBigramDictionary extends ExpandableDictionary {
/** Maximum frequency for all pairs */
private static final int FREQUENCY_MAX = 127;
- /**
- * If this pair is typed 6 times, it would be suggested.
- * Should be smaller than ContactsDictionary.FREQUENCY_FOR_CONTACTS_BIGRAM
- */
- protected static final int SUGGEST_THRESHOLD = 6 * FREQUENCY_FOR_TYPED;
-
/** Maximum number of pairs. Pruning will start when databases goes above this number. */
private static int sMaxUserBigrams = 10000;
@@ -164,10 +158,14 @@ public class UserBigramDictionary extends ExpandableDictionary {
* Pair will be added to the userbigram database.
*/
public int addBigrams(String word1, String word2) {
- // remove caps
+ // remove caps if second word is autocapitalized
if (mIme != null && mIme.getCurrentWord().isAutoCapitalized()) {
word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1);
}
+ // Do not insert a word as a bigram of itself
+ if (word1.equals(word2)) {
+ return 0;
+ }
int freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED);
if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX;
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index c06bd736e..2aaa26c8d 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -16,12 +16,14 @@
package com.android.inputmethod.latin;
+import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.os.RemoteException;
import android.provider.UserDictionary.Words;
public class UserDictionary extends ExpandableDictionary {
@@ -99,24 +101,34 @@ public class UserDictionary extends ExpandableDictionary {
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 = contentResolver.query(Words.CONTENT_URI, PROJECTION_ADD,
- "word=? and ((locale IS NULL) or (locale=?))",
- new String[] { word, mLocale }, null);
- if (cursor != null && cursor.moveToFirst()) {
- 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())) {
- long id = cursor.getLong(cursor.getColumnIndex(Words._ID));
- Uri uri = Uri.withAppendedPath(Words.CONTENT_URI, Long.toString(id));
- // Update the entry with new frequency value.
- contentResolver.update(uri, values, null, null);
+ try {
+ final Cursor 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);
}
- } else {
- // Insert new entry.
- contentResolver.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(){}
}
}
}.start();
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 1cbc434b6..6bdc0a857 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -16,6 +16,15 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+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 android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.os.AsyncTask;
@@ -26,10 +35,6 @@ import android.text.InputType;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-
-import com.android.inputmethod.keyboard.KeyboardId;
import java.io.BufferedReader;
import java.io.File;
@@ -39,12 +44,17 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
public class Utils {
private static final String TAG = Utils.class.getSimpleName();
private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4;
private static boolean DBG = LatinImeLogger.sDBG;
+ private static boolean DBG_EDIT_DISTANCE = false;
private Utils() {
// Intentional empty constructor for utility class.
@@ -101,17 +111,49 @@ public class Utils {
}
}
- public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm) {
- return imm.getEnabledInputMethodList().size() > 1
+ public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManagerCompatWrapper imm) {
+ final List<InputMethodInfoCompatWrapper> enabledImis = imm.getEnabledInputMethodList();
+
+ // Filters out IMEs that have auxiliary subtypes only (including either implicitly or
+ // explicitly enabled ones).
+ final ArrayList<InputMethodInfoCompatWrapper> filteredImis =
+ new ArrayList<InputMethodInfoCompatWrapper>();
+
+ outerloop:
+ for (InputMethodInfoCompatWrapper imi : enabledImis) {
+ // We can return true immediately after we find two or more filtered IMEs.
+ if (filteredImis.size() > 1) return true;
+ final List<InputMethodSubtypeCompatWrapper> subtypes =
+ imm.getEnabledInputMethodSubtypeList(imi, true);
+ // IMEs that have no subtypes should be included.
+ if (subtypes.isEmpty()) {
+ filteredImis.add(imi);
+ continue;
+ }
+ // IMEs that have one or more non-auxiliary subtypes should be included.
+ for (InputMethodSubtypeCompatWrapper subtype : subtypes) {
+ if (!subtype.isAuxiliary()) {
+ filteredImis.add(imi);
+ continue outerloop;
+ }
+ }
+ }
+
+ return filteredImis.size() > 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;
}
- public static String getInputMethodId(InputMethodManager imm, String packageName) {
- for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) {
+ public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) {
+ return getInputMethodInfo(imm, packageName).getId();
+ }
+
+ public static InputMethodInfoCompatWrapper getInputMethodInfo(
+ InputMethodManagerCompatWrapper imm, String packageName) {
+ for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) {
if (imi.getPackageName().equals(packageName))
- return imi.getId();
+ return imi;
}
throw new RuntimeException("Can not find input method id for " + packageName);
}
@@ -202,11 +244,11 @@ public class Utils {
return mCharBuf[mEnd];
}
}
- public char getLastChar() {
- if (mLength < 1) {
+ public char getBackwardNthChar(int n) {
+ if (mLength <= n || n < 0) {
return PLACEHOLDER_DELIMITER_CHAR;
} else {
- return mCharBuf[normalize(mEnd - 1)];
+ return mCharBuf[normalize(mEnd - n - 1)];
}
}
public int getPreviousX(char c, int back) {
@@ -227,9 +269,16 @@ public class Utils {
return mYBuf[index];
}
}
- public String getLastString() {
+ public String getLastWord(int ignoreCharCount) {
StringBuilder sb = new StringBuilder();
- for (int i = 0; i < mLength; ++i) {
+ int i = ignoreCharCount;
+ for (; i < mLength; ++i) {
+ char c = mCharBuf[normalize(mEnd - 1 - i)];
+ if (!((LatinIME)mContext).isWordSeparator(c)) {
+ break;
+ }
+ }
+ for (; i < mLength; ++i) {
char c = mCharBuf[normalize(mEnd - 1 - i)];
if (!((LatinIME)mContext).isWordSeparator(c)) {
sb.append(c);
@@ -244,6 +293,8 @@ 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.");
@@ -259,12 +310,27 @@ public class Utils {
}
for (int i = 0; i < sl; ++i) {
for (int j = 0; j < tl; ++j) {
- if (Character.toLowerCase(s.charAt(i)) == Character.toLowerCase(t.charAt(j))) {
- dp[i + 1][j + 1] = dp[i][j];
- } else {
- dp[i + 1][j + 1] = 1 + Math.min(dp[i][j],
- Math.min(dp[i + 1][j], dp[i][j + 1]));
+ 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];
@@ -285,7 +351,7 @@ public class Utils {
// In dictionary.cpp, getSuggestion() method,
// suggestion scores are computed using the below formula.
- // original score (called 'frequency')
+ // 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,
@@ -295,7 +361,7 @@ public class Utils {
// (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 frequency was 255.
+ // 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
@@ -306,6 +372,7 @@ public class Utils {
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();
@@ -313,8 +380,16 @@ public class Utils {
final int distance = editDistance(before, after);
// If afterLength < beforeLength, the algorithm is suggesting a word by excessive character
// correction.
- final double maximumScore = MAX_INITIAL_SCORE
- * Math.pow(TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength))
+ 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,
@@ -485,7 +560,7 @@ public class Utils {
case InputType.TYPE_CLASS_PHONE:
return KeyboardId.MODE_PHONE;
case InputType.TYPE_CLASS_TEXT:
- if (Utils.isEmailVariation(variation)) {
+ if (InputTypeCompatUtils.isEmailVariation(variation)) {
return KeyboardId.MODE_EMAIL;
} else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
return KeyboardId.MODE_URL;
@@ -501,42 +576,6 @@ public class Utils {
}
}
- public static boolean isEmailVariation(int variation) {
- return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
- || variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
- }
-
- public static boolean isWebInputType(int inputType) {
- final int variation =
- inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
- return (variation
- == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT))
- || (variation
- == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD))
- || (variation
- == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS));
- }
-
- // Please refer to TextView.isPasswordInputType
- public static boolean isPasswordInputType(int inputType) {
- final int variation =
- inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
- return (variation
- == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD))
- || (variation
- == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD))
- || (variation
- == (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD));
- }
-
- // Please refer to TextView.isVisiblePasswordInputType
- public static boolean isVisiblePasswordInputType(int inputType) {
- final int variation =
- inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
- return variation
- == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
- }
-
public static boolean containsInCsv(String key, String csv) {
if (csv == null)
return false;
@@ -560,7 +599,9 @@ public class Utils {
* @return main dictionary resource id
*/
public static int getMainDictionaryResourceId(Resources res) {
- return res.getIdentifier("main", "raw", LatinIME.class.getPackage().getName());
+ final String MAIN_DIC_NAME = "main";
+ String packageName = LatinIME.class.getPackage().getName();
+ return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName);
}
public static void loadNativeLibrary() {
@@ -570,4 +611,108 @@ public class Utils {
Log.e(TAG, "Could not load native library jni_latinime");
}
}
+
+ /**
+ * Returns true if a and b are equal ignoring the case of the character.
+ * @param a first character to check
+ * @param b second character to check
+ * @return {@code true} if a and b are equal, {@code false} otherwise.
+ */
+ public static boolean equalsIgnoreCase(char a, char b) {
+ // Some language, such as Turkish, need testing both cases.
+ return a == b
+ || Character.toLowerCase(a) == Character.toLowerCase(b)
+ || Character.toUpperCase(a) == Character.toUpperCase(b);
+ }
+
+ /**
+ * Returns true if a and b are equal ignoring the case of the characters, including if they are
+ * both null.
+ * @param a first CharSequence to check
+ * @param b second CharSequence to check
+ * @return {@code true} if a and b are equal, {@code false} otherwise.
+ */
+ public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) {
+ if (a == b)
+ return true; // including both a and b are null.
+ if (a == null || b == null)
+ return false;
+ final int length = a.length();
+ if (length != b.length())
+ return false;
+ for (int i = 0; i < length; i++) {
+ if (!equalsIgnoreCase(a.charAt(i), b.charAt(i)))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns true if a and b are equal ignoring the case of the characters, including if a is null
+ * and b is zero length.
+ * @param a CharSequence to check
+ * @param b character array to check
+ * @param offset start offset of array b
+ * @param length length of characters in array b
+ * @return {@code true} if a and b are equal, {@code false} otherwise.
+ * @throws IndexOutOfBoundsException
+ * if {@code offset < 0 || length < 0 || offset + length > data.length}.
+ * @throws NullPointerException if {@code b == null}.
+ */
+ public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) {
+ if (offset < 0 || length < 0 || length > b.length - offset)
+ throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset
+ + " length=" + length);
+ if (a == null)
+ return length == 0; // including a is null and b is zero length.
+ if (a.length() != length)
+ return false;
+ for (int i = 0; i < length; i++) {
+ if (!equalsIgnoreCase(a.charAt(i), b[offset + i]))
+ return false;
+ }
+ return true;
+ }
+
+ public static float getDipScale(Context context) {
+ final float scale = context.getResources().getDisplayMetrics().density;
+ return scale;
+ }
+
+ /** Convert pixel to DIP */
+ public static int dipToPixel(float scale, int dip) {
+ return (int) (dip * scale + 0.5);
+ }
+
+ public static Locale setSystemLocale(Resources res, Locale newLocale) {
+ final Configuration conf = res.getConfiguration();
+ final Locale saveLocale = conf.locale;
+ conf.locale = newLocale;
+ res.updateConfiguration(conf, res.getDisplayMetrics());
+ return saveLocale;
+ }
+
+ private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>();
+
+ public static Locale constructLocaleFromString(String localeStr) {
+ if (localeStr == null)
+ return null;
+ synchronized (sLocaleCache) {
+ if (sLocaleCache.containsKey(localeStr))
+ return sLocaleCache.get(localeStr);
+ Locale retval = null;
+ String[] localeParams = localeStr.split("_", 3);
+ if (localeParams.length == 1) {
+ retval = new Locale(localeParams[0]);
+ } else if (localeParams.length == 2) {
+ retval = new Locale(localeParams[0], localeParams[1]);
+ } else if (localeParams.length == 3) {
+ retval = new Locale(localeParams[0], localeParams[1], localeParams[2]);
+ }
+ if (retval != null) {
+ sLocaleCache.put(localeStr, retval);
+ }
+ return retval;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
index 2389d4e3c..4377373d2 100644
--- a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
+++ b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
@@ -39,6 +39,7 @@ public class WhitelistDictionary extends Dictionary {
public static WhitelistDictionary init(Context context) {
synchronized (sInstance) {
if (context != null) {
+ // Wordlist is initialized by the proper language in Suggestion.java#init
sInstance.initWordlist(
context.getResources().getStringArray(R.array.wordlist_whitelist));
} else {
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 02583895b..af5e4b179 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -31,18 +31,18 @@ public class WordComposer {
/**
* The list of unicode values for each keystroke (including surrounding keys)
*/
- private final ArrayList<int[]> mCodes;
+ private ArrayList<int[]> mCodes;
private int mTypedLength;
- private final int[] mXCoordinates;
- private final int[] mYCoordinates;
+ private int[] mXCoordinates;
+ private int[] mYCoordinates;
/**
* The word chosen from the candidate list, until it is committed.
*/
private String mPreferredWord;
- private final StringBuilder mTypedWord;
+ private StringBuilder mTypedWord;
private int mCapsCount;
@@ -62,7 +62,11 @@ public class WordComposer {
mYCoordinates = new int[N];
}
- WordComposer(WordComposer source) {
+ public WordComposer(WordComposer source) {
+ init(source);
+ }
+
+ public void init(WordComposer source) {
mCodes = new ArrayList<int[]>(source.mCodes);
mPreferredWord = source.mPreferredWord;
mTypedWord = new StringBuilder(source.mTypedWord);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java
new file mode 100644
index 000000000..63c6d69d7
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java
@@ -0,0 +1,115 @@
+/*
+ * 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.spellcheck;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.android.inputmethod.compat.ArraysCompatUtils;
+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.DictionaryFactory;
+import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Implements spell checking methods.
+ */
+public class SpellChecker {
+
+ public final Dictionary mDictionary;
+
+ public SpellChecker(final Context context, final Locale locale) {
+ final Resources resources = context.getResources();
+ final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
+ mDictionary = DictionaryFactory.createDictionaryFromManager(context, locale,
+ fallbackResourceId);
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Finds out whether a word is in the dictionary or not.
+ *
+ * @param text the sequence containing the word to check for.
+ * @param start the index of the first character of the word in text.
+ * @param end the index of the next-to-last character in text.
+ * @return true if the word is in the dictionary, false otherwise.
+ */
+ public boolean isCorrect(final CharSequence text, final int start, final int end) {
+ return mDictionary.isValidWord(text.subSequence(start, end));
+ }
+
+ private static class SuggestionsGatherer implements WordCallback {
+ private final int DEFAULT_SUGGESTION_LENGTH = 16;
+ private final List<String> mSuggestions = new LinkedList<String>();
+ private int[] mScores = new int[DEFAULT_SUGGESTION_LENGTH];
+ private int mLength = 0;
+
+ @Override
+ synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
+ int dicTypeId, DataType dataType) {
+ if (mLength >= mScores.length) {
+ final int newLength = mScores.length * 2;
+ mScores = new int[newLength];
+ }
+ 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.
+ final int insertionIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;
+ System.arraycopy(mScores, insertionIndex, mScores, insertionIndex + 1,
+ mLength - insertionIndex);
+ mLength += 1;
+ mScores[insertionIndex] = score;
+ mSuggestions.add(insertionIndex, new String(word, wordOffset, wordLength));
+ return true;
+ }
+
+ public List<String> getGatheredSuggestions() {
+ return mSuggestions;
+ }
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Gets a list of suggestions for a specific string.
+ *
+ * This returns a list of possible corrections for the text passed as an
+ * arguments. It may split or group words, and even perform grammatical
+ * analysis.
+ *
+ * @param text the sequence containing the word to check for.
+ * @param start the index of the first character of the word in text.
+ * @param end the index of the next-to-last character in text.
+ * @return a list of possible suggestions to replace the text.
+ */
+ public List<String> getSuggestions(final CharSequence text, final int start, final int end) {
+ final SuggestionsGatherer suggestionsGatherer = new SuggestionsGatherer();
+ final WordComposer composer = new WordComposer();
+ for (int i = start; i < end; ++i) {
+ int character = text.charAt(i);
+ composer.add(character, new int[] { character },
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
+ }
+ mDictionary.getWords(composer, suggestionsGatherer);
+ return suggestionsGatherer.getGatheredSuggestions();
+ }
+}