aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/AndroidManifest.xml2
-rw-r--r--java/proguard.flags4
-rw-r--r--java/res/anim/key_preview_fadeout.xml29
-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_candidate_normal.9.pngbin248 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.pngbin472 -> 511 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.pngbin649 -> 760 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.pngbin944 -> 1088 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.pngbin663 -> 730 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.pngbin869 -> 940 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.pngbin1119 -> 1260 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.pngbin1370 -> 1649 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin1315 -> 1696 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.pngbin448 -> 461 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.pngbin126 -> 332 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.pngbin453 -> 498 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.pngbin649 -> 811 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal.9.pngbin904 -> 715 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off.9.pngbin1076 -> 1001 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.pngbin2059 -> 2389 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on.9.pngbin1137 -> 1077 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.pngbin2029 -> 2408 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.pngbin1719 -> 2213 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed.9.pngbin831 -> 745 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.pngbin1041 -> 1042 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.pngbin1086 -> 1105 bytes
-rw-r--r--java/res/drawable-hdpi/cancel.pngbin9335 -> 3992 bytes
-rw-r--r--java/res/drawable-hdpi/candidate_feedback_background.9.pngbin1607 -> 833 bytes
-rw-r--r--java/res/drawable-hdpi/caution.pngbin2451 -> 1641 bytes
-rw-r--r--java/res/drawable-hdpi/dialog_bubble_step02.9.pngbin1422 -> 1475 bytes
-rw-r--r--java/res/drawable-hdpi/dialog_bubble_step07.9.pngbin7031 -> 6012 bytes
-rw-r--r--java/res/drawable-hdpi/highlight_pressed.pngbin1152 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/hint_popup.9.pngbin242 -> 226 bytes
-rw-r--r--java/res/drawable-hdpi/ic_dialog_keyboard.pngbin1157 -> 807 bytes
-rw-r--r--java/res/drawable-hdpi/ic_mic_dialog.pngbin4083 -> 3634 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_keyboard.pngbin812 -> 1068 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_mic.pngbin892 -> 681 bytes
-rw-r--r--java/res/drawable-hdpi/ic_suggest_strip_microphone.pngbin970 -> 548 bytes
-rw-r--r--java/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.pngbin795 -> 438 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background.9.pngbin207 -> 200 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_dark_background.9.pngbin210 -> 1041 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_0.9.pngbin377 -> 379 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_1.9.pngbin347 -> 301 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_2.9.pngbin382 -> 404 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_3.9.pngbin401 -> 413 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_4.9.pngbin375 -> 341 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_5.9.pngbin402 -> 388 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_6.9.pngbin392 -> 413 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_7.9.pngbin379 -> 367 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_8.9.pngbin400 -> 417 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_hint_9.9.pngbin395 -> 417 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background.9.pngbin937 -> 1099 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.pngbin136 -> 4040 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.pngbin1099 -> 1310 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background.9.pngbin1204 -> 1494 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip.9.pngbin248 -> 215 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip_divider.pngbin2946 -> 1012 bytes
-rw-r--r--java/res/drawable-hdpi/mic_slash.pngbin12569 -> 6995 bytes
-rw-r--r--java/res/drawable-hdpi/ok_cancel.pngbin4043 -> 774 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level0.pngbin7411 -> 6017 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level1.pngbin7471 -> 6267 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level2.pngbin7526 -> 6359 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level3.pngbin7676 -> 6506 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level4.pngbin7672 -> 6542 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level5.pngbin7498 -> 6463 bytes
-rw-r--r--java/res/drawable-hdpi/speak_now_level6.pngbin11212 -> 6782 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_123_mic.pngbin2583 -> 2576 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_delete.pngbin1856 -> 2314 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_done.pngbin1837 -> 1588 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_mic.pngbin1453 -> 1410 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num0.pngbin1928 -> 1903 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num1.pngbin899 -> 792 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num2.pngbin2805 -> 3241 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num3.pngbin2578 -> 2829 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num4.pngbin2489 -> 2638 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num5.pngbin2287 -> 2532 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num6.pngbin3017 -> 3568 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num7.pngbin3108 -> 3687 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num8.pngbin2719 -> 2952 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_num9.pngbin3330 -> 3887 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_numalt.pngbin2724 -> 2971 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_numpound.pngbin1633 -> 1577 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_numstar.pngbin1675 -> 1742 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_return.pngbin1426 -> 1111 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_search.pngbin2045 -> 1612 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_settings.pngbin1710 -> 729 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_shift.pngbin1820 -> 1474 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_shift_locked.pngbin1467 -> 1115 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_space.pngbin790 -> 358 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_tab.pngbin1123 -> 1008 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_123_mic.pngbin2510 -> 2575 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete.pngbin4003 -> 599 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_done.pngbin1827 -> 1593 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.pngbin6061 -> 3541 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_delete.pngbin4019 -> 681 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_done.pngbin1711 -> 1068 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.pngbin3397 -> 1275 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.pngbin3388 -> 1329 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_mic.pngbin4637 -> 2494 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_numalt.pngbin5931 -> 3797 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_return.pngbin4346 -> 2018 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_search.pngbin4658 -> 2335 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_settings.pngbin4641 -> 1558 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_shift.pngbin3865 -> 677 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.pngbin3845 -> 652 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_space.pngbin3908 -> 1336 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_feedback_tab.pngbin4111 -> 1707 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_arrows_left.pngbin3220 -> 1253 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_arrows_right.pngbin3286 -> 1372 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic.pngbin3893 -> 886 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num0.pngbin1872 -> 1931 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num1.pngbin867 -> 809 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num2.pngbin2720 -> 3214 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num3.pngbin2523 -> 2805 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num4.pngbin2419 -> 2647 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num5.pngbin2230 -> 2536 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num6.pngbin2950 -> 3573 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num7.pngbin3035 -> 3684 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num8.pngbin2628 -> 2904 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_num9.pngbin3255 -> 3860 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numalt.pngbin2664 -> 2919 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numpound.pngbin1583 -> 1600 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_numstar.pngbin1618 -> 1749 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return.pngbin4024 -> 1719 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search.pngbin4248 -> 1260 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings.pngbin4015 -> 1094 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift.pngbin3740 -> 640 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked.pngbin3686 -> 593 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space.pngbin3331 -> 326 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_led.9.pngbin557 -> 3249 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab.pngbin3792 -> 1434 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo.pngbin1328 -> 900 bytes
-rw-r--r--java/res/drawable-hdpi/voice_ime_background.9.pngbin1348 -> 1271 bytes
-rw-r--r--java/res/drawable-hdpi/voice_swipe_hint.pngbin4028 -> 5965 bytes
-rwxr-xr-x[-rw-r--r--]java/res/drawable-hdpi/working.pngbin4179 -> 1180 bytes
-rw-r--r--java/res/drawable-mdpi/btn_candidate_normal.9.pngbin205 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/highlight_pressed.pngbin593 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.pngbin1004 -> 3804 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo.pngbin1587 -> 386 bytes
-rw-r--r--java/res/drawable-mdpi/top_suggest_line_holo.9.pngbin1012 -> 0 bytes
-rw-r--r--java/res/drawable/btn_candidate.xml2
-rw-r--r--java/res/drawable/ic_suggest_scroll_background.xml25
-rw-r--r--java/res/drawable/keyboard_key_feedback_honeycomb.xml2
-rw-r--r--java/res/layout-xlarge/candidate.xml23
-rw-r--r--java/res/layout-xlarge/candidates.xml43
-rw-r--r--java/res/layout-xlarge/keyboard_popup_honeycomb.xml41
-rw-r--r--java/res/layout-xlarge/recognition_status.xml101
-rw-r--r--java/res/layout/candidate.xml23
-rw-r--r--java/res/layout/candidates.xml14
-rw-r--r--java/res/layout/input_basic.xml3
-rw-r--r--java/res/layout/input_basic_highcontrast.xml4
-rw-r--r--java/res/layout/input_gingerbread.xml5
-rw-r--r--java/res/layout/input_honeycomb.xml7
-rw-r--r--java/res/layout/input_stone_bold.xml5
-rw-r--r--java/res/layout/input_stone_normal.xml5
-rw-r--r--java/res/layout/key_preview_honeycomb.xml2
-rw-r--r--java/res/layout/keyboard_popup.xml13
-rw-r--r--java/res/layout/keyboard_popup_honeycomb.xml13
-rw-r--r--java/res/layout/keyboard_popup_stone.xml (renamed from java/res/layout/input_stone_popup.xml)5
-rw-r--r--java/res/layout/recognition_status.xml29
-rw-r--r--java/res/values-ar/strings.xml23
-rw-r--r--java/res/values-bg/strings.xml23
-rw-r--r--java/res/values-ca/strings.xml23
-rw-r--r--java/res/values-cs/strings.xml23
-rw-r--r--java/res/values-da/strings.xml23
-rw-r--r--java/res/values-de/config.xml (renamed from java/res/xml/kbd_popup_narrow_template.xml)12
-rw-r--r--java/res/values-de/strings.xml23
-rw-r--r--java/res/values-el/strings.xml23
-rw-r--r--java/res/values-en-rGB/strings.xml23
-rw-r--r--java/res/values-es-rUS/strings.xml23
-rw-r--r--java/res/values-es/strings.xml29
-rw-r--r--java/res/values-fa/strings.xml23
-rw-r--r--java/res/values-fi/strings.xml23
-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.xml23
-rw-r--r--java/res/values-hdpi/config.xml (renamed from java/res/anim/key_preview_fadein.xml)15
-rw-r--r--java/res/values-hr/strings.xml23
-rw-r--r--java/res/values-hu/strings.xml23
-rw-r--r--java/res/values-in/strings.xml23
-rw-r--r--java/res/values-it/donottranslate.xml4
-rw-r--r--java/res/values-it/strings.xml23
-rw-r--r--java/res/values-iw/strings.xml23
-rw-r--r--java/res/values-ja/strings.xml23
-rw-r--r--java/res/values-ko/strings.xml23
-rw-r--r--java/res/values-land/dimens.xml13
-rw-r--r--java/res/values-lt/strings.xml23
-rw-r--r--java/res/values-lv/strings.xml23
-rw-r--r--java/res/values-nb/strings.xml23
-rw-r--r--java/res/values-nl/strings.xml23
-rw-r--r--java/res/values-pl/strings.xml23
-rw-r--r--java/res/values-pt-rPT/strings.xml23
-rw-r--r--java/res/values-pt/strings.xml23
-rw-r--r--java/res/values-rm/strings.xml43
-rw-r--r--java/res/values-ro/strings.xml23
-rw-r--r--java/res/values-ru/strings.xml23
-rw-r--r--java/res/values-sk/strings.xml23
-rw-r--r--java/res/values-sl/strings.xml23
-rw-r--r--java/res/values-sr/strings.xml23
-rw-r--r--java/res/values-sv/strings.xml23
-rw-r--r--java/res/values-th/strings.xml23
-rw-r--r--java/res/values-tl/strings.xml23
-rw-r--r--java/res/values-tr/strings.xml23
-rw-r--r--java/res/values-uk/strings.xml23
-rw-r--r--java/res/values-vi/strings.xml23
-rw-r--r--java/res/values-xlarge-land/dimens.xml8
-rw-r--r--java/res/values-xlarge/config.xml8
-rw-r--r--java/res/values-xlarge/dimens.xml17
-rw-r--r--java/res/values-zh-rCN/strings.xml23
-rw-r--r--java/res/values-zh-rTW/strings.xml23
-rw-r--r--java/res/values/attrs.xml9
-rw-r--r--java/res/values/colors.xml2
-rw-r--r--java/res/values/config.xml21
-rw-r--r--java/res/values/dimens.xml33
-rw-r--r--java/res/values/donottranslate-altchars.xml7
-rw-r--r--java/res/values/donottranslate.xml15
-rw-r--r--java/res/values/keycodes.xml27
-rw-r--r--java/res/values/strings.xml48
-rw-r--r--java/res/values/styles.xml6
-rw-r--r--java/res/xml-ar/kbd_qwerty.xml35
-rw-r--r--java/res/xml-cs/kbd_qwerty.xml1
-rw-r--r--java/res/xml-da/kbd_qwerty.xml1
-rw-r--r--java/res/xml-de/kbd_qwerty.xml1
-rw-r--r--java/res/xml-fi/kbd_qwerty.xml1
-rw-r--r--java/res/xml-fr-rCA/kbd_qwerty.xml1
-rw-r--r--java/res/xml-fr-rCH/kbd_qwerty.xml1
-rw-r--r--java/res/xml-fr/kbd_qwerty.xml1
-rw-r--r--java/res/xml-hu/kbd_qwerty.xml1
-rw-r--r--java/res/xml-iw/kbd_qwerty.xml99
-rw-r--r--java/res/xml-nb/kbd_qwerty.xml1
-rw-r--r--java/res/xml-pl/kbd_qwerty.xml (renamed from java/res/xml-xlarge/kbd_qwerty.xml)4
-rw-r--r--java/res/xml-ru/kbd_qwerty.xml1
-rw-r--r--java/res/xml-sr/kbd_qwerty.xml1
-rw-r--r--java/res/xml-sv/kbd_qwerty.xml1
-rw-r--r--java/res/xml-xlarge/kbd_ar_rows.xml139
-rw-r--r--java/res/xml-xlarge/kbd_iw_rows.xml130
-rw-r--r--java/res/xml-xlarge/kbd_key_styles.xml6
-rw-r--r--java/res/xml-xlarge/kbd_sr_rows.xml20
-rw-r--r--java/res/xml-xlarge/kbd_symbols.xml3
-rw-r--r--java/res/xml-xlarge/kbd_symbols_shift.xml3
-rw-r--r--java/res/xml/kbd_ar_rows.xml119
-rw-r--r--java/res/xml/kbd_azerty_rows.xml2
-rw-r--r--java/res/xml/kbd_iw_rows.xml106
-rw-r--r--java/res/xml/kbd_key_styles.xml74
-rw-r--r--java/res/xml/kbd_qwerty.xml1
-rw-r--r--java/res/xml/kbd_qwerty_black_symbol.xml84
-rw-r--r--java/res/xml/kbd_qwerty_f1.xml22
-rw-r--r--java/res/xml/kbd_qwerty_row3.xml2
-rw-r--r--java/res/xml/kbd_qwerty_row4.xml59
-rw-r--r--java/res/xml/kbd_qwertz_rows.xml2
-rw-r--r--java/res/xml/kbd_sr_rows.xml17
-rw-r--r--java/res/xml/kbd_symbols.xml8
-rw-r--r--java/res/xml/kbd_symbols_f1.xml11
-rw-r--r--java/res/xml/kbd_symbols_shift.xml18
-rw-r--r--java/res/xml/kbd_symbols_shift_row4.xml10
-rw-r--r--java/res/xml/method.xml220
-rw-r--r--java/res/xml/prefs.xml168
-rw-r--r--java/res/xml/prefs_for_debug.xml7
-rw-r--r--java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java39
-rw-r--r--java/src/com/android/inputmethod/compat/CompatUtils.java160
-rw-r--r--java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java99
-rw-r--r--java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java91
-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.java155
-rw-r--r--java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java95
-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)144
-rw-r--r--java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java36
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java (renamed from java/src/com/android/inputmethod/latin/InputLanguageSelection.java)150
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java (renamed from java/src/com/android/inputmethod/latin/LanguageSwitcher.java)63
-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)2
-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.java53
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java162
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyStyles.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java65
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java31
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardParser.java39
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java193
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java914
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboard.java220
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java40
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboard.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java81
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java15
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java332
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java1
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java13
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java124
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupPanel.java46
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java126
-rw-r--r--java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java4
-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.java1
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java159
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java151
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java93
-rw-r--r--java/src/com/android/inputmethod/latin/CandidateView.java5
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsDictionary.java15
-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.java158
-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.java38
-rw-r--r--java/src/com/android/inputmethod/latin/Flag.java64
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java1109
-rw-r--r--java/src/com/android/inputmethod/latin/LatinImeLogger.java7
-rw-r--r--java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java29
-rw-r--r--java/src/com/android/inputmethod/latin/Recorrection.java255
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java262
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java369
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java184
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java8
-rw-r--r--java/src/com/android/inputmethod/latin/TextEntryState.java18
-rw-r--r--java/src/com/android/inputmethod/latin/UserBigramDictionary.java10
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java195
-rw-r--r--java/src/com/android/inputmethod/latin/WordAlternatives.java59
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java12
333 files changed, 6793 insertions, 4074 deletions
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index e0eecfc7d..2fbf4c2be 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"/>
diff --git a/java/proguard.flags b/java/proguard.flags
index 729f4ad61..914bd7595 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -18,3 +18,7 @@
-keep class com.android.inputmethod.latin.AutoCorrection {
java.lang.CharSequence getAutoCorrectionWord();
}
+
+-keep class com.android.inputmethod.latin.Utils {
+ boolean equalsIgnoreCase(...);
+}
diff --git a/java/res/anim/key_preview_fadeout.xml b/java/res/anim/key_preview_fadeout.xml
deleted file mode 100644
index 7de5123cd..000000000
--- a/java/res/anim/key_preview_fadeout.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.
-*/
--->
-
-<set
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator"
->
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="0.0"
- android:duration="@integer/config_preview_fadeout_anim_time" />
-</set>
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_candidate_normal.9.png b/java/res/drawable-hdpi/btn_candidate_normal.9.png
deleted file mode 100644
index 7cab5a899..000000000
--- a/java/res/drawable-hdpi/btn_candidate_normal.9.png
+++ /dev/null
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..01fc8ca78 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_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
index dabf77ec6..af4017e2c 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_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
index 6e7d74c88..4c35aca95 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_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
index ddb77c224..174f3452c 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_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
index 1e9227e1c..1fcbd9a88 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_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
index 7207b2ece..072753f37 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_fulltrans_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
index a524168c9..b6c234c04 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 4395e978a..73a8cd1c3 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..1ad746053 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_popup_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png
index 2ed1b3447..e3a77d61b 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_normal.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..431c44967 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..ccd59d5fa 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_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal.9.png
index 6ec7e6592..42c7c146d 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 995780cbf..01e2506b0 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 1388b6694..fad0ec458 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 7215782eb..83c6eb3fc 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 5a94cb6ac..215f8157c 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 c6373a8af..88acdd748 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_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
index 0bd49a0e7..e047eaff1 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 634419f1b..218a2d29e 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 8474f9f42..afe49512e 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/cancel.png b/java/res/drawable-hdpi/cancel.png
index fdf01dba6..506cf99d0 100644
--- a/java/res/drawable-hdpi/cancel.png
+++ b/java/res/drawable-hdpi/cancel.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 16499002e..203c4e640 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 caed9419d..5cb6c54b9 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/dialog_bubble_step02.9.png b/java/res/drawable-hdpi/dialog_bubble_step02.9.png
index 2a3ac18c0..b338364c5 100644
--- a/java/res/drawable-hdpi/dialog_bubble_step02.9.png
+++ b/java/res/drawable-hdpi/dialog_bubble_step02.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/dialog_bubble_step07.9.png b/java/res/drawable-hdpi/dialog_bubble_step07.9.png
index 0a5046b07..94b915432 100644
--- a/java/res/drawable-hdpi/dialog_bubble_step07.9.png
+++ b/java/res/drawable-hdpi/dialog_bubble_step07.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/highlight_pressed.png b/java/res/drawable-hdpi/highlight_pressed.png
deleted file mode 100644
index 638df19bc..000000000
--- a/java/res/drawable-hdpi/highlight_pressed.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/hint_popup.9.png b/java/res/drawable-hdpi/hint_popup.9.png
index 5b2ad5388..b5ec003e6 100644
--- a/java/res/drawable-hdpi/hint_popup.9.png
+++ b/java/res/drawable-hdpi/hint_popup.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_dialog_keyboard.png b/java/res/drawable-hdpi/ic_dialog_keyboard.png
index fb6d89879..c7729566c 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 6498cd589..349dc4b37 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 b5a9fa866..7015e266a 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 5d68e85a6..cb86a5598 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 0462bdd16..c00b4aaa6 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 80c20f691..256dc3d61 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/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background.9.png
index d57463fb6..edffac5b8 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_dark_background.9.png b/java/res/drawable-hdpi/keyboard_dark_background.9.png
index fa3d449f7..f315cbdd4 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_hint_0.9.png b/java/res/drawable-hdpi/keyboard_hint_0.9.png
index da52e0f5b..271264e92 100644
--- a/java/res/drawable-hdpi/keyboard_hint_0.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_0.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_1.9.png b/java/res/drawable-hdpi/keyboard_hint_1.9.png
index 7325c4cbb..eaf374262 100644
--- a/java/res/drawable-hdpi/keyboard_hint_1.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_1.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_2.9.png b/java/res/drawable-hdpi/keyboard_hint_2.9.png
index 35b7f2527..8a1657117 100644
--- a/java/res/drawable-hdpi/keyboard_hint_2.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_2.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_3.9.png b/java/res/drawable-hdpi/keyboard_hint_3.9.png
index 1ae284838..34b501109 100644
--- a/java/res/drawable-hdpi/keyboard_hint_3.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_3.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_4.9.png b/java/res/drawable-hdpi/keyboard_hint_4.9.png
index b67d6dd51..d4cc250dd 100644
--- a/java/res/drawable-hdpi/keyboard_hint_4.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_4.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_5.9.png b/java/res/drawable-hdpi/keyboard_hint_5.9.png
index ec52198d8..6a054b42f 100644
--- a/java/res/drawable-hdpi/keyboard_hint_5.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_5.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_6.9.png b/java/res/drawable-hdpi/keyboard_hint_6.9.png
index 66dcf67e5..66e91400a 100644
--- a/java/res/drawable-hdpi/keyboard_hint_6.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_6.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_7.9.png b/java/res/drawable-hdpi/keyboard_hint_7.9.png
index 9d5499272..5eae24f4f 100644
--- a/java/res/drawable-hdpi/keyboard_hint_7.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_7.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_8.9.png b/java/res/drawable-hdpi/keyboard_hint_8.9.png
index beba1624c..ea7f512fd 100644
--- a/java/res/drawable-hdpi/keyboard_hint_8.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_8.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_hint_9.9.png b/java/res/drawable-hdpi/keyboard_hint_9.9.png
index 31ea54f32..0bf85de93 100644
--- a/java/res/drawable-hdpi/keyboard_hint_9.9.png
+++ b/java/res/drawable-hdpi/keyboard_hint_9.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png
index 27d992375..762a25704 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_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..8d6acacfb 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_more_background.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png
index 33263b9d7..141d2d6be 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_more_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background.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 baff80950..d6b2c7936 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 7cab5a899..0ccdb6ab2 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_divider.png b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
index 7fca8c608..7ca3e6131 100644
--- a/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-hdpi/mic_slash.png b/java/res/drawable-hdpi/mic_slash.png
index 71f4dc506..dc8da6252 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/ok_cancel.png b/java/res/drawable-hdpi/ok_cancel.png
index 48c00f094..f11e57a38 100644
--- a/java/res/drawable-hdpi/ok_cancel.png
+++ b/java/res/drawable-hdpi/ok_cancel.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level0.png b/java/res/drawable-hdpi/speak_now_level0.png
index 31571f75b..342849cfe 100644
--- a/java/res/drawable-hdpi/speak_now_level0.png
+++ b/java/res/drawable-hdpi/speak_now_level0.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level1.png b/java/res/drawable-hdpi/speak_now_level1.png
index c8d0aae5d..8947a4306 100644
--- a/java/res/drawable-hdpi/speak_now_level1.png
+++ b/java/res/drawable-hdpi/speak_now_level1.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level2.png b/java/res/drawable-hdpi/speak_now_level2.png
index 123eea66e..44fc58c4e 100644
--- a/java/res/drawable-hdpi/speak_now_level2.png
+++ b/java/res/drawable-hdpi/speak_now_level2.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level3.png b/java/res/drawable-hdpi/speak_now_level3.png
index a8a2c5cff..cfa5c1b87 100644
--- a/java/res/drawable-hdpi/speak_now_level3.png
+++ b/java/res/drawable-hdpi/speak_now_level3.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level4.png b/java/res/drawable-hdpi/speak_now_level4.png
index b84d7b0e9..a050d8836 100644
--- a/java/res/drawable-hdpi/speak_now_level4.png
+++ b/java/res/drawable-hdpi/speak_now_level4.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level5.png b/java/res/drawable-hdpi/speak_now_level5.png
index 8dd2b607f..8cd5ae7ad 100644
--- a/java/res/drawable-hdpi/speak_now_level5.png
+++ b/java/res/drawable-hdpi/speak_now_level5.png
Binary files differ
diff --git a/java/res/drawable-hdpi/speak_now_level6.png b/java/res/drawable-hdpi/speak_now_level6.png
index 888d0e5c7..9f4481eb4 100644
--- a/java/res/drawable-hdpi/speak_now_level6.png
+++ b/java/res/drawable-hdpi/speak_now_level6.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png
index 24edfaa1c..3e4eff698 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_delete.png b/java/res/drawable-hdpi/sym_bkeyboard_delete.png
index 4ccd218ac..1d24cc85c 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_delete.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_delete.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_done.png b/java/res/drawable-hdpi/sym_bkeyboard_done.png
index 6959aeeef..b77803d21 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_done.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_done.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_mic.png
index 6876fb64a..512f46080 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_mic.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num0.png b/java/res/drawable-hdpi/sym_bkeyboard_num0.png
index 08df3f3dd..678a790de 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num0.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num0.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num1.png b/java/res/drawable-hdpi/sym_bkeyboard_num1.png
index 36d8e5696..4e68e35b3 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num1.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num1.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num2.png b/java/res/drawable-hdpi/sym_bkeyboard_num2.png
index c67fe2ea4..546663fda 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num2.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num2.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num3.png b/java/res/drawable-hdpi/sym_bkeyboard_num3.png
index cf80b2745..57f9a8d8e 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num3.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num3.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num4.png b/java/res/drawable-hdpi/sym_bkeyboard_num4.png
index bfbb55a8f..de504388f 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num4.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num4.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num5.png b/java/res/drawable-hdpi/sym_bkeyboard_num5.png
index 9f121ec12..1d2e1ef89 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num5.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num5.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num6.png b/java/res/drawable-hdpi/sym_bkeyboard_num6.png
index 256186f3a..39788b727 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num6.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num6.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num7.png b/java/res/drawable-hdpi/sym_bkeyboard_num7.png
index 7c8ce205e..fff6f27bf 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num7.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num7.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num8.png b/java/res/drawable-hdpi/sym_bkeyboard_num8.png
index 4cfe7b11c..8cc1a955e 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num8.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num8.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_num9.png b/java/res/drawable-hdpi/sym_bkeyboard_num9.png
index d19c15cc8..021742509 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_num9.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_num9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_numalt.png b/java/res/drawable-hdpi/sym_bkeyboard_numalt.png
index 762fd8cd7..200714f66 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_numalt.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_numalt.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_numpound.png b/java/res/drawable-hdpi/sym_bkeyboard_numpound.png
index 2bd800d68..0a46122b2 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_numpound.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_numpound.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_numstar.png b/java/res/drawable-hdpi/sym_bkeyboard_numstar.png
index b574f83f3..ca22bd535 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_numstar.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_numstar.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_return.png b/java/res/drawable-hdpi/sym_bkeyboard_return.png
index 2f9631a20..426e1599e 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_return.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_return.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_search.png b/java/res/drawable-hdpi/sym_bkeyboard_search.png
index 7a5a0aab8..1b6f884fa 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_search.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_search.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_settings.png b/java/res/drawable-hdpi/sym_bkeyboard_settings.png
index 8a8caa895..08ba18f28 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_settings.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_settings.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift.png b/java/res/drawable-hdpi/sym_bkeyboard_shift.png
index 1e3d5ec14..5a22dd309 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_shift.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_shift.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png
index e8a4d6423..566449126 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_space.png b/java/res/drawable-hdpi/sym_bkeyboard_space.png
index 9937a6288..cd0ebe2f4 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_space.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_space.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_tab.png b/java/res/drawable-hdpi/sym_bkeyboard_tab.png
index 8dee747d2..3466e1271 100644
--- a/java/res/drawable-hdpi/sym_bkeyboard_tab.png
+++ b/java/res/drawable-hdpi/sym_bkeyboard_tab.png
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 6f8292912..62669803d 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_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png
index 8db099a7a..459ebcff8 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_done.png b/java/res/drawable-hdpi/sym_keyboard_done.png
index 6ba51d58c..471c5021b 100644
--- a/java/res/drawable-hdpi/sym_keyboard_done.png
+++ b/java/res/drawable-hdpi/sym_keyboard_done.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
index 4867298fa..eef789680 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_123_mic.png
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
index 7c12f79a1..8322e8e1d 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_done.png b/java/res/drawable-hdpi/sym_keyboard_feedback_done.png
index e79bbb382..7015e266a 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_done.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_done.png
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
index 4f4923b85..889477cfb 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_left.png
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
index ed2ebe66c..b0f6d7feb 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_language_arrows_right.png
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 f228910c3..f82c33ae3 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
index bb69300d1..819236c8e 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_numalt.png
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
index 99fa13cae..f038d3abe 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_return.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_return.png
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
index c006866d2..337f9e4fe 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_search.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_search.png
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 5c685f9c3..8a02be07e 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
index 5b91afb82..abf15f8f9 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_shift.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
index 77e6a5fe9..1fd822ea6 100644
--- a/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
+++ b/java/res/drawable-hdpi/sym_keyboard_feedback_shift_locked.png
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 2d1b4a4b4..70debca9b 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 82280c608..d2efb1619 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
index 34b8e931a..dcc4bd59b 100644
--- a/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png
+++ b/java/res/drawable-hdpi/sym_keyboard_language_arrows_left.png
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
index b6ea3362b..ecf61a98e 100644
--- a/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png
+++ b/java/res/drawable-hdpi/sym_keyboard_language_arrows_right.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png
index 7207f8a92..c8dca62a0 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
index 169efe21e..10ac70b9d 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num0.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num0.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num1.png b/java/res/drawable-hdpi/sym_keyboard_num1.png
index 5b868489f..0fc03efa5 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num1.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num1.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num2.png b/java/res/drawable-hdpi/sym_keyboard_num2.png
index ddbe2199c..283560b35 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num2.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num2.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num3.png b/java/res/drawable-hdpi/sym_keyboard_num3.png
index 1de90f3b1..9a3b3294b 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num3.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num3.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num4.png b/java/res/drawable-hdpi/sym_keyboard_num4.png
index c67ba5206..f13ff1ae9 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num4.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num4.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num5.png b/java/res/drawable-hdpi/sym_keyboard_num5.png
index 8410f2537..c251329fa 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num5.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num5.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num6.png b/java/res/drawable-hdpi/sym_keyboard_num6.png
index 22fa29d3f..4acba4c91 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num6.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num6.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num7.png b/java/res/drawable-hdpi/sym_keyboard_num7.png
index a3798ea34..14931c18c 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num7.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num7.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num8.png b/java/res/drawable-hdpi/sym_keyboard_num8.png
index 7e963ad6b..d4973fdc9 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num8.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num8.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_num9.png b/java/res/drawable-hdpi/sym_keyboard_num9.png
index 1160d8545..49cec66f4 100644
--- a/java/res/drawable-hdpi/sym_keyboard_num9.png
+++ b/java/res/drawable-hdpi/sym_keyboard_num9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numalt.png b/java/res/drawable-hdpi/sym_keyboard_numalt.png
index f3a73deb0..3cc5311cd 100644
--- a/java/res/drawable-hdpi/sym_keyboard_numalt.png
+++ b/java/res/drawable-hdpi/sym_keyboard_numalt.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numpound.png b/java/res/drawable-hdpi/sym_keyboard_numpound.png
index 471f4fda3..d09133929 100644
--- a/java/res/drawable-hdpi/sym_keyboard_numpound.png
+++ b/java/res/drawable-hdpi/sym_keyboard_numpound.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_numstar.png b/java/res/drawable-hdpi/sym_keyboard_numstar.png
index 017c0f461..e838e169f 100644
--- a/java/res/drawable-hdpi/sym_keyboard_numstar.png
+++ b/java/res/drawable-hdpi/sym_keyboard_numstar.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png
index 984db426e..9d97e1efd 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_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png
index 179e725f6..1aa22d7e2 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_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png
index 164117812..35d1ed6e6 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_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png
index 2b3bd668d..bf217d147 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_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
index 8a34a98a3..d11b39712 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_space.png b/java/res/drawable-hdpi/sym_keyboard_space.png
index dacc97d0a..fcd20de7d 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_led.9.png b/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
index c76f64b94..2c6f4a925 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_tab.png b/java/res/drawable-hdpi/sym_keyboard_tab.png
index efd740b5b..51d17d989 100644
--- a/java/res/drawable-hdpi/sym_keyboard_tab.png
+++ b/java/res/drawable-hdpi/sym_keyboard_tab.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 8a445eb56..6e6279a8a 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/voice_ime_background.9.png b/java/res/drawable-hdpi/voice_ime_background.9.png
index a604f497c..42868522f 100644
--- a/java/res/drawable-hdpi/voice_ime_background.9.png
+++ b/java/res/drawable-hdpi/voice_ime_background.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/voice_swipe_hint.png b/java/res/drawable-hdpi/voice_swipe_hint.png
index 976fd56d6..130f83a9c 100644
--- a/java/res/drawable-hdpi/voice_swipe_hint.png
+++ b/java/res/drawable-hdpi/voice_swipe_hint.png
Binary files differ
diff --git a/java/res/drawable-hdpi/working.png b/java/res/drawable-hdpi/working.png
index c43439e93..5ea702307 100644..100755
--- a/java/res/drawable-hdpi/working.png
+++ b/java/res/drawable-hdpi/working.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_candidate_normal.9.png b/java/res/drawable-mdpi/btn_candidate_normal.9.png
deleted file mode 100644
index fa6c0feff..000000000
--- a/java/res/drawable-mdpi/btn_candidate_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/highlight_pressed.png b/java/res/drawable-mdpi/highlight_pressed.png
deleted file mode 100644
index d27f1061a..000000000
--- a/java/res/drawable-mdpi/highlight_pressed.png
+++ /dev/null
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 a7acb4a4d..286cf84fc 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/sym_keyboard_voice_off_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
index 081a13096..44919dfcc 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-mdpi/top_suggest_line_holo.9.png b/java/res/drawable-mdpi/top_suggest_line_holo.9.png
deleted file mode 100644
index 8fdffd317..000000000
--- a/java/res/drawable-mdpi/top_suggest_line_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable/btn_candidate.xml b/java/res/drawable/btn_candidate.xml
index b0c1c3038..efcee9f54 100644
--- a/java/res/drawable/btn_candidate.xml
+++ b/java/res/drawable/btn_candidate.xml
@@ -24,6 +24,4 @@
<item
android:state_pressed="true"
android:drawable="@drawable/btn_candidate_pressed" />
- <item
- android:drawable="@drawable/btn_candidate_normal" />
</selector>
diff --git a/java/res/drawable/ic_suggest_scroll_background.xml b/java/res/drawable/ic_suggest_scroll_background.xml
deleted file mode 100644
index 9d246e40e..000000000
--- a/java/res/drawable/ic_suggest_scroll_background.xml
+++ /dev/null
@@ -1,25 +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">
-
- <item android:state_pressed="false"
- android:drawable="@android:color/transparent" />
-
- <item android:state_pressed="true"
- android:drawable="@drawable/highlight_pressed" />
-
-</selector> \ No newline at end of file
diff --git a/java/res/drawable/keyboard_key_feedback_honeycomb.xml b/java/res/drawable/keyboard_key_feedback_honeycomb.xml
index dd9b53e46..a3ea140cd 100644
--- a/java/res/drawable/keyboard_key_feedback_honeycomb.xml
+++ b/java/res/drawable/keyboard_key_feedback_honeycomb.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_long_pressable="true"
- android:drawable="@drawable/keyboard_key_feedback_more_background" />
+ android:drawable="@drawable/keyboard_key_feedback_more_background_holo" />
<item android:drawable="@drawable/keyboard_key_feedback_background_holo" />
</selector>
diff --git a/java/res/layout-xlarge/candidate.xml b/java/res/layout-xlarge/candidate.xml
index 74532a1e2..582e64261 100644
--- a/java/res/layout-xlarge/candidate.xml
+++ b/java/res/layout-xlarge/candidate.xml
@@ -20,41 +20,40 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
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:layout_height="match_parent"
+ android:src="@drawable/keyboard_suggest_strip_divider"
+ android:paddingRight="@dimen/candidate_padding"
+ android:paddingLeft="@dimen/candidate_padding"
+ android:visibility="invisible"
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:layout_height="match_parent"
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" />
+ android:gravity="center_vertical|center_horizontal" />
<TextView
android:id="@+id/candidate_debug_info"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:visibility="gone"
android:textSize="10dip"
android:textColor="#ff808080"
android:focusable="false"
android:clickable="false"
- android:gravity="bottom"
- android:paddingLeft="4dip" />
+ android:gravity="bottom" />
</LinearLayout>
diff --git a/java/res/layout-xlarge/candidates.xml b/java/res/layout-xlarge/candidates.xml
index e2ddb84b1..096a0adf1 100644
--- a/java/res/layout-xlarge/candidates.xml
+++ b/java/res/layout-xlarge/candidates.xml
@@ -21,25 +21,34 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
+ android:gravity="bottom"
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"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/candidate_strip_minimum_height"
>
- <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"
+ <!-- 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:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_suggest_strip_holo"
+ android:paddingRight="@dimen/candidate_strip_padding"
+ android:paddingLeft="@dimen/candidate_strip_padding"
>
- <com.android.inputmethod.latin.CandidateView
- android:id="@+id/candidates"
- android:orientation="horizontal"
+ <HorizontalScrollView
android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip_holo" />
- </HorizontalScrollView>
+ android:layout_height="wrap_content"
+ android:fadingEdge="horizontal"
+ android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
+ android:scrollbars="none"
+ >
+ <com.android.inputmethod.latin.CandidateView
+ android:id="@+id/candidates"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/candidate_strip_height"
+ android:gravity="center_vertical" />
+ </HorizontalScrollView>
+ </LinearLayout>
</LinearLayout>
diff --git a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml b/java/res/layout-xlarge/keyboard_popup_honeycomb.xml
deleted file mode 100644
index 0b8229ca5..000000000
--- a/java/res/layout-xlarge/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-xlarge/recognition_status.xml b/java/res/layout-xlarge/recognition_status.xml
new file mode 100644
index 000000000..40bc09823
--- /dev/null
+++ b/java/res/layout-xlarge/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
index f2c4126b3..5472a1dd1 100644
--- a/java/res/layout/candidate.xml
+++ b/java/res/layout/candidate.xml
@@ -20,41 +20,40 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
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:layout_height="match_parent"
+ android:src="@drawable/keyboard_suggest_strip_divider"
+ android:paddingRight="@dimen/candidate_padding"
+ android:paddingLeft="@dimen/candidate_padding"
+ android:visibility="invisible"
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:layout_height="match_parent"
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" />
+ android:gravity="center_vertical|center_horizontal" />
<TextView
android:id="@+id/candidate_debug_info"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:visibility="gone"
android:textSize="10dip"
android:textColor="#ff808080"
android:focusable="false"
android:clickable="false"
- android:gravity="bottom"
- android:paddingLeft="4dip" />
+ android:gravity="bottom" />
</LinearLayout>
diff --git a/java/res/layout/candidates.xml b/java/res/layout/candidates.xml
index 1b8d04183..3d91c1d20 100644
--- a/java/res/layout/candidates.xml
+++ b/java/res/layout/candidates.xml
@@ -21,25 +21,25 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
+ android:gravity="bottom"
android:layout_width="match_parent"
- android:layout_height="@dimen/candidate_strip_height"
- android:background="@drawable/keyboard_suggest_strip"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/candidate_strip_minimum_height"
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:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyboard_suggest_strip"
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" />
+ android:gravity="center_vertical" />
</HorizontalScrollView>
</LinearLayout>
diff --git a/java/res/layout/input_basic.xml b/java/res/layout/input_basic.xml
index 7b85bae94..8666daece 100644
--- a/java/res/layout/input_basic.xml
+++ b/java/res/layout/input_basic.xml
@@ -21,10 +21,11 @@
<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:id="@+id/latin_keyboard_view"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:padding="0dip"
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
index d9200fd5e..4829c7d7c 100644
--- a/java/res/layout/input_basic_highcontrast.xml
+++ b/java/res/layout/input_basic_highcontrast.xml
@@ -21,11 +21,11 @@
<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:id="@+id/latin_keyboard_view"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:padding="0dip"
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
index 6233e6dc6..ccca501af 100644
--- a/java/res/layout/input_gingerbread.xml
+++ b/java/res/layout/input_gingerbread.xml
@@ -21,12 +21,11 @@
<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:id="@+id/latin_keyboard_view"
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:padding="0dip"
android:background="@drawable/keyboard_dark_background"
latin:keyBackground="@drawable/btn_keyboard_key_gingerbread"
diff --git a/java/res/layout/input_honeycomb.xml b/java/res/layout/input_honeycomb.xml
index 6ccc63c2b..8dadafd81 100644
--- a/java/res/layout/input_honeycomb.xml
+++ b/java/res/layout/input_honeycomb.xml
@@ -21,16 +21,17 @@
<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:id="@+id/latin_keyboard_view"
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:padding="0dip"
android:background="@drawable/keyboard_background_holo"
latin:keyBackground="@drawable/btn_keyboard_key_honeycomb"
latin:keyPreviewLayout="@layout/key_preview_honeycomb"
+ latin:keyPreviewHeight="@dimen/key_preview_height_holo"
+ latin:keyPreviewOffset="@dimen/key_preview_offset_holo"
latin:popupLayout="@layout/keyboard_popup_honeycomb"
latin:keyTextColorDisabled="#FF63666D"
latin:keyLetterStyle="bold"
diff --git a/java/res/layout/input_stone_bold.xml b/java/res/layout/input_stone_bold.xml
index 6fdc93855..a0b40684f 100644
--- a/java/res/layout/input_stone_bold.xml
+++ b/java/res/layout/input_stone_bold.xml
@@ -21,10 +21,11 @@
<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:id="@+id/latin_keyboard_view"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:padding="0dip"
android:background="@drawable/keyboard_background"
latin:keyBackground="@drawable/btn_keyboard_key_stone"
@@ -33,5 +34,5 @@
latin:shadowColor="@color/latinkeyboard_key_color_white"
latin:keyLetterStyle="bold"
latin:colorScheme="black"
- latin:popupLayout="@layout/input_stone_popup"
+ latin:popupLayout="@layout/keyboard_popup_stone"
/>
diff --git a/java/res/layout/input_stone_normal.xml b/java/res/layout/input_stone_normal.xml
index 6ae9aed55..41cbc16fa 100644
--- a/java/res/layout/input_stone_normal.xml
+++ b/java/res/layout/input_stone_normal.xml
@@ -21,10 +21,11 @@
<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:id="@+id/latin_keyboard_view"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:padding="0dip"
android:background="@drawable/keyboard_background"
latin:keyBackground="@drawable/btn_keyboard_key_stone"
@@ -32,5 +33,5 @@
latin:keyTextColorDisabled="#FF808080"
latin:shadowColor="@color/latinkeyboard_key_color_white"
latin:colorScheme="black"
- latin:popupLayout="@layout/input_stone_popup"
+ latin:popupLayout="@layout/keyboard_popup_stone"
/>
diff --git a/java/res/layout/key_preview_honeycomb.xml b/java/res/layout/key_preview_honeycomb.xml
index a90fe5588..2fbfbb517 100644
--- a/java/res/layout/key_preview_honeycomb.xml
+++ b/java/res/layout/key_preview_honeycomb.xml
@@ -23,7 +23,7 @@
android:layout_height="80sp"
android:textSize="40sp"
android:textColor="@color/latinkeyboard_key_color_white"
- android:minWidth="24dip"
+ android:minWidth="32dip"
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..0317d8deb 100644
--- a/java/res/layout/keyboard_popup.xml
+++ b/java/res/layout/keyboard_popup.xml
@@ -19,20 +19,19 @@
-->
<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"
+ android:paddingLeft="@dimen/mini_keyboard_horizontal_padding"
+ android:paddingRight="@dimen/mini_keyboard_horizontal_padding"
>
- <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"
diff --git a/java/res/layout/keyboard_popup_honeycomb.xml b/java/res/layout/keyboard_popup_honeycomb.xml
index e5fcbd44c..2ddcbdc0c 100644
--- a/java/res/layout/keyboard_popup_honeycomb.xml
+++ b/java/res/layout/keyboard_popup_honeycomb.xml
@@ -19,20 +19,19 @@
-->
<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_holo"
- android:paddingLeft="24dip"
- android:paddingRight="24dip"
+ android:paddingLeft="@dimen/mini_keyboard_horizontal_padding_holo"
+ android:paddingRight="@dimen/mini_keyboard_horizontal_padding_holo"
>
- <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_honeycomb_popup"
latin:keyHysteresisDistance="0dip"
diff --git a/java/res/layout/input_stone_popup.xml b/java/res/layout/keyboard_popup_stone.xml
index b4da04536..94176b244 100644
--- a/java/res/layout/input_stone_popup.xml
+++ b/java/res/layout/keyboard_popup_stone.xml
@@ -25,9 +25,9 @@
android:orientation="horizontal"
android:background="@drawable/keyboard_popup_panel_background"
>
- <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_height="wrap_content"
@@ -36,6 +36,5 @@
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/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-ar/strings.xml b/java/res/values-ar/strings.xml
index d1d70ff74..df5b87ac1 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"استخدام الأحرف الكبيرة تلقائيًا"</string>
<string name="quick_fixes" msgid="5353213327680897927">"إصلاحات سريعة"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"تصحيح الأخطاء المكتوبة الشائعة"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"المس الكلمات التي تم إدخالها لتصحيحها، وذلك فقط عندما تكون الاقتراحات مرئية."</string>
<string name="keyboard_layout" msgid="437433231038683666">"مظهر لوحة المفاتيح"</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_en_GB_keyboard" msgid="7945856548410373708">"لوحة مفاتيح إنجليزية (بريطانيا)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 418bb18a1..7f59a13db 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Бързи корекции"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Коригира най-честите грешки при въвеждане"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Докоснете въведените думи, за да ги поправите – само когато предложенията са видими"</string>
<string name="keyboard_layout" msgid="437433231038683666">"Тема на клавиатурата"</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_en_GB_keyboard" msgid="7945856548410373708">"английска (Великобрит.) клавиатура"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 1bfa3a9ab..36939fef7 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</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>
@@ -36,6 +38,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">"Utilitza el 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 +48,10 @@
<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="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 la paraula anterior per a la predicció també"</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 +61,6 @@
<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="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 Mobile"</a>"."</string>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Teclat anglès (Regne Unit)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index b0cb7daf7..132bc1c29 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Klávesnice – angličtina (VB)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index eb79888d6..ad92b24d1 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Skriv aut. med stort"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Hurtige løsninger"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Retter almindelige stavefejl"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Engelsk tastatur (Storbritannien)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/xml/kbd_popup_narrow_template.xml b/java/res/values-de/config.xml
index 36caf1c15..272ff326f 100644
--- a/java/res/xml/kbd_popup_narrow_template.xml
+++ b/java/res/values-de/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.
@@ -18,10 +18,6 @@
*/
-->
-<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="9.45%p"
- latin:horizontalGap="0px"
- latin:verticalGap="0px"
- latin:rowHeight="@dimen/popup_key_height"
- >
-</Keyboard>
+<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 e79d2c833..65f0faa32 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschr."</string>
<string name="quick_fixes" msgid="5353213327680897927">"Quick Fixes"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Korrigiert gängige Tippfehler"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="voice_warning_title" msgid="4419354150908395008">"Spracheingabe"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spracheingaben werden derzeit 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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Englische Tastatur (GB)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 4412fa45d..5cee959a0 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Γρήγορες διορθώσεις"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Διορθώνει συνηθισμένα λάθη πληκτρολόγησης"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Αγγίξτε τις λέξες για να τις διορθώσετε, μόνο όταν οι προτάσεις είναι ορατές"</string>
<string name="keyboard_layout" msgid="437433231038683666">"Θέμα πληκτρολογίου"</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_en_GB_keyboard" msgid="7945856548410373708">"Αγγλικό (ΗΒ) πληκτρολόγιο"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index b2e62b0cd..7d5d50177 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Quick fixes"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrects commonly typed mistakes"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"English (UK) Keyboard"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 02f36ff79..e40f98b3b 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Arreglos rápidos"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige errores de escritura comunes"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Teclado en inglés (Reino Unido)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 24e975baa..e1532427a 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -27,7 +27,12 @@
<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>
+ <!-- no translation found for correction_category (2236750915056607613) -->
+ <skip />
+ <!-- no translation found for ngram_category (5337109164339320257) -->
+ <skip />
+ <!-- no translation found for misc_category (6894192814868233453) -->
+ <skip />
<string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</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>
@@ -36,6 +41,8 @@
<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>
+ <!-- no translation found for prefs_use_spacebar_language_switch (8828538114550634449) -->
+ <skip />
<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 +52,12 @@
<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>
+ <!-- outdated translation 7146707435859263625 --> <string name="bigram_suggestion" msgid="2636414079905220518">"Sugerencias de bigramas"</string>
<string name="bigram_suggestion_summary" msgid="4383845146070101531">"Usar palabra anterior para mejorar sugerencias"</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>: guardada"</string>
<string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Sig."</string>
@@ -56,18 +67,6 @@
<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="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>
@@ -106,6 +105,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Teclado inglés (Reino Unido)"</string>
@@ -115,6 +115,7 @@
<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_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>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index b594411ac..25ee9dff8 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"نوشتن با حروف بزرگ خودکار"</string>
<string name="quick_fixes" msgid="5353213327680897927">"راه حل های سریع"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"تصحیح خطاهای تایپی رایج"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"فقط هنگامی که پیشنهادات قابل مشاهده هستند، برای تصحیح کلمات وارد شده آنها را لمس کنید"</string>
<string name="keyboard_layout" msgid="437433231038683666">"طرح زمینه صفحه کلید"</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_en_GB_keyboard" msgid="7945856548410373708">"صفحه کلید انگلیسی (بریتانیایی)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 0bf385552..f02e8217d 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Pikakorjaukset"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Korjaa yleiset kirjoitusvirheet"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Näppäimistö: englanti (UK)"</string>
@@ -115,6 +109,7 @@
<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_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>
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 65e88c1ff..276aed2c5 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Corrections rapides"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corrige les fautes de frappe courantes"</string>
@@ -36,6 +38,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">"Sélecteur langue barre d\'espace"</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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Clavier anglais (Royaume-Uni)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/anim/key_preview_fadein.xml b/java/res/values-hdpi/config.xml
index 9fad7b9a7..7333e9449 100644
--- a/java/res/anim/key_preview_fadein.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.
@@ -18,12 +18,7 @@
*/
-->
-<set
- 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>
+<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/strings.xml b/java/res/values-hr/strings.xml
index e6879a6d1..6117821ee 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</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>
@@ -36,6 +38,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">"Koristite 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 +48,10 @@
<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="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">"Koristite 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 +61,6 @@
<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="voice_warning_title" msgid="4419354150908395008">"Glasovni unos"</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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Engleska (UK) tipkovnica"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index a8bf98367..81255d719 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Angol (UK) billentyűzet"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index 4df7f1e7f..32ef38d35 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Perbaikan cepat"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Memperbaiki kesalahan ketik umum"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Keyboard Inggris (Britania Raya)"</string>
@@ -115,6 +109,7 @@
<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_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>
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 9bf4f9e30..3a896fcd7 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Tastiera inglese (Regno Unito)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index af0854c97..0b26ed9fe 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"הפיכה אוטומטית של אותיות לרישיות"</string>
<string name="quick_fixes" msgid="5353213327680897927">"תיקונים מהירים"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"מתקן שגיאות הקלדה נפוצות"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"גע במילים שהוזנו כדי לתקן אותן, רק כאשר הצעות מוצגות"</string>
<string name="keyboard_layout" msgid="437433231038683666">"עיצוב מקלדת"</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_en_GB_keyboard" msgid="7945856548410373708">"מקלדת אנגלית (בריטניה)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index cd2cf8070..402c35675 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string>
<string name="quick_fixes" msgid="5353213327680897927">"クイックフィックス"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"よくある誤字・脱字を修正します"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"候補が表示されているときのみ、入力した語句をタップして修正する"</string>
<string name="keyboard_layout" msgid="437433231038683666">"キーボードテーマ"</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_en_GB_keyboard" msgid="7945856548410373708">"英語(英国)のキーボード"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index 7a09da880..ca2f570a8 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string>
<string name="quick_fixes" msgid="5353213327680897927">"빠른 수정"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"자주 발생하는 오타를 수정합니다."</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"입력한 단어를 터치하여 수정(추천 단어가 표시되는 경우에만)"</string>
<string name="keyboard_layout" msgid="437433231038683666">"키보드 테마"</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_en_GB_keyboard" msgid="7945856548410373708">"영어(영국) 키보드"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index 7df124bfc..c46a51711 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -19,20 +19,21 @@
-->
<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>
<!-- key_height + key_bottom_gap = popup_key_height -->
-<!-- <dimen name="key_height">0.250in</dimen>-->
+<!-- <dimen name="key_height">0.260in</dimen>-->
<dimen name="key_bottom_gap">0.020in</dimen>
- <dimen name="popup_key_height">0.270in</dimen>
+ <dimen name="popup_key_height">0.280in</dimen>
<dimen name="keyboard_top_padding">0.0in</dimen>
<dimen name="keyboard_bottom_padding">0.0in</dimen>
+ <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen>
<dimen name="candidate_strip_height">38dip</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 c12c62aaa..fbe50e005 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Angliška (JK) klaviatūra"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 8b975b033..84bee5382 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -27,7 +27,9 @@
<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, pamatojoties uz iepriekšējiem vārdiem"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Citas opcijas"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</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>
@@ -36,6 +38,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 atstarpēšanas taustiņu, lai pārslēgtu valodu"</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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Angļu (Lielbritānija) tastatūra"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 0471e74c3..e20c9515e 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Autokorrektur"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Retter vanlige stavefeil"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Engelsk tastatur (Storbritannia)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index a1213ec33..89b714bc8 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Snelle oplossingen"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Hiermee worden veelvoorkomende typefouten gecorrigeerd"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Engels toetsenbord (VK)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 633b159c9..65240d748 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Szybkie poprawki"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Poprawia częste błędy wpisywania"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Klawiatura angielska (UK)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index f06d64c70..b972ce049 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Teclado inglês (Reino Unido)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index 9fc1a97f2..a999dc67e 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Capitaliz. automática"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Teclado para inglês (Reino Unido)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 57548b5e4..b0c1bea24 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -29,7 +29,12 @@
<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 />
<string name="auto_cap" msgid="1719746674854628252">"Maiusclas automaticas"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Correcturas sveltas"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Curregia sbagls da tippar currents"</string>
@@ -43,6 +48,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 +66,12 @@
<skip />
<!-- no translation found for auto_correction_threshold_mode_aggeressive (3524029103734923819) -->
<skip />
- <string name="bigram_suggestion" msgid="1323347224043514969">"Propostas da tip bigram"</string>
+ <!-- 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,30 +85,6 @@
<skip />
<!-- no translation found for label_wait_key (6402152600878093134) -->
<skip />
- <!-- no translation found for description_delete_key (5586406298531883960) -->
- <skip />
- <!-- no translation found for description_return_key (8750044000806461678) -->
- <skip />
- <!-- no translation found for description_settings_key (7484527796782969219) -->
- <skip />
- <!-- no translation found for description_shift_key (346906866277787836) -->
- <skip />
- <!-- no translation found for description_space_key (8512130111575878517) -->
- <skip />
- <!-- no translation found for description_switch_alpha_symbol_key (4537975384274405537) -->
- <skip />
- <!-- no translation found for description_tab_key (828186583738307137) -->
- <skip />
- <!-- no translation found for description_voice_key (3057731675774652754) -->
- <skip />
- <!-- no translation found for description_symbols_on (2994366855822840559) -->
- <skip />
- <!-- no translation found for description_symbols_off (3209578267079515136) -->
- <skip />
- <!-- no translation found for description_shift_on (6983188949895971587) -->
- <skip />
- <!-- no translation found for description_shift_off (8553265474523069034) -->
- <skip />
<string name="voice_warning_title" msgid="4419354150908395008">"Cumonds vocals"</string>
<string name="voice_warning_locale_not_supported" msgid="637923019716442333">"\"Cumonds vocals en Vossa lingua na vegnan actualmain betg sustegnids, ma la funcziun è disponibla per englais.\""</string>
<!-- outdated translation 4611518823070986445 --> <string name="voice_warning_may_not_understand" msgid="5596289095878251072">"Ils cumonds vocals èn ina funcziunalitad experimentala che utilisescha la renconuschientscha vocala da rait da Google."</string>
@@ -146,6 +133,8 @@
<string name="keyboard_layout" msgid="437433231038683666">"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) -->
@@ -164,6 +153,8 @@
<skip />
<!-- no translation found for subtype_mode_fr_CH_keyboard (6742806653181621228) -->
<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) -->
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 9c973922a..0fcefd1f2 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Remedieri rapide"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Corectează greşelile introduse frecvent"</string>
@@ -36,6 +38,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">"Sp. pt. comut. lb."</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 +48,10 @@
<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="bigram_suggestion" msgid="2636414079905220518">"Sugestii pentru cuvinte de două litere"</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">"Sugestii pentru cuvinte de două litere"</string>
+ <string name="bigram_prediction_summary" msgid="1747261921174300098">"De asemenea, utilizaţi pentru sugestii cuvântul precedent"</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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Tastatură engleză (Marea Britanie)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index f8fdab021..2e8577ea1 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Заглавные автоматически"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Быстрое исправление"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Исправлять распространенные опечатки"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Нажмите на слово, чтобы исправить его (при наличии подсказок)"</string>
<string name="keyboard_layout" msgid="437433231038683666">"Вид клавиатуры"</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_en_GB_keyboard" msgid="7945856548410373708">"Клавиатура: английская (Великобритания)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 569f273a4..eeefa820f 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"klávesnica – angličtina (br.)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 715e6c567..91f9036e6 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Samodejne velike začetnice"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Hitri popravki"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Popravi pogoste tipkarske napake"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Tipkovnica za britansko angleščino"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 115732779..b20f1df2e 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Брзе исправке"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Исправља честе грешке у куцању"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Додирните унете речи да бисте их исправили само када су предлози видљиви"</string>
<string name="keyboard_layout" msgid="437433231038683666">"Тема тастатуре"</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_en_GB_keyboard" msgid="7945856548410373708">"Језик тастатуре: енглески (УК)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index b8c62f46e..2d35fd87b 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Snabba lösningar"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Åtgärdar automatiskt vanliga misstag"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Engelskt tangentbord (Storbrit.)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index 836b98724..cd7fe95c0 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string>
<string name="quick_fixes" msgid="5353213327680897927">"แก้ไขด่วน"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"แก้ไขข้อผิดพลาดในการพิมพ์ที่พบบ่อย"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"แตะคำที่ป้อนไว้เพื่อแก้ไข เฉพาะเมื่อเห็นข้อเสนอแนะเท่านั้น"</string>
<string name="keyboard_layout" msgid="437433231038683666">"ชุดรูปแบบแป้นพิมพ์"</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_en_GB_keyboard" msgid="7945856548410373708">"แป้นพิมพ์ภาษาอังกฤษ (สหราชอาณาจักร)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 386b1fdd8..da62eafc6 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Ingles (UK) na Keyboard"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 71a6215dd..2607ae257 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</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>
@@ -36,6 +38,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 içn boşluk çubğn kullan"</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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"İngilizce (İngiltere) Klavye"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 26906329a..a2f589d1d 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string>
<string name="quick_fixes" msgid="5353213327680897927">"Шв. виправлення"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"Виправляє поширені помилки"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"Торкніться введених слів, щоб виправити їх, лише коли ввімкнено пропозиції"</string>
<string name="keyboard_layout" msgid="437433231038683666">"Тема клавіатури"</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_en_GB_keyboard" msgid="7945856548410373708">"Англ. розкладка (Великобританія)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 70defe3b7..81be8264e 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</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>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<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="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_en_GB_keyboard" msgid="7945856548410373708">"Bàn phím tiếng Anh (Anh)"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-xlarge-land/dimens.xml b/java/res/values-xlarge-land/dimens.xml
index 625dd263c..fd6b1f386 100644
--- a/java/res/values-xlarge-land/dimens.xml
+++ b/java/res/values-xlarge-land/dimens.xml
@@ -19,7 +19,7 @@
-->
<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> -->
@@ -28,12 +28,14 @@
<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="keyboard_horizontal_edges_padding">0.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_preview_height_holo">26.5mm</dimen>
+ <dimen name="key_preview_offset_holo">7.5mm</dimen>
+
<dimen name="candidate_strip_padding">40.0mm</dimen>
</resources>
diff --git a/java/res/values-xlarge/config.xml b/java/res/values-xlarge/config.xml
index f075b1b50..80ef3cd8e 100644
--- a/java/res/values-xlarge/config.xml
+++ b/java/res/values-xlarge/config.xml
@@ -22,7 +22,8 @@
<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>
+ <!-- TODO: This configuration value is temporary set true to check popup preview behavior. -->
+ <bool name="config_enable_show_popup_on_keypress_option">true</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>
@@ -36,10 +37,11 @@
<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-xlarge/dimens.xml b/java/res/values-xlarge/dimens.xml
index 69283202e..4f78bea4f 100644
--- a/java/res/values-xlarge/dimens.xml
+++ b/java/res/values-xlarge/dimens.xml
@@ -19,7 +19,7 @@
-->
<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> -->
@@ -28,8 +28,8 @@
<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="keyboard_horizontal_edges_padding">0.0mm</dimen>
+ <dimen name="mini_keyboard_horizontal_padding_holo">40dip</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 -->
@@ -39,13 +39,18 @@
<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_preview_text_size_large">24dip</dimen>
+ <dimen name="key_preview_height_holo">23.0mm</dimen>
+ <dimen name="key_preview_offset_holo">8.0mm</dimen>
<dimen name="candidate_strip_height">46dip</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-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 3b092bfcc..1f15831b3 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"自动大写"</string>
<string name="quick_fixes" msgid="5353213327680897927">"快速纠正"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"纠正常见的输入错误"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"仅在系统显示建议后,才触摸输入的字词进行更正"</string>
<string name="keyboard_layout" msgid="437433231038683666">"键盘主题"</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_en_GB_keyboard" msgid="7945856548410373708">"英语(英国)键盘"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index a3bf911a1..8a89aeb08 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -27,7 +27,9 @@
<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="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
<string name="quick_fixes" msgid="5353213327680897927">"快速修正"</string>
<string name="quick_fixes_summary" msgid="3405028402510332373">"修正一般打字錯誤"</string>
@@ -36,6 +38,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 +48,10 @@
<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="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 +61,6 @@
<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="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>
@@ -106,6 +99,7 @@
<string name="prefs_enable_recorrection_summary" msgid="5082041365862396329">"輕觸輸入的字詞即可加以修正 (出現建議時才適用)"</string>
<string name="keyboard_layout" msgid="437433231038683666">"鍵盤主題"</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_en_GB_keyboard" msgid="7945856548410373708">"英文 (英國) 鍵盤"</string>
@@ -115,6 +109,7 @@
<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_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>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index f0da2744b..e88b007a9 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -91,6 +91,8 @@
<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" />
</declare-styleable>
<declare-styleable name="Keyboard_Key">
@@ -107,8 +109,8 @@
<!-- 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. -->
@@ -142,6 +144,9 @@
<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" />
</declare-styleable>
<declare-styleable name="Keyboard_Row">
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index 0161589a4..733a464cc 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -21,11 +21,9 @@
<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_extension_background">#A0000000</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>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index bdb4409f0..1d24b1088 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -37,20 +37,26 @@
<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_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>
@@ -65,7 +71,7 @@
<!-- 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_text_size_of_language_on_spacebar" translatable="false">small</string>
- <integer name="config_max_popup_keyboard_column">10</integer>
+ <integer name="config_max_popup_keyboard_column">5</integer>
<!-- Whether or not auto-correction should be enabled by default -->
<bool name="enable_autocorrect">true</bool>
<string-array name="auto_correction_threshold_values" translatable="false">
@@ -78,4 +84,7 @@
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 7f00cdba3..69f962f00 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -19,38 +19,45 @@
-->
<resources>
- <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
- <dimen name="keyboardHeight">1.265in</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.295in -->
+ <dimen name="keyboardHeight">1.285in</dimen>
<!-- key_height + key_bottom_gap = popup_key_height -->
- <!-- <dimen name="key_height">0.290in</dimen> -->
+ <!-- <dimen name="key_height">0.295in</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="popup_key_height">0.330in</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>
+ <dimen name="keyboard_horizontal_edges_padding">0.0in</dimen>
+ <dimen name="mini_keyboard_horizontal_padding">16dip</dimen>
+ <dimen name="mini_keyboard_horizontal_padding_holo">32dip</dimen>
<dimen name="mini_keyboard_key_horizontal_padding">8dip</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="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="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_height">80sp</dimen>
<dimen name="key_preview_offset">0.000in</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="key_preview_text_size_large">36sp</dimen>
+ <dimen name="key_preview_height_holo">130sp</dimen>
+ <dimen name="key_preview_offset_holo">0.193in</dimen>
<dimen name="candidate_strip_height">42dip</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">32dip</dimen>
<dimen name="candidate_padding">6dip</dimen>
<dimen name="candidate_text_size">18dip</dimen>
<dimen name="spacebar_vertical_correction">4dip</dimen>
diff --git a/java/res/values/donottranslate-altchars.xml b/java/res/values/donottranslate-altchars.xml
index 518e74af1..e77957578 100644
--- a/java/res/values/donottranslate-altchars.xml
+++ b/java/res/values/donottranslate-altchars.xml
@@ -47,12 +47,9 @@
<string name="alternates_for_currency_dollar">¢,£,€,¥,₱</string>
<string name="alternates_for_currency_euro">¢,£,$,¥,₱</string>
<string name="alternates_for_currency_pound">¢,$,€,¥,₱</string>
- <string name="alternates_for_mic">"\@drawable/sym_keyboard_settings|\@integer/key_settings,\@drawable/sym_keyboard_mic|\@integer/key_voice"</string>
<string name="alternates_for_smiley">":-)|:-) ,:-(|:-( ,;-)|;-) ,:-P|:-P ,=-O|=-O ,:-*|:-* ,:O|:O ,B-)|B-) ,:-$|:-$ ,:-!|:-! ,:-[|:-[ ,O:-)|O:-) ,:-\\\\\\\\|:-\\\\\\\\ ,:\'(|:\'( ,:-D|:-D "</string>
- <string name="alternates_for_settings_slash">"\@drawable/sym_keyboard_settings|\@integer/key_settings,/"</string>
- <string name="alternates_for_settings_at">"\@drawable/sym_keyboard_settings|\@integer/key_settings,\@"</string>
- <string name="alternates_for_settings_comma">"\@drawable/sym_keyboard_settings|\@integer/key_settings,\\,"</string>
- <string name="alternates_for_punctuation">":,/,&amp;,(,),-,+,;,\@,\',\",\?,!,\\,"</string>
+ <string name="alternates_for_punctuation">"\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
+ <string name="alternates_for_web_tab_punctuation">".,\\,,\?,!,:,-,\',\",(,),/,;,+,&amp;,\@"</string>
<string name="keylabel_for_popular_domain">".com"</string>
<!-- popular web domains for the locale - most popular, displayed on the keyboard -->
<string name="alternates_for_popular_domain">".net,.org,.gov,.edu"</string>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 6a1069e99..1cdae3d81 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>
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
index d6f9bfc28..d5926ecfd 100644
--- a/java/res/values/keycodes.xml
+++ b/java/res/values/keycodes.xml
@@ -23,29 +23,12 @@
<integer name="key_tab">9</integer>
<integer name="key_return">10</integer>
<integer name="key_space">32</integer>
+ <integer name="key_dash">45</integer>
+ <integer name="key_single_quote">39</integer>
+ <integer name="key_double_quote">34</integer>
<integer name="key_shift">-1</integer>
<integer name="key_switch_alpha_symbol">-2</integer>
<integer name="key_delete">-5</integer>
- <integer name="key_settings">-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 3c0a9c1a2..823f1e58f 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -38,7 +38,13 @@
<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 to enable auto capitalization of sentences -->
<string name="auto_cap">Auto-capitalization</string>
@@ -55,6 +61,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>
@@ -78,9 +86,13 @@
<string name="auto_correction_threshold_mode_aggeressive">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,31 +114,6 @@
<!-- 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>
-
<!-- Voice related labels -->
<!-- Title of the warning dialog that shows when a user initiates voice input for
@@ -242,6 +229,8 @@
<!-- 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] -->
@@ -260,12 +249,17 @@
<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 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 Russian keyboard subtype [CHAR LIMIT=35] -->
<string name="subtype_mode_ru_keyboard">Russian Keyboard</string>
<!-- Description for Serbian keyboard subtype [CHAR LIMIT=35] -->
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 130714fd3..8a4b16d7a 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -35,11 +35,7 @@
<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>
- <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/xml-ar/kbd_qwerty.xml b/java/res/xml-ar/kbd_qwerty.xml
new file mode 100644
index 000000000..5faf60336
--- /dev/null
+++ b/java/res/xml-ar/kbd_qwerty.xml
@@ -0,0 +1,35 @@
+<?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: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_ar_rows" />
+</Keyboard>
diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml-cs/kbd_qwerty.xml
index 010bdb3f7..0e6e40d7c 100644
--- a/java/res/xml-cs/kbd_qwerty.xml
+++ b/java/res/xml-cs/kbd_qwerty.xml
@@ -28,6 +28,7 @@
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" />
diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-da/kbd_qwerty.xml
index 441b7cb17..d9847ae83 100644
--- a/java/res/xml-da/kbd_qwerty.xml
+++ b/java/res/xml-da/kbd_qwerty.xml
@@ -27,6 +27,7 @@
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" />
diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml
index a23e4fbf0..e6569667d 100644
--- a/java/res/xml-de/kbd_qwerty.xml
+++ b/java/res/xml-de/kbd_qwerty.xml
@@ -28,6 +28,7 @@
latin:verticalGap="@dimen/key_bottom_gap"
latin:popupKeyboardTemplate="@xml/kbd_popup_template"
latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="de_DE"
>
<include
latin:keyboardLayout="@xml/kbd_qwertz_rows" />
diff --git a/java/res/xml-fi/kbd_qwerty.xml b/java/res/xml-fi/kbd_qwerty.xml
index b0a7b3eb0..ea08d670b 100644
--- a/java/res/xml-fi/kbd_qwerty.xml
+++ b/java/res/xml-fi/kbd_qwerty.xml
@@ -27,6 +27,7 @@
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" />
diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml
index 92d92f0e6..f9c29698b 100644
--- a/java/res/xml-fr-rCA/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCA/kbd_qwerty.xml
@@ -28,6 +28,7 @@
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" />
diff --git a/java/res/xml-fr-rCH/kbd_qwerty.xml b/java/res/xml-fr-rCH/kbd_qwerty.xml
index a23e4fbf0..e47cfd9b4 100644
--- a/java/res/xml-fr-rCH/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCH/kbd_qwerty.xml
@@ -28,6 +28,7 @@
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" />
diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml-fr/kbd_qwerty.xml
index 2d0b42baf..2f8e67bb1 100644
--- a/java/res/xml-fr/kbd_qwerty.xml
+++ b/java/res/xml-fr/kbd_qwerty.xml
@@ -28,6 +28,7 @@
latin:verticalGap="@dimen/key_bottom_gap"
latin:popupKeyboardTemplate="@xml/kbd_popup_template"
latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="fr_FR"
>
<include
latin:keyboardLayout="@xml/kbd_azerty_rows" />
diff --git a/java/res/xml-hu/kbd_qwerty.xml b/java/res/xml-hu/kbd_qwerty.xml
index 010bdb3f7..db729cf02 100644
--- a/java/res/xml-hu/kbd_qwerty.xml
+++ b/java/res/xml-hu/kbd_qwerty.xml
@@ -28,6 +28,7 @@
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" />
diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml
index 98bfd7e0b..4cd565b88 100644
--- a/java/res/xml-iw/kbd_qwerty.xml
+++ b/java/res/xml-iw/kbd_qwerty.xml
@@ -1,19 +1,19 @@
<?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.
*/
-->
@@ -28,85 +28,8 @@
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:horizontalGap="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:horizontalGap="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:horizontalGap="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_iw_rows" />
</Keyboard>
diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml
index 441b7cb17..7b20ca28d 100644
--- a/java/res/xml-nb/kbd_qwerty.xml
+++ b/java/res/xml-nb/kbd_qwerty.xml
@@ -27,6 +27,7 @@
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" />
diff --git a/java/res/xml-xlarge/kbd_qwerty.xml b/java/res/xml-pl/kbd_qwerty.xml
index 1c8d51ffe..fad28d641 100644
--- a/java/res/xml-xlarge/kbd_qwerty.xml
+++ b/java/res/xml-pl/kbd_qwerty.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.
@@ -23,10 +23,12 @@
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="pl_PL"
>
<include
latin:keyboardLayout="@xml/kbd_qwerty_rows" />
diff --git a/java/res/xml-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml
index 0eb311501..e5aea581e 100644
--- a/java/res/xml-ru/kbd_qwerty.xml
+++ b/java/res/xml-ru/kbd_qwerty.xml
@@ -27,6 +27,7 @@
latin:verticalGap="@dimen/key_bottom_gap"
latin:popupKeyboardTemplate="@xml/kbd_popup_template"
latin:maxPopupKeyboardColumn="@integer/config_max_popup_keyboard_column"
+ latin:keyboardLocale="ru_RU"
>
<include
latin:keyboardLayout="@xml/kbd_ru_rows" />
diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml
index 3995e4e27..9782cd5eb 100644
--- a/java/res/xml-sr/kbd_qwerty.xml
+++ b/java/res/xml-sr/kbd_qwerty.xml
@@ -27,6 +27,7 @@
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" />
diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml
index 72bdc339e..3ff1679a2 100644
--- a/java/res/xml-sv/kbd_qwerty.xml
+++ b/java/res/xml-sv/kbd_qwerty.xml
@@ -27,6 +27,7 @@
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" />
diff --git a/java/res/xml-xlarge/kbd_ar_rows.xml b/java/res/xml-xlarge/kbd_ar_rows.xml
new file mode 100644
index 000000000..e84aae6b5
--- /dev/null
+++ b/java/res/xml-xlarge/kbd_ar_rows.xml
@@ -0,0 +1,139 @@
+<?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.49%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="7.949%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:keyWidth="9.331%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="7.49%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="7.949%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:keyWidth="8.593%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.042%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:popupCharacters="ز,ژ" />
+ <Key
+ latin:keyLabel="ظ" />
+ <Key
+ latin:keyLabel="د" />
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="11.736%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-xlarge/kbd_iw_rows.xml b/java/res/xml-xlarge/kbd_iw_rows.xml
new file mode 100644
index 000000000..a3a239dbf
--- /dev/null
+++ b/java/res/xml-xlarge/kbd_iw_rows.xml
@@ -0,0 +1,130 @@
+<?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.272%p"
+ >
+ <Key
+ latin:keyStyle="tabKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="7.949%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="ם" />
+ <Key
+ latin:keyLabel="פ" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="9.331%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.157%p"
+ >
+ <Key
+ latin:keyStyle="toSymbolKeyStyle"
+ latin:keyLabelOption="alignLeft"
+ latin:keyWidth="10.167%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:keyWidth="8.593%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <Row
+ latin:keyWidth="8.042%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="15.192%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="ץ,ץ׳" />
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="12.530%p"
+ latin:keyEdgeFlags="right" />
+ </Row>
+ <include latin:keyboardLayout="@xml/kbd_qwerty_row4" />
+</merge>
diff --git a/java/res/xml-xlarge/kbd_key_styles.xml b/java/res/xml-xlarge/kbd_key_styles.xml
index fc06d00fc..57eaccbae 100644
--- a/java/res/xml-xlarge/kbd_key_styles.xml
+++ b/java/res/xml-xlarge/kbd_key_styles.xml
@@ -28,7 +28,7 @@
>
<key-style
latin:styleName="functionalKeyStyle"
- latin:isModifier="true" />
+ latin:isFunctional="true" />
<key-style
latin:styleName="shiftKeyStyle"
latin:code="@integer/key_shift"
@@ -73,7 +73,7 @@
latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
+ latin:code="@integer/key_shortcut"
latin:keyIcon="@drawable/sym_keyboard_voice_holo"
latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
latin:parentStyle="functionalKeyStyle" />
@@ -127,7 +127,7 @@
latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
+ latin:code="@integer/key_shortcut"
latin:keyIcon="@drawable/sym_bkeyboard_mic"
latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
latin:parentStyle="functionalKeyStyle" />
diff --git a/java/res/xml-xlarge/kbd_sr_rows.xml b/java/res/xml-xlarge/kbd_sr_rows.xml
index ce9e20817..be0058505 100644
--- a/java/res/xml-xlarge/kbd_sr_rows.xml
+++ b/java/res/xml-xlarge/kbd_sr_rows.xml
@@ -30,7 +30,7 @@
<Key
latin:keyStyle="tabKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="7.949%p"
+ latin:keyWidth="8.640%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="љ"
@@ -66,7 +66,7 @@
latin:keyLabel="ш" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="9.331%p"
+ latin:keyWidth="8.640%p"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -75,7 +75,7 @@
<Key
latin:keyStyle="toSymbolKeyStyle"
latin:keyLabelOption="alignLeft"
- latin:keyWidth="7.949%p"
+ latin:keyWidth="8.640%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="а" />
@@ -101,7 +101,7 @@
latin:keyLabel="ћ" />
<Key
latin:keyStyle="returnKeyStyle"
- latin:keyWidth="9.331%p"
+ latin:keyWidth="8.640%p"
latin:keyEdgeFlags="right" />
</Row>
<Row
@@ -109,12 +109,10 @@
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="12.400%p"
+ latin:keyWidth="8.640%p"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="ђ" />
- <Key
- latin:keyLabel="ж" />
+ latin:keyLabel="ѕ" />
<Key
latin:keyLabel="џ" />
<Key
@@ -128,6 +126,10 @@
<Key
latin:keyLabel="м" />
<Key
+ latin:keyLabel="ђ" />
+ <Key
+ latin:keyLabel="ж" />
+ <Key
latin:keyLabel=","
latin:manualTemporaryUpperCaseCode="33"
latin:keyHintIcon="@drawable/key_hint_exclamation_holo"
@@ -141,7 +143,7 @@
latin:popupCharacters="\?" />
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="12.400%p"
+ latin:keyWidth="8.640%p"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml-xlarge/kbd_symbols.xml b/java/res/xml-xlarge/kbd_symbols.xml
index 1061178e0..f1deae0f9 100644
--- a/java/res/xml-xlarge/kbd_symbols.xml
+++ b/java/res/xml-xlarge/kbd_symbols.xml
@@ -211,9 +211,10 @@
latin:keyLabel="-" />
</case>
<default>
+ <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
<Key
latin:keyLabel="&quot;"
- latin:popupCharacters="“,”,«,»,˝" />
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" />
<Key
latin:keyLabel="_" />
</default>
diff --git a/java/res/xml-xlarge/kbd_symbols_shift.xml b/java/res/xml-xlarge/kbd_symbols_shift.xml
index 8359b7571..cc23358a5 100644
--- a/java/res/xml-xlarge/kbd_symbols_shift.xml
+++ b/java/res/xml-xlarge/kbd_symbols_shift.xml
@@ -99,7 +99,8 @@
latin:popupCharacters="↑,↓,←,→" />
<Key
latin:keyStyle="nonPasswordSymbolKeyStyle"
- latin:keyLabel="°" />
+ latin:keyLabel="°"
+ latin:popupCharacters="′,″" />
<Key
latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="±"
diff --git a/java/res/xml/kbd_ar_rows.xml b/java/res/xml/kbd_ar_rows.xml
new file mode 100644
index 000000000..b2ea45701
--- /dev/null
+++ b/java/res/xml/kbd_ar_rows.xml
@@ -0,0 +1,119 @@
+<?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: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: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="12%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_azerty_rows.xml
index 9eeb22ecb..ab3e1a097 100644
--- a/java/res/xml/kbd_azerty_rows.xml
+++ b/java/res/xml/kbd_azerty_rows.xml
@@ -108,6 +108,7 @@
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="w"
@@ -131,6 +132,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_iw_rows.xml b/java/res/xml/kbd_iw_rows.xml
new file mode 100644
index 000000000..fb0c2a915
--- /dev/null
+++ b/java/res/xml/kbd_iw_rows.xml
@@ -0,0 +1,106 @@
+<?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:rowEdgeFlags="top"
+ >
+ <Spacer
+ latin:horizontalGap="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:keyStyle="deleteKeyStyle"
+ latin:keyWidth="15%p"
+ latin:visualInsetsLeft="1%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:horizontalGap="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" />
+</merge>
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index 473510ec4..d4d25d4a2 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -21,14 +21,45 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- Functional key styles -->
+ <!-- Base key style for the functional key -->
<switch>
- <case
+ <case
latin:colorScheme="white"
>
<key-style
latin:styleName="functionalKeyStyle"
- latin:isModifier="true" />
+ latin:isFunctional="true" />
+ </case>
+ <case
+ latin:colorScheme="black"
+ >
+ <key-style
+ latin:styleName="functionalKeyStyle" />
+ </case>
+ </switch>
+ <!-- Base key style for the key which may have settings key as popup key -->
+ <switch>
+ <case
+ latin:hasSettingsKey="true"
+ >
+ <key-style
+ latin:styleName="settingsPopupStyle"
+ latin:parentStyle="functionalKeyStyle" />
+ </case>
+ <!-- latin:hasSettingsKey="false" -->
+ <default>
+ <key-style
+ latin:styleName="settingsPopupStyle"
+ latin:keyHintIcon="@drawable/hint_popup"
+ latin:popupCharacters="\@drawable/sym_keyboard_settings|\@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"
@@ -87,12 +118,10 @@
latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
+ latin:code="@integer/key_shortcut"
latin:keyIcon="@drawable/sym_keyboard_mic"
latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_mic"
- latin:parentStyle="functionalKeyStyle" />
+ 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
@@ -105,8 +134,6 @@
latin:colorScheme="black"
>
<key-style
- latin:styleName="functionalKeyStyle" />
- <key-style
latin:styleName="shiftKeyStyle"
latin:code="@integer/key_shift"
latin:keyIcon="@drawable/sym_bkeyboard_shift"
@@ -164,12 +191,10 @@
latin:parentStyle="functionalKeyStyle" />
<key-style
latin:styleName="micKeyStyle"
- latin:code="@integer/key_voice"
+ latin:code="@integer/key_shortcut"
latin:keyIcon="@drawable/sym_bkeyboard_mic"
latin:iconPreview="@drawable/sym_keyboard_feedback_mic"
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_mic"
- latin:parentStyle="functionalKeyStyle" />
+ 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
@@ -287,4 +312,27 @@
latin:popupCharacters="@string/alternates_for_smiley"
latin:maxPopupKeyboardColumn="5"
latin:parentStyle="functionalKeyStyle" />
+ <switch>
+ <case
+ latin:passwordInput="true"
+ >
+ <key-style
+ latin:styleName="nonPasswordSymbolKeyStyle"
+ latin:enabled="false" />
+ <key-style
+ latin:styleName="nonPasswordFunctionalKeyStyle"
+ latin:enabled="false"
+ latin:parentStyle="functionalKeyStyle" />
+ </case>
+ <!-- latin:passwordInput="false" -->
+ <default>
+ <key-style
+ latin:styleName="nonPasswordSymbolKeyStyle"
+ latin:enabled="true" />
+ <key-style
+ latin:styleName="nonPasswordFunctionalKeyStyle"
+ latin:enabled="true"
+ latin:parentStyle="functionalKeyStyle" />
+ </default>
+ </switch>
</merge> \ No newline at end of file
diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml
index 92d92f0e6..a4251c0bd 100644
--- a/java/res/xml/kbd_qwerty.xml
+++ b/java/res/xml/kbd_qwerty.xml
@@ -28,6 +28,7 @@
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" />
diff --git a/java/res/xml/kbd_qwerty_black_symbol.xml b/java/res/xml/kbd_qwerty_black_symbol.xml
deleted file mode 100644
index 6e45c12bf..000000000
--- a/java/res/xml/kbd_qwerty_black_symbol.xml
+++ /dev/null
@@ -1,84 +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:hasSettingsKey="false"
- >
- <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
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_bkeyboard_123_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_123_mic"
- latin:keyWidth="20%p"
- latin:isModifier="true"
- latin:keyEdgeFlags="left" />
- </case>
- <default>
- <Key
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyLabel="@string/label_to_symbol_key"
- latin:keyWidth="20%p"
- latin:isModifier="true"
- latin:keyEdgeFlags="left" />
- </default>
- </switch>
- </case>
- <case
- latin:hasSettingsKey="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
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyIcon="@drawable/sym_bkeyboard_123_mic"
- latin:iconPreview="@drawable/sym_keyboard_feedback_123_mic"
- latin:keyWidth="15%p"
- latin:isModifier="true"
- latin:keyEdgeFlags="left" />
- </case>
- <default>
- <Key
- latin:code="@integer/key_switch_alpha_symbol"
- latin:keyLabel="@string/label_to_symbol_key"
- latin:keyWidth="15%p"
- latin:isModifier="true"
- latin:keyEdgeFlags="left" />
- </default>
- </switch>
- </case>
- </switch>
-</merge>
diff --git a/java/res/xml/kbd_qwerty_f1.xml b/java/res/xml/kbd_qwerty_f1.xml
index cbdb8c09a..d0e2884e1 100644
--- a/java/res/xml/kbd_qwerty_f1.xml
+++ b/java/res/xml/kbd_qwerty_f1.xml
@@ -27,18 +27,14 @@
>
<Key
latin:keyLabel="/"
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_settings_slash"
- latin:isModifier="true" />
+ latin:keyStyle="settingsPopupStyle" />
</case>
<case
latin:mode="email"
>
<Key
latin:keyLabel="\@"
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_settings_at"
- latin:isModifier="true" />
+ latin:keyStyle="settingsPopupStyle" />
</case>
<default>
<switch>
@@ -48,15 +44,19 @@
<Key
latin:keyStyle="micKeyStyle" />
</case>
+ <!-- latin:hasVoiceKey="false" -->
<case
- latin:hasVoiceKey="false"
+ latin:mode="web"
>
<Key
- latin:keyLabel=","
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_settings_comma"
- latin:isModifier="true" />
+ latin:keyLabel="."
+ latin:keyStyle="settingsPopupStyle" />
</case>
+ <default>
+ <Key
+ latin:keyLabel=","
+ latin:keyStyle="settingsPopupStyle" />
+ </default>
</switch>
</default>
</switch>
diff --git a/java/res/xml/kbd_qwerty_row3.xml b/java/res/xml/kbd_qwerty_row3.xml
index 26608fd71..3d106e615 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"
@@ -49,6 +50,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="15%p"
+ 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 0db011672..82f5a4a92 100644
--- a/java/res/xml/kbd_qwerty_row4.xml
+++ b/java/res/xml/kbd_qwerty_row4.xml
@@ -35,29 +35,28 @@
latin:keyEdgeFlags="left" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f1" />
+ <Key
+ latin:keyStyle="spaceKeyStyle"
+ latin:keyWidth="40%p" />
<switch>
<case
latin:mode="web"
>
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="20%p" />
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="20%p" />
+ <Key
+ latin:keyHintIcon="@drawable/hint_popup"
+ latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+ latin:maxPopupKeyboardColumn="8"
+ latin:keyStyle="tabKeyStyle" />
</case>
<default>
<Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="40%p" />
+ latin:keyLabel="."
+ latin:keyHintIcon="@drawable/hint_popup"
+ latin:popupCharacters="@string/alternates_for_punctuation"
+ latin:maxPopupKeyboardColumn="7"
+ latin:keyStyle="functionalKeyStyle" />
</default>
</switch>
- <Key
- latin:keyLabel="."
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_punctuation"
- latin:maxPopupKeyboardColumn="7"
- latin:keyStyle="functionalKeyStyle" />
<switch>
<case
latin:mode="im"
@@ -86,28 +85,28 @@
latin:keyStyle="settingsKeyStyle" />
<include
latin:keyboardLayout="@xml/kbd_qwerty_f1" />
+ <Key
+ latin:keyStyle="spaceKeyStyle"
+ latin:keyWidth="30%p" />
<switch>
<case
latin:mode="web"
>
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p" />
- <Key
+ <Key
+ latin:keyHintIcon="@drawable/hint_popup"
+ latin:popupCharacters="@string/alternates_for_web_tab_punctuation"
+ latin:maxPopupKeyboardColumn="8"
latin:keyStyle="tabKeyStyle" />
</case>
<default>
<Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="30%p" />
+ latin:keyLabel="."
+ latin:keyHintIcon="@drawable/hint_popup"
+ latin:popupCharacters="@string/alternates_for_punctuation"
+ latin:maxPopupKeyboardColumn="7"
+ latin:keyStyle="functionalKeyStyle" />
</default>
</switch>
- <Key
- latin:keyLabel="."
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_punctuation"
- latin:maxPopupKeyboardColumn="7"
- latin:keyStyle="functionalKeyStyle" />
<switch>
<case
latin:mode="im"
@@ -117,14 +116,6 @@
latin:keyWidth="25%p"
latin:keyEdgeFlags="right" />
</case>
- <case
- latin:mode="web"
- >
- <Key
- latin:keyStyle="returnKeyStyle"
- latin:keyWidth="15%p"
- latin:keyEdgeFlags="right" />
- </case>
<default>
<Key
latin:keyStyle="returnKeyStyle"
diff --git a/java/res/xml/kbd_qwertz_rows.xml b/java/res/xml/kbd_qwertz_rows.xml
index 375f12335..bb41f067a 100644
--- a/java/res/xml/kbd_qwertz_rows.xml
+++ b/java/res/xml/kbd_qwertz_rows.xml
@@ -78,6 +78,7 @@
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="y"
@@ -100,6 +101,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsLeft="1%p"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_sr_rows.xml b/java/res/xml/kbd_sr_rows.xml
index 4a5ed1195..8d6b070b2 100644
--- a/java/res/xml/kbd_sr_rows.xml
+++ b/java/res/xml/kbd_sr_rows.xml
@@ -73,7 +73,7 @@
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="8.333%p"
+ latin:keyWidth="9.09%p"
>
<Key
latin:keyLabel="а"
@@ -97,20 +97,17 @@
<Key
latin:keyLabel="ч" />
<Key
- latin:keyLabel="ћ" />
- <Key
- latin:keyLabel="ђ"
+ latin:keyLabel="ћ"
latin:keyEdgeFlags="right" />
</Row>
<Row
- latin:keyWidth="8.5%p"
+ latin:keyWidth="8.90%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="11.75%p"
latin:keyEdgeFlags="left" />
<Key
- latin:keyLabel="ж" />
+ latin:keyLabel="ѕ" />
<Key
latin:keyLabel="џ" />
<Key
@@ -124,8 +121,12 @@
<Key
latin:keyLabel="м" />
<Key
+ latin:keyLabel="ђ" />
+ <Key
+ latin:keyLabel="ж" />
+ <Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="11.75%p"
+ latin:keyWidth="11.00%p"
latin:keyEdgeFlags="right" />
</Row>
<include
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index b3b3f4ebd..9748bce8b 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -100,16 +100,19 @@
<Key
latin:keyStyle="altKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="!"
latin:popupCharacters="¡" />
+ <!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
<Key
latin:keyLabel="&quot;"
- latin:popupCharacters="“,”,«,»,˝" />
+ latin:popupCharacters="“,”,„,‟,«,»"
+ latin:maxPopupKeyboardColumn="6" />
<Key
latin:keyLabel="\'"
- latin:popupCharacters="‘,’" />
+ latin:popupCharacters="‘,’,‚,‛,´" />
<Key
latin:keyLabel=":" />
<Key
@@ -122,6 +125,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="15%p"
+ 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 8487b6158..0fb7136b9 100644
--- a/java/res/xml/kbd_symbols_f1.xml
+++ b/java/res/xml/kbd_symbols_f1.xml
@@ -28,14 +28,11 @@
<Key
latin:keyStyle="micKeyStyle" />
</case>
- <case
- latin:hasVoiceKey="false"
- >
+ <!-- latin:hasVoiceKey="false" -->
+ <default>
<Key
latin:keyLabel=","
- latin:keyHintIcon="@drawable/hint_popup"
- latin:popupCharacters="@string/alternates_for_settings_comma"
- latin:keyStyle="functionalKeyStyle" />
- </case>
+ latin:keyStyle="settingsPopupStyle" />
+ </default>
</switch>
</merge>
diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml
index 368ee805b..3978f1776 100644
--- a/java/res/xml/kbd_symbols_shift.xml
+++ b/java/res/xml/kbd_symbols_shift.xml
@@ -42,16 +42,21 @@
<Key
latin:keyLabel="|" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="•"
latin:popupCharacters="♪,♥,♠,♦,♣" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="√" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="π"
latin:popupCharacters="Π" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="÷" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="×" />
<Key
latin:keyLabel="{" />
@@ -64,13 +69,18 @@
latin:keyStyle="nonSpecialBackgroundTabKeyStyle"
latin:keyEdgeFlags="left" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="£" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="¢" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="€" />
<Key
- latin:keyLabel="°" />
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
+ latin:keyLabel="°"
+ latin:popupCharacters="′,″" />
<Key
latin:keyLabel="^"
latin:popupCharacters="↑,↓,←,→" />
@@ -89,14 +99,19 @@
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="15%p"
+ latin:visualInsetsRight="1%p"
latin:keyEdgeFlags="left" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="™" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="®" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="©" />
<Key
+ latin:keyStyle="nonPasswordSymbolKeyStyle"
latin:keyLabel="¶"
latin:popupCharacters="§" />
<Key
@@ -110,6 +125,7 @@
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="15%p"
+ 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 9159bab24..4f8567d58 100644
--- a/java/res/xml/kbd_symbols_shift_row4.xml
+++ b/java/res/xml/kbd_symbols_shift_row4.xml
@@ -34,13 +34,14 @@
latin:keyEdgeFlags="left" />
<Key
latin:keyLabel="„"
- latin:keyStyle="functionalKeyStyle" />
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="40%p" />
<Key
latin:keyLabel="…"
- latin:keyStyle="functionalKeyStyle" />
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<switch>
<case
latin:mode="im"
@@ -69,13 +70,14 @@
latin:keyStyle="settingsKeyStyle" />
<Key
latin:keyLabel="„"
- latin:keyStyle="functionalKeyStyle" />
+ latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<Key
latin:keyStyle="spaceKeyStyle"
latin:keyWidth="30%p" />
<Key
latin:keyLabel="…"
- latin:keyStyle="functionalKeyStyle" />
+ latin:keyStyle="nonPasswordFunctionalKeyStyle" />
<switch>
<case
latin:mode="im"
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 8dec7abec..df43701d3 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -24,6 +24,7 @@
<!-- 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"
@@ -34,28 +35,34 @@
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"
- />
+<!-- <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"
/>
+ <!-- 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 +72,35 @@
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_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_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"
@@ -110,12 +116,19 @@
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 +139,16 @@
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_ru_keyboard"
@@ -147,64 +165,64 @@
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"
- 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"
- />
+<!-- <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..24a1d45a5 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -14,86 +14,66 @@
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">
<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"
- />
-
+ 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="subtype_settings"
+ android:title="@string/language_selection_title"
+ android:summary="@string/language_selection_summary" />
</PreferenceCategory>
-
<PreferenceCategory
- android:title="@string/prediction_category"
- android:key="prediction_settings">
-
+ android:title="@string/correction_category"
+ android:key="correction_settings">
<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 +81,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 +89,53 @@
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>
+ <!-- <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/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/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java
new file mode 100644
index 000000000..0b532f7f0
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/CompatUtils.java
@@ -0,0 +1,160 @@
+/*
+ * 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.InvocationTargetException;
+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
+ return null;
+ } catch (NoSuchMethodException e) {
+ // ignore
+ return null;
+ }
+ }
+
+ public static Field getField(Class<?> targetClass, String name) {
+ try {
+ return targetClass.getField(name);
+ } catch (SecurityException e) {
+ // ignore
+ return null;
+ } 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
+ return null;
+ } catch (NoSuchMethodException e) {
+ // ignore
+ return null;
+ }
+ }
+
+ public static Object invoke(
+ Object receiver, Object defaultValue, Method method, Object... args) {
+ if (receiver == null || method == null) return defaultValue;
+ try {
+ return method.invoke(receiver, args);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Exception in invoke: IllegalArgumentException");
+ return defaultValue;
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Exception in invoke: IllegalAccessException");
+ return defaultValue;
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "Exception in invoke: IllegalTargetException");
+ return defaultValue;
+ }
+ }
+
+ public static Object getFieldValue(Object receiver, Object defaultValue, Field field) {
+ if (receiver == null || field == null) return defaultValue;
+ try {
+ return field.get(receiver);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Exception in getFieldValue: IllegalArgumentException");
+ return defaultValue;
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Exception in getFieldValue: IllegalAccessException");
+ return defaultValue;
+ }
+ }
+
+ public static void setFieldValue(Object receiver, Field field, Object value) {
+ if (receiver == null || field == null) return;
+ try {
+ field.set(receiver, value);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Exception in setFieldValue: IllegalArgumentException");
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Exception in setFieldValue: IllegalAccessException");
+ }
+ }
+
+ 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..f6f4f7a59
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
@@ -0,0 +1,99 @@
+/*
+ * 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_FLAG_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_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/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
new file mode 100644
index 000000000..c926be06f
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
@@ -0,0 +1,91 @@
+/*
+ * 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.util.Log;
+import android.view.inputmethod.InputConnection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class InputConnectionCompatUtils {
+ private static final String TAG = InputConnectionCompatUtils.class.getSimpleName();
+ 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 };
+ try {
+ Object correctionInfo = CONSTRUCTOR_CorrectionInfo.newInstance(args);
+ CompatUtils.invoke(ic, null, METHOD_InputConnection_commitCorrection,
+ correctionInfo);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error in commitCorrection: IllegalArgumentException");
+ } catch (InstantiationException e) {
+ Log.e(TAG, "Error in commitCorrection: InstantiationException");
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Error in commitCorrection: IllegalAccessException");
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "Error in commitCorrection: InvocationTargetException");
+ }
+ }
+
+
+ /**
+ * 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..828aea41f
--- /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 com.android.inputmethod.deprecated.LanguageSwitcherProxy;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+
+import android.inputmethodservice.InputMethodService;
+import android.view.inputmethod.InputMethodSubtype;
+
+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..806c355a9
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java
@@ -0,0 +1,155 @@
+/*
+ * 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 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 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..d85174188
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java
@@ -0,0 +1,95 @@
+/*
+ * 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 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;
+ 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 isWebPasswordInputType(int inputType) {
+ return WEB_TEXT_PASSWORD_INPUT_TYPE != 0
+ && inputType == WEB_TEXT_PASSWORD_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);
+ }
+
+ // 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/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..e14a49c49
--- /dev/null
+++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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 105656fe0..753dceead 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);
@@ -133,7 +145,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
}
}
- private VoiceIMEConnector() {
+ private VoiceProxy() {
// Intentional empty constructor for singleton.
}
@@ -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(),
@@ -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/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
index 5587c685f..a1b49b475 100644
--- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2008-2009 Google Inc.
- *
+ *
* 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
@@ -14,11 +14,20 @@
* the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.deprecated.languageswitcher;
+
+import com.android.inputmethod.keyboard.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.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
@@ -26,20 +35,21 @@ 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;
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 HashMap<CheckBoxPreference, Locale> mLocaleMap =
+ new HashMap<CheckBoxPreference, Locale>();
private static class Loc implements Comparable<Object> {
private static Collator sCollator = Collator.getInstance();
@@ -75,17 +85,27 @@ public class InputLanguageSelection extends PreferenceActivity {
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, "");
String[] languageList = mSelectedLanguages.split(",");
- mAvailableLanguages = getUniqueLocales();
+ ArrayList<Loc> availableLanguages = getUniqueLocales();
PreferenceGroup parent = getPreferenceScreen();
- for (int i = 0; i < mAvailableLanguages.size(); i++) {
+ for (int i = 0; i < availableLanguages.size(); i++) {
+ Locale locale = availableLanguages.get(i).mLocale;
+ final Pair<Boolean, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale);
+ final boolean hasDictionary = hasDictionaryOrLayout.first;
+ final boolean hasLayout = hasDictionaryOrLayout.second;
+ // Add this locale to the supported list if:
+ // 1) this locale has a layout/ 2) this locale has a dictionary and the length
+ // of the locale is equal to or larger than 5.
+ if (!hasLayout && !(hasDictionary && locale.toString().length() >= 5)) {
+ continue;
+ }
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)) {
+ if (hasDictionary) {
pref.setSummary(R.string.has_dictionary);
}
+ mLocaleMap.put(pref, locale);
parent.addPreference(pref);
}
}
@@ -98,26 +118,30 @@ public class InputLanguageSelection extends PreferenceActivity {
return false;
}
- private boolean hasDictionary(Locale locale) {
+ private Pair<Boolean, Boolean> hasDictionaryOrLayout(Locale locale) {
+ if (locale == null) return new Pair<Boolean, Boolean>(false, false);
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;
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+ final boolean hasDictionary = DictionaryFactory.isDictionaryAvailable(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) {
}
- bd.close();
- conf.locale = saveLocale;
- res.updateConfiguration(conf, res.getDisplayMetrics());
- return haveDictionary;
+ Utils.setSystemLocale(res, saveLocale);
+ return new Pair<Boolean, Boolean>(hasDictionary, hasLayout);
}
private String get5Code(Locale locale) {
@@ -141,8 +165,7 @@ public class InputLanguageSelection extends PreferenceActivity {
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) + ",";
+ checkedLanguages += get5Code(mLocaleMap.get(pref)) + ",";
}
}
if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null
@@ -162,36 +185,42 @@ public class InputLanguageSelection extends PreferenceActivity {
for (int i = 0 ; i < origSize; i++ ) {
String s = locales[i];
int len = s.length();
+ String language = "";
+ String country = "";
if (len == 5) {
- String language = s.substring(0, 2);
- String country = s.substring(3, 5);
- Locale l = new Locale(language, country);
+ 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 (arrayContains(BLACKLIST_LANGUAGES, language)) continue;
+ // Exclude languages that are not relevant to LatinIME
+ if (TextUtils.isEmpty(language)) {
+ continue;
+ }
- if (finalSize == 0) {
+ 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, true), l);
+ new Loc(SubtypeSwitcher.getFullDisplayName(l, false), 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);
+ String displayName;
+ if (s.equals("zz_ZZ")) {
+ // ignore this locale
} else {
- String displayName;
- if (s.equals("zz_ZZ")) {
- // ignore this locale
- } else {
- displayName = SubtypeSwitcher.getFullDisplayName(l, true);
- preprocess[finalSize++] = new Loc(displayName, l);
- }
+ displayName = SubtypeSwitcher.getFullDisplayName(l, true);
+ preprocess[finalSize++] = new Loc(displayName, l);
}
}
}
@@ -201,11 +230,4 @@ public class InputLanguageSelection extends PreferenceActivity {
}
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/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
index 6faf7f95e..5ef236e31 100644
--- a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
@@ -14,11 +14,18 @@
* 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 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 +35,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 +58,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 +113,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() +
@@ -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/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
index dfdfbaa9f..0ef73d2d7 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 d11d3b042..52a4f4e58 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 95a79f463..b57c16f40 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 4d746e120..7721fe268 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 543290b32..8cc79de1e 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 2df9e8588..7ee0de9c9 100644
--- a/java/src/com/android/inputmethod/voice/VoiceInput.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
@@ -14,7 +14,7 @@
* 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;
diff --git a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
index 3e65434a2..87b943426 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 8bac669fc..a3025f252 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 f4c24de0c..310689cb2 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 24e8926c5..5c59d4441 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -61,8 +61,11 @@ public class Key {
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 +86,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;
@@ -93,8 +96,8 @@ public class Key {
/** The current pressed state of this key */
public boolean mPressed;
- /** If this is a sticky key, is it on? */
- public boolean mOn;
+ /** If this is a sticky key, is its highlight on? */
+ public boolean mHighlightOn;
/** Key is enabled and responds on press */
public boolean mEnabled = true;
@@ -144,13 +147,14 @@ public class Key {
mKeyboard = keyboard;
mHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
mGap = keyboard.getHorizontalGap();
+ mVisualInsetsLeft = mVisualInsetsRight = 0;
mWidth = width - mGap;
mEdgeFlags = edgeFlags;
mHintIcon = null;
mManualTemporaryUpperCaseHintIcon = null;
mManualTemporaryUpperCaseCode = Keyboard.CODE_DUMMY;
mLabelOption = 0;
- mModifier = false;
+ mFunctional = false;
mSticky = false;
mRepeatable = false;
mPopupCharacters = null;
@@ -224,12 +228,16 @@ 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;
+ mVisualInsetsLeft = KeyboardParser.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_visualInsetsLeft, mKeyboard.getDisplayHeight(), 0);
+ mVisualInsetsRight = KeyboardParser.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_visualInsetsRight, mKeyboard.getDisplayHeight(), 0);
mPreviewIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_iconPreview);
Keyboard.setDefaultBounds(mPreviewIcon);
mIcon = style.getDrawable(keyAttr, R.styleable.Keyboard_Key_keyIcon);
@@ -315,26 +323,19 @@ 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 boolean isInside(int x, int y) {
- return mKeyboard.isInside(this, x, y);
+ public void onReleased() {
+ mPressed = false;
}
/**
@@ -377,20 +378,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 {
@@ -400,7 +395,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 a7ede5f26..0b13afecb 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -16,36 +16,35 @@
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;
-
- private Key[] mKeys;
+public class KeyDetector {
+ private static final String TAG = KeyDetector.class.getSimpleName();
+ private static final boolean DEBUG = false;
- protected int mCorrectionX;
-
- protected int mCorrectionY;
+ public static final int NOT_A_CODE = -1;
+ public static final int NOT_A_KEY = -1;
- protected boolean mProximityCorrectOn;
+ private Keyboard mKeyboard;
+ private int mCorrectionX;
+ private int mCorrectionY;
+ private boolean mProximityCorrectOn;
+ private int mProximityThresholdSquare;
- protected int mProximityThresholdSquare;
+ // 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];
- 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;
}
protected int getTouchX(int x) {
@@ -56,11 +55,11 @@ public abstract class KeyDetector {
return y + mCorrectionY;
}
- protected Key[] getKeys() {
- if (mKeys == null)
+ protected List<Key> getKeys() {
+ 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.getKeys();
}
public void setProximityCorrectionEnabled(boolean enabled) {
@@ -76,6 +75,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 +99,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 = 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 +169,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 = 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/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/KeyStyles.java
index 169f2e6c3..d464c2029 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyStyles.java
@@ -185,7 +185,7 @@ public class KeyStyles {
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);
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 06d44680d..492883caf 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -63,24 +63,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,6 +126,8 @@ public class Keyboard {
/** Height of keyboard */
private int mKeyboardHeight;
+ private int mMostCommonKeyWidth = 0;
+
public final KeyboardId mId;
// Variables for pre-computing nearest keys.
@@ -165,7 +165,9 @@ public class Keyboard {
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
- mDisplayWidth = width;
+ final int horizontalEdgesPadding = (int)res.getDimension(
+ R.dimen.keyboard_horizontal_edges_padding);
+ mDisplayWidth = width - horizontalEdgesPadding * 2;
mDisplayHeight = height;
mDefaultHorizontalGap = 0;
@@ -293,7 +295,7 @@ public class Keyboard {
public boolean setShiftLocked(boolean newShiftLockState) {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
- key.mOn = newShiftLockState;
+ key.mHighlightOn = newShiftLockState;
key.setIcon(newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key));
}
mShiftState.setShiftLocked(newShiftLockState);
@@ -381,10 +383,6 @@ public class Keyboard {
mProximityInfo.setProximityInfo(mGridNeighbors, getMinWidth(), getHeight(), mKeys);
}
- public boolean isInside(Key key, int x, int y) {
- return key.isOnKey(x, y);
- }
-
/**
* Returns the indices of the keys that are closest to the given point.
* @param x the x-coordinate of the point
@@ -403,6 +401,41 @@ public class Keyboard {
return EMPTY_INT_ARRAY;
}
+ /**
+ * 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 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());
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index d09f6786e..f68b68f1d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -16,8 +16,9 @@
package com.android.inputmethod.keyboard;
+import com.android.inputmethod.compat.EditorInfoCompatUtils;
+import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Utils;
import android.view.inputmethod.EditorInfo;
@@ -62,8 +63,8 @@ public class KeyboardId {
this.mMode = mode;
this.mXmlId = xmlId;
this.mColorScheme = colorScheme;
- this.mPasswordInput = Utils.isPasswordInputType(inputType)
- || Utils.isVisiblePasswordInputType(inputType);
+ this.mPasswordInput = InputTypeCompatUtils.isPasswordInputType(inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(inputType);
this.mHasSettingsKey = hasSettingsKey;
this.mVoiceKeyEnabled = voiceKeyEnabled;
this.mHasVoiceKey = hasVoiceKey;
@@ -140,7 +141,7 @@ public class KeyboardId {
mLocale,
(mOrientation == 1 ? "port" : "land"),
modeName(mMode),
- imeOptionsName(mImeAction),
+ EditorInfoCompatUtils.imeOptionsName(mImeAction),
(mPasswordInput ? " passwordInput" : ""),
(mHasSettingsKey ? " hasSettingsKey" : ""),
(mVoiceKeyEnabled ? " voiceKeyEnabled" : ""),
@@ -170,26 +171,4 @@ public class KeyboardId {
}
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_PREVIOUS: action = "actionPrevious"; break;
- default: action = "actionUnknown(" + actionNo + ")"; break;
- }
- if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
- return "flagNoEnterAction|" + action;
- } else {
- return action;
- }
- }
}
-
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index feb56ab3a..69ae7886a 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -16,11 +16,13 @@
package com.android.inputmethod.keyboard;
+import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.latin.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
@@ -121,6 +123,7 @@ public class KeyboardParser {
private final Keyboard mKeyboard;
private final Resources mResources;
+ private int mHorizontalEdgesPadding;
private int mCurrentX = 0;
private int mCurrentY = 0;
private int mMaxRowWidth = 0;
@@ -131,6 +134,7 @@ public class KeyboardParser {
public KeyboardParser(Keyboard keyboard, Resources res) {
mKeyboard = keyboard;
mResources = res;
+ mHorizontalEdgesPadding = (int)res.getDimension(R.dimen.keyboard_horizontal_edges_padding);
}
public int getMaxRowWidth() {
@@ -150,6 +154,7 @@ public class KeyboardParser {
final String tag = parser.getName();
if (TAG_KEYBOARD.equals(tag)) {
parseKeyboardAttributes(parser);
+ startKeyboard();
parseKeyboardContent(parser, mKeyboard.getKeys());
break;
} else {
@@ -159,6 +164,27 @@ 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),
@@ -453,7 +479,7 @@ public class KeyboardParser {
booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"),
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_languageCode), "languageCode"),
textAttr(a.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"),
@@ -519,25 +545,32 @@ public class KeyboardParser {
throw new NonEmptyTag(tag, parser);
}
+ private void startKeyboard() {
+ mCurrentY += (int)mResources.getDimension(R.dimen.keyboard_top_padding);
+ }
+
private void startRow(Row row) {
mCurrentX = 0;
+ setSpacer(mHorizontalEdgesPadding);
mCurrentRow = row;
}
private void endRow() {
if (mCurrentRow == null)
throw new InflateException("orphant end row tag");
+ setSpacer(mHorizontalEdgesPadding);
+ if (mCurrentX > mMaxRowWidth)
+ mMaxRowWidth = mCurrentX;
mCurrentY += mCurrentRow.mDefaultHeight;
mCurrentRow = null;
}
private void endKey(Key key) {
mCurrentX += key.mGap + key.mWidth;
- if (mCurrentX > mMaxRowWidth)
- mMaxRowWidth = mCurrentX;
}
private void endKeyboard(int defaultVerticalGap) {
+ mCurrentY += (int)mResources.getDimension(R.dimen.keyboard_bottom_padding);
mTotalHeight = mCurrentY - defaultVerticalGap;
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 64a23ab92..333fbc779 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.keyboard;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
@@ -29,7 +30,6 @@ import android.content.res.Resources;
import android.util.Log;
import android.view.InflateException;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
import java.lang.ref.SoftReference;
import java.util.HashMap;
@@ -57,6 +57,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private LatinKeyboardView mInputView;
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 +76,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;
@@ -124,7 +129,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
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);
} catch (RuntimeException e) {
@@ -146,14 +151,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// Update the settings key state because number of enabled IMEs could have been changed
mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService);
final KeyboardId id = getKeyboardId(attribute, isSymbols);
-
- final Keyboard oldKeyboard = mInputView.getKeyboard();
- if (oldKeyboard != null && oldKeyboard.mId.equals(id))
- return;
-
makeSymbolsKeyboardIds(id.mMode, attribute);
mCurrentId = id;
- mInputView.setPreviewEnabled(mInputMethodService.getPopupOn());
+ mInputView.setKeyPreviewEnabled(mInputMethodService.getPopupOn());
setKeyboard(getKeyboard(id));
}
@@ -169,7 +169,8 @@ 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);
@@ -183,7 +184,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
- mSubtypeSwitcher.changeSystemLocale(savedLocale);
+ Utils.setSystemLocale(res, savedLocale);
} else if (DEBUG) {
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
}
@@ -195,6 +196,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;
}
@@ -263,10 +265,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
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, mVoiceKeyEnabled, hasVoiceKey, true);
+ attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, false);
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, mVoiceKeyEnabled, hasVoiceKey, true);
+ attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, false);
}
public int getKeyboardMode() {
@@ -296,12 +298,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
return null;
}
- public void keyReleased() {
- LatinKeyboard latinKeyboard = getLatinKeyboard();
- if (latinKeyboard != null)
- latinKeyboard.keyReleased();
- }
-
public boolean isShiftedOrShiftLocked() {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null)
@@ -344,8 +340,7 @@ 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)) {
@@ -443,9 +438,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:"
@@ -475,15 +467,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:"
@@ -496,6 +486,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
} else if (isShiftLocked() && !shiftKeyState.isIgnoring() && !withSliding) {
// Shift has been pressed without chording while caps lock state.
toggleCapsLock();
+ // To be able to turn off caps lock by "double tap" on shift key, we should ignore
+ // the second tap of the "double tap" from now for a while because we just have
+ // already turned off caps lock above.
+ mInputView.startIgnoringDoubleTap();
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()
&& !withSliding) {
// Shift has been pressed without chording while shifted state.
@@ -506,42 +500,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()
@@ -553,8 +545,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() {
@@ -565,22 +562,21 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mCurrentId = mSymbolsShiftedId;
keyboard = getKeyboard(mCurrentId);
// 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);
// 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() {
@@ -594,42 +590,62 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
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();
}
+ 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
@@ -640,18 +656,38 @@ 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 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 AUTO_MODE_SWITCH_STATE_SYMBOL:
+ 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;
@@ -752,8 +788,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
if (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))
|| (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_AUTO))
&& Utils.hasMultipleEnabledIMEsOrSubtypes(
- ((InputMethodManager) context.getSystemService(
- Context.INPUT_METHOD_SERVICE))))) {
+ (InputMethodManagerCompatWrapper.getInstance(context))))) {
return true;
}
return false;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 61af15b1d..c551ed49f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -36,24 +35,23 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
-import android.os.SystemClock;
-import android.provider.Settings;
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.ViewGroup.LayoutParams;
-import android.view.WindowManager;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.WeakHashMap;
/**
@@ -74,7 +72,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private static final boolean DEBUG_SHOW_ALIGN = false;
private static final boolean DEBUG_KEYBOARD_GRID = false;
- private static final boolean ENABLE_CAPSLOCK_BY_LONGPRESS = 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;
@@ -106,35 +104,23 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// Main keyboard
private Keyboard mKeyboard;
- private Key[] mKeys;
- // Key preview popup
+ // Key preview
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 boolean mShowKeyPreview = true;
+ private int mKeyPreviewDisplayedY;
private final int mDelayBeforePreview;
private final int mDelayAfterPreview;
+ private ViewGroup mPreviewPlacer;
+ private final int[] mCoordinates = new int[2];
- // 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;
+ // Mini keyboard
+ private PopupWindow mPopupWindow;
+ private PopupPanel mPopupMiniKeyboardPanel;
+ private final WeakHashMap<Key, PopupPanel> mPopupPanelCache =
+ new WeakHashMap<Key, PopupPanel>();
/** Listener for {@link KeyboardActionListener}. */
private KeyboardActionListener mKeyboardActionListener;
@@ -146,14 +132,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private final boolean mHasDistinctMultitouch;
private int mOldPointerCount = 1;
+ private int mOldKeyIndex;
- // Accessibility
- private boolean mIsAccessibilityEnabled;
-
- protected KeyDetector mKeyDetector = new ProximityKeyDetector();
+ protected KeyDetector mKeyDetector = new KeyDetector();
// Swipe gesture detector
- private GestureDetector mGestureDetector;
+ protected GestureDetector mGestureDetector;
private final SwipeTracker mSwipeTracker = new SwipeTracker();
private final int mSwipeThreshold;
private final boolean mDisambiguateSwipe;
@@ -190,65 +174,67 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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_SHOW_KEY_PREVIEW = 1;
+ private static final int MSG_DISMISS_KEY_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;
@Override
public void handleMessage(Message msg) {
+ 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:
+ showKey(msg.arg1, tracker);
+ break;
+ case MSG_DISMISS_KEY_PREVIEW:
+ mPreviewText.setVisibility(View.INVISIBLE);
+ break;
+ case MSG_REPEAT_KEY:
+ tracker.onRepeatKey(msg.arg1);
+ startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker);
+ break;
+ case MSG_LONGPRESS_KEY:
+ openMiniKeyboardIfRequired(msg.arg1, tracker);
+ break;
+ case MSG_LONGPRESS_SHIFT_KEY:
+ onLongPressShiftKey(tracker);
+ 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) {
+ removeMessages(MSG_SHOW_KEY_PREVIEW);
+ if (mPreviewText.getVisibility() == VISIBLE || delay == 0) {
// Show right away, if it's already visible and finger is moving around
showKey(keyIndex, tracker);
} else {
- sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker),
- delay);
+ sendMessageDelayed(
+ obtainMessage(MSG_SHOW_KEY_PREVIEW, keyIndex, 0, tracker), delay);
}
}
- public void cancelPopupPreview() {
- removeMessages(MSG_POPUP_PREVIEW);
+ public void cancelShowKeyPreview(PointerTracker tracker) {
+ removeMessages(MSG_SHOW_KEY_PREVIEW, tracker);
}
- public void dismissPreview(long delay) {
- if (mPreviewPopup.isShowing()) {
- sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay);
- }
+ public void cancelAllShowKeyPreviews() {
+ removeMessages(MSG_SHOW_KEY_PREVIEW);
}
- public void cancelDismissPreview() {
- removeMessages(MSG_DISMISS_PREVIEW);
+ public void dismissKeyPreview(long delay, PointerTracker tracker) {
+ sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay);
+ }
+
+ public void cancelDismissKeyPreview(PointerTracker tracker) {
+ removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker);
+ }
+
+ public void cancelAllDismissKeyPreviews() {
+ removeMessages(MSG_DISMISS_KEY_PREVIEW);
}
public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
@@ -286,12 +272,22 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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();
- cancelPopupPreview();
- cancelDismissPreview();
+ cancelAllShowKeyPreviews();
+ cancelAllDismissKeyPreviews();
}
}
@@ -367,29 +363,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final Resources res = getResources();
- mPreviewPopup = new PopupWindow(context);
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;
+ mShowKeyPreview = false;
}
- mPreviewPopup.setTouchable(false);
- mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
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);
@@ -400,11 +384,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mKeyBackground.getPadding(mPadding);
mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density);
- // TODO: Refer frameworks/base/core/res/res/values/config.xml
+ // TODO: Refer to 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() {
@@ -455,7 +436,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final PointerTracker tracker = getPointerTracker(id);
// If the second down event is also on shift key.
if (tracker.isOnShiftKey((int)secondDown.getX(), (int)secondDown.getY())) {
- onDoubleTapShiftKey(tracker);
+ // 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.
@@ -474,6 +460,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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) {
@@ -498,23 +489,23 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
*/
public void setKeyboard(Keyboard keyboard) {
if (mKeyboard != null) {
- dismissKeyPreview();
+ dismissAllKeyPreviews();
}
// Remove any pending messages, except dismissing preview
mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
+ mHandler.cancelAllShowKeyPreviews();
mKeyboard = keyboard;
LatinImeLogger.onSetKeyboard(keyboard);
- mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
+ mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
-getPaddingTop() + mVerticalCorrection);
for (PointerTracker tracker : mPointerTrackers) {
- tracker.setKeyboard(keyboard, mKeys, mKeyHysteresisDistance);
+ tracker.setKeyboard(keyboard, mKeyHysteresisDistance);
}
requestLayout();
mKeyboardChanged = true;
invalidateAllKeys();
- mKeyDetector.setProximityThreshold(KeyDetector.getMostCommonKeyWidth(keyboard));
- mMiniKeyboardCache.clear();
+ mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
+ mPopupPanelCache.clear();
}
/**
@@ -536,56 +527,28 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
/**
- * 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
+ * @see #isKeyPreviewEnabled()
*/
- public void setPreviewEnabled(boolean previewEnabled) {
- mShowPreview = previewEnabled;
+ public void setKeyPreviewEnabled(boolean previewEnabled) {
+ mShowKeyPreview = previewEnabled;
}
/**
- * 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 #setKeyPreviewEnabled(boolean)
*/
- public boolean isPreviewEnabled() {
- return mShowPreview;
+ public boolean isKeyPreviewEnabled() {
+ return mShowKeyPreview;
}
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
@@ -651,152 +614,32 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
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());
+ if (mInvalidatedKey != null && mInvalidatedKeyRect.contains(mDirtyRect)) {
+ // Draw a single key.
+ onBufferDrawKey(canvas, mInvalidatedKey);
+ } else {
+ // Draw all keys.
+ for (final Key key : mKeyboard.getKeys()) {
+ onBufferDrawKey(canvas, key);
}
- 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++)
@@ -804,9 +647,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 (mPopupMiniKeyboardPanel != null) {
+ mPaint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
+ canvas.drawRect(0, 0, width, height, mPaint);
}
mInvalidatedKey = null;
@@ -814,6 +657,134 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mDirtyRect.setEmpty();
}
+ private void onBufferDrawKey(final Canvas canvas, final Key key) {
+ final Paint paint = mPaint;
+ final Drawable keyBackground = mKeyBackground;
+ final Rect padding = mPadding;
+ final int kbdPaddingLeft = getPaddingLeft();
+ final int kbdPaddingTop = getPaddingTop();
+ final int keyDrawX = key.mX + key.mVisualInsetsLeft;
+ final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
+ final int rowHeight = padding.top + key.mHeight;
+ final boolean isManualTemporaryUpperCase = mKeyboard.isManualTemporaryUpperCase();
+
+ canvas.translate(keyDrawX + kbdPaddingLeft, key.mY + kbdPaddingTop);
+
+ // Draw key background.
+ final int[] drawableState = key.getCurrentDrawableState();
+ keyBackground.setState(drawableState);
+ final Rect bounds = keyBackground.getBounds();
+ if (keyDrawWidth != bounds.right || key.mHeight != bounds.bottom) {
+ keyBackground.setBounds(0, 0, keyDrawWidth, key.mHeight);
+ }
+ keyBackground.draw(canvas);
+
+ // Draw key label.
+ if (key.mLabel != null) {
+ // Switch the character to uppercase if shift is pressed
+ final String label = key.mLabel == null ? null : adjustCase(key.mLabel).toString();
+ // 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, keyDrawWidth, 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, keyDrawWidth, 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 = keyDrawWidth - mKeyLabelHorizontalPadding - padding.right;
+ paint.setTextAlign(Align.RIGHT);
+ if (DEBUG_SHOW_ALIGN)
+ drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint());
+ } else {
+ positionX = (keyDrawWidth + 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 = keyDrawWidth - padding.right - mKeyLabelHorizontalPadding
+ - drawableWidth;
+ if (DEBUG_SHOW_ALIGN)
+ drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight,
+ 0xc0808000, new Paint());
+ } else { // Align center
+ drawableX = (keyDrawWidth + 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());
+ }
+
+ // Draw hint icon.
+ if (key.mHintIcon != null) {
+ final int drawableWidth = keyDrawWidth;
+ 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());
+ }
+
+ canvas.translate(-keyDrawX - kbdPaddingLeft, -key.mY - kbdPaddingTop);
+ }
+
public int getLabelSizeAndSetPaint(CharSequence label, int keyLabelOption, Paint paint) {
// For characters, use large font. For labels like "Done", use small font.
final int labelSize;
@@ -885,118 +856,119 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
// TODO: clean up this method.
- private void dismissKeyPreview() {
- for (PointerTracker tracker : mPointerTrackers)
- tracker.releaseKey();
- showPreview(KeyDetector.NOT_A_KEY, null);
+ private void dismissAllKeyPreviews() {
+ for (PointerTracker tracker : mPointerTrackers) {
+ tracker.setReleasedKeyGraphics();
+ dismissKeyPreview(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 showKeyPreview(int keyIndex, PointerTracker tracker) {
+ if (mShowKeyPreview) {
+ mHandler.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 dismissKeyPreview(PointerTracker tracker) {
+ if (mShowKeyPreview) {
+ mHandler.cancelShowKeyPreview(tracker);
+ mHandler.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) {
+ ViewGroup placer = mPreviewPlacer;
+ if (placer == null) {
+ final FrameLayout screenContent = (FrameLayout) getRootView().findViewById(
+ android.R.id.content);
+ if (android.os.Build.VERSION.SDK_INT >= /* HONEYCOMB */11) {
+ placer = screenContent;
+ } else {
+ // Insert LinearLayout to be able to setMargin because pre-Honeycomb FrameLayout
+ // could not handle setMargin properly.
+ placer = new LinearLayout(getContext());
+ screenContent.addView(placer);
}
+ mPreviewPlacer = placer;
+ }
+ if (placer instanceof FrameLayout) {
+ // Honeycomb or later.
+ placer.addView(keyPreview, new FrameLayout.LayoutParams(0, 0));
+ } else {
+ // Gingerbread or ealier.
+ placer.addView(keyPreview, new LinearLayout.LayoutParams(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)
return;
+
+ mHandler.cancelAllDismissKeyPreviews();
+
+ 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);
+ previewText.setText(adjustCase(tracker.getPreviewText(key)));
if (key.mLabel.length() > 1) {
- mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
- mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
+ previewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
- mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
- mPreviewText.setTypeface(mKeyLetterStyle);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
+ previewText.setTypeface(mKeyLetterStyle);
}
} else {
final Drawable previewIcon = key.getPreviewIcon();
- mPreviewText.setCompoundDrawables(null, null, null,
+ previewText.setCompoundDrawables(null, null, null,
previewIcon != null ? previewIcon : key.getIcon());
- mPreviewText.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;
- }
-
- 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.setText(null);
}
// 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.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ final int previewWidth = Math.max(previewText.getMeasuredWidth(), keyDrawWidth
+ + previewText.getPaddingLeft() + previewText.getPaddingRight());
+ final int previewHeight = mPreviewHeight;
+ getLocationInWindow(mCoordinates);
+ final int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + mCoordinates[0];
+ final int previewY = key.mY - previewHeight + mCoordinates[1] + mPreviewOffset;
+ // Record key preview position to display mini-keyboard later at the same position
+ mKeyPreviewDisplayedY = previewY;
+
+ // Place the key preview.
+ // TODO: Adjust position of key previews which touch screen edges
+ final MarginLayoutParams lp = (MarginLayoutParams)previewText.getLayoutParams();
+ lp.width = previewWidth;
+ lp.height = previewHeight;
+ lp.setMargins(previewX, previewY, 0, 0);
+ previewText.setVisibility(VISIBLE);
}
/**
@@ -1023,70 +995,72 @@ 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) {
+ private boolean openMiniKeyboardIfRequired(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)
+ final Key parentKey = tracker.getKey(keyIndex);
+ if (parentKey == null)
return false;
- boolean result = onLongPress(popupKey, tracker);
+ boolean result = onLongPress(parentKey, tracker);
if (result) {
- dismissKeyPreview();
- mMiniKeyboardTrackerId = tracker.mPointerId;
- // Mark this tracker "already processed" and remove it from the pointer queue
- tracker.setAlreadyProcessed();
- mPointerQueue.remove(tracker);
+ dismissAllKeyPreviews();
+ tracker.onLongPressed(mPointerQueue);
}
return result;
}
private void onLongPressShiftKey(PointerTracker tracker) {
- tracker.setAlreadyProcessed();
- mPointerQueue.remove(tracker);
+ tracker.onLongPressed(mPointerQueue);
mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
}
- private void onDoubleTapShiftKey(PointerTracker tracker) {
+ 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 mPointerQueueueue.
mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
}
- private View inflateMiniKeyboardContainer(Key popupKey) {
+ // 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 KeyboardView miniKeyboardView =
- (KeyboardView)container.findViewById(R.id.KeyboardView);
+ final PopupMiniKeyboardView miniKeyboardView =
+ (PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
miniKeyboardView.setOnKeyboardActionListener(new KeyboardActionListener() {
@Override
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
mKeyboardActionListener.onCodeInput(primaryCode, keyCodes, x, y);
- dismissPopupKeyboard();
+ dismissMiniKeyboard();
}
@Override
public void onTextInput(CharSequence text) {
mKeyboardActionListener.onTextInput(text);
- dismissPopupKeyboard();
+ dismissMiniKeyboard();
}
@Override
public void onCancelInput() {
mKeyboardActionListener.onCancelInput();
- dismissPopupKeyboard();
+ dismissMiniKeyboard();
}
@Override
@@ -1102,112 +1076,57 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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).build();
+ parentKey).build();
miniKeyboardView.setKeyboard(keyboard);
- miniKeyboardView.mMiniKeyboardParent = this;
container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
- return container;
- }
-
- private static boolean isOneRowKeys(List<Key> keys) {
- 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;
+ return miniKeyboardView;
}
/**
- * 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
+ * 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 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);
+ 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);
}
- final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX()
- : popupKey.mX + popupKey.mWidth / 2;
- final int popupX = pointX - miniKeyboard.getDefaultCoordX()
- - container.getPaddingLeft()
- + getPaddingLeft() + mWindowOffset[0];
- final int popupY = popupKey.mY - mKeyboard.getVerticalGap()
- - (container.getMeasuredHeight() - container.getPaddingBottom())
- + getPaddingTop() + mWindowOffset[1];
- final int x = popupX;
- final int y = mShowPreview && isOneRowKeys(miniKeyboard.getKeys())
- ? 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();
+ 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);
}
- // 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();
+ mPopupMiniKeyboardPanel = popupPanel;
+ popupPanel.showPanel(this, parentKey, tracker, mKeyPreviewDisplayedY, mPopupWindow);
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);
+ new PointerTracker(i, this, mHandler, mKeyDetector, this);
+ if (mKeyboard != null)
+ tracker.setKeyboard(mKeyboard, mKeyHysteresisDistance);
if (listener != null)
tracker.setOnKeyboardActionListener(listener);
pointers.add(tracker);
@@ -1217,8 +1136,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
public boolean isInSlidingKeyInput() {
- if (mMiniKeyboardView != null) {
- return mMiniKeyboardView.isInSlidingKeyInput();
+ if (mPopupMiniKeyboardPanel != null) {
+ return mPopupMiniKeyboardPanel.isInSlidingKeyInput();
} else {
return mPointerQueue.isInSlidingKeyInput();
}
@@ -1238,20 +1157,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// 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) {
+ if (!mHasDistinctMultitouch && 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();
+ // Gesture detector must be enabled only when mini-keyboard is not on the screen.
+ if (mPopupMiniKeyboardPanel == null && mGestureDetector != null
+ && mGestureDetector.onTouchEvent(me)) {
+ dismissAllKeyPreviews();
mHandler.cancelKeyTimers();
return true;
}
@@ -1262,26 +1178,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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;
+ // Needs to be called after the gesture detector gets a turn, as it may have displayed the
+ // mini keyboard
+ if (mPopupMiniKeyboardPanel != null) {
+ return mPopupMiniKeyboardPanel.onTouchEvent(me);
}
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.
@@ -1294,17 +1197,26 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// 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) {
+ if (!mHasDistinctMultitouch) {
// 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);
+ // 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, null);
+ if (action == MotionEvent.ACTION_UP)
+ tracker.onUpEvent(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);
+ final int lastX = tracker.getLastX();
+ final int lastY = tracker.getLastY();
+ mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
+ tracker.onUpEvent(lastX, lastY, eventTime, null);
} else if (pointerCount == 1 && oldPointerCount == 1) {
tracker.onTouchEvent(action, x, y, eventTime, null);
} else {
@@ -1345,12 +1257,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
}
public void closing() {
- mPreviewPopup.dismiss();
+ mPreviewText.setVisibility(View.GONE);
mHandler.cancelAllMessages();
- dismissPopupKeyboard();
+ dismissMiniKeyboard();
mDirtyRect.union(0, 0, getWidth(), getHeight());
- mMiniKeyboardCache.clear();
+ mPopupPanelCache.clear();
requestLayout();
}
@@ -1365,21 +1277,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
closing();
}
- private void dismissPopupKeyboard() {
- if (mMiniKeyboardPopup.isShowing()) {
- mMiniKeyboardPopup.dismiss();
- mMiniKeyboardView = null;
- mMiniKeyboardOriginX = 0;
- mMiniKeyboardOriginY = 0;
+ private boolean dismissMiniKeyboard() {
+ if (mPopupWindow != null && mPopupWindow.isShowing()) {
+ mPopupWindow.dismiss();
+ mPopupMiniKeyboardPanel = null;
invalidateAllKeys();
+ return true;
}
+ return false;
}
public boolean handleBack() {
- if (mMiniKeyboardPopup.isShowing()) {
- dismissPopupKeyboard();
- return true;
- }
- return false;
+ return dismissMiniKeyboard();
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index 5820049bb..c279769f6 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -26,6 +26,9 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.PorterDuff;
@@ -33,40 +36,48 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+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;
+ public static final int CODE_NEXT_LANGUAGE = -100;
+ public static final int CODE_PREV_LANGUAGE = -101;
+
private final Context mContext;
+ 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 int mSpaceKeyIndex;
private final Drawable mSpaceAutoCorrectionIndicator;
private final Drawable mButtonArrowLeftIcon;
private final Drawable mButtonArrowRightIcon;
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 final int mSpacebarLanguageSwitchThreshold;
+ private int mSpacebarSlidingLanguageSwitchDiff;
private 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)
+ // 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.4f;
// Height in space key the language name will be drawn. (proportional to space key height)
public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
@@ -92,7 +103,7 @@ public class LatinKeyboard extends Keyboard {
case CODE_SPACE:
spaceKeyIndex = index;
break;
- case CODE_VOICE:
+ case CODE_SHORTCUT:
shortcutKeyIndex = index;
break;
}
@@ -102,7 +113,7 @@ 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;
@@ -120,8 +131,8 @@ public class LatinKeyboard extends Keyboard {
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);
+ // The threshold is "key width" x 1.25
+ mSpacebarLanguageSwitchThreshold = (getMostCommonKeyWidth() * 5) / 4;
}
public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) {
@@ -137,6 +148,12 @@ public class LatinKeyboard extends Keyboard {
return newColor;
}
+ private static ColorFilter getSpacebarDrawableFilter(float fadeFactor) {
+ final ColorMatrix colorMatrix = new ColorMatrix();
+ colorMatrix.setScale(1, 1, 1, fadeFactor);
+ return new ColorMatrixColorFilter(colorMatrix);
+ }
+
public void updateShortcutKey(boolean available, LatinKeyboardView view) {
if (mShortcutKey == null)
return;
@@ -157,19 +174,14 @@ public class LatinKeyboard extends Keyboard {
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);
}
}
@@ -182,8 +194,7 @@ 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) {
+ Drawable rArrow, int width, int height, float origTextSize) {
final float arrowWidth = lArrow.getIntrinsicWidth();
final float arrowHeight = lArrow.getIntrinsicHeight();
final float maxTextWidth = width - (arrowWidth + arrowWidth);
@@ -194,17 +205,23 @@ public class LatinKeyboard extends Keyboard {
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);
+ // 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 > maxTextWidth);
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 = SubtypeSwitcher.getMiddleDisplayLanguage(locale);
+ textWidth = getTextWidth(paint, language, origTextSize, bounds);
+ textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
+ useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME)
+ || (textWidth > maxTextWidth);
} else {
- useShortName = textWidth > maxTextWidth;
- textSize = origTextSize;
+ useShortName = false;
}
+
if (useShortName) {
language = SubtypeSwitcher.getShortDisplayLanguage(locale);
textWidth = getTextWidth(paint, language, origTextSize, bounds);
@@ -223,19 +240,31 @@ public class LatinKeyboard extends Keyboard {
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(mContext.getResources(), 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);
+ 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 +281,9 @@ public class LatinKeyboard extends Keyboard {
defaultTextSize = 14;
}
- final boolean allowVariableTextSize = true;
- final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(),
+ final String language = layoutSpacebar(paint, inputLocale,
mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
- getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize),
- allowVariableTextSize);
+ getTextSizeFromTheme(mContext.getTheme(), 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,14 +292,19 @@ 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) {
+ // Put arrows that are already laid out on either side of the text
+ // Because language switch is disabled on phone and number layouts, hide arrows.
+ // TODO: Sort out how to enable language switch on these layouts.
+ if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()
+ && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1
+ && !(isPhoneKeyboard() || isNumberKeyboard())) {
+ mButtonArrowLeftIcon.setColorFilter(getSpacebarDrawableFilter(textFadeFactor));
+ mButtonArrowRightIcon.setColorFilter(getSpacebarDrawableFilter(textFadeFactor));
mButtonArrowLeftIcon.draw(canvas);
mButtonArrowRightIcon.draw(canvas);
}
@@ -297,7 +329,14 @@ public class LatinKeyboard extends Keyboard {
return buffer;
}
- private void updateLocaleDrag(int diff) {
+ public void setSpacebarSlidingLanguageSwitchDiff(int diff) {
+ mSpacebarSlidingLanguageSwitchDiff = diff;
+ }
+
+ public void updateSpacebarPreviewIcon(int diff) {
+ if (mSpacebarSlidingLanguageSwitchDiff == diff)
+ return;
+ mSpacebarSlidingLanguageSwitchDiff = diff;
if (mSlidingLocaleIcon == null) {
final int width = Math.max(mSpaceKey.mWidth,
(int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO));
@@ -305,7 +344,6 @@ public class LatinKeyboard extends Keyboard {
mSlidingLocaleIcon =
new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height);
mSlidingLocaleIcon.setBounds(0, 0, width, height);
- mSpaceKey.setPreviewIcon(mSlidingLocaleIcon);
}
mSlidingLocaleIcon.setDiff(diff);
if (Math.abs(diff) == Integer.MAX_VALUE) {
@@ -316,69 +354,49 @@ 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) {
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 77e9caecc..c98076f35 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -16,9 +16,9 @@
package com.android.inputmethod.keyboard;
+import com.android.inputmethod.deprecated.VoiceProxy;
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;
@@ -55,24 +55,19 @@ public class LatinKeyboardView extends KeyboardView {
}
@Override
- public void setPreviewEnabled(boolean previewEnabled) {
+ public void setKeyPreviewEnabled(boolean previewEnabled) {
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.setKeyPreviewEnabled(false);
} else {
- super.setPreviewEnabled(previewEnabled);
+ super.setKeyPreviewEnabled(previewEnabled);
}
}
@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;
@@ -145,10 +140,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();
@@ -216,8 +207,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 +216,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 +236,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 3b1408ccf..5dde15e94 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -18,6 +18,8 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
+import java.util.List;
+
public class MiniKeyboard extends Keyboard {
private int mDefaultKeyCoordX;
@@ -32,4 +34,19 @@ public class MiniKeyboard extends Keyboard {
public int getDefaultCoordX() {
return mDefaultKeyCoordX;
}
+
+ public boolean isOneRowKeyboard() {
+ 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/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
index 53dab9440..e540fa106 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
@@ -34,7 +34,7 @@ public class MiniKeyboardBuilder {
/* package */ static class MiniKeyboardLayoutParams {
public final int mKeyWidth;
public final int mRowHeight;
- /* package */ final boolean mTopRowNeedsCentering;
+ /* package */ final int mTopRowAdjustment;
public final int mNumRows;
public final int mNumColumns;
public final int mLeftKeys;
@@ -55,29 +55,52 @@ public class MiniKeyboardBuilder {
if (parentKeyboardWidth / keyWidth < maxColumns)
throw new IllegalArgumentException("Keyboard is too small to hold mini keyboard: "
+ parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
- final int numRows = (numKeys + maxColumns - 1) / maxColumns;
mKeyWidth = keyWidth;
mRowHeight = rowHeight;
- mNumRows = numRows;
- final int numColumns = Math.min(numKeys, maxColumns);
- final int topRowKeys = numKeys % numColumns;
+ final int numRows = (numKeys + maxColumns - 1) / maxColumns;
+ mNumRows = numRows;
+ final int numColumns = getOptimizedColumns(numKeys, maxColumns);
mNumColumns = numColumns;
- mTopRowNeedsCentering = topRowKeys != 0 && (numColumns - topRowKeys) % 2 != 0;
final int numLeftKeys = (numColumns - 1) / 2;
final int numRightKeys = numColumns - numLeftKeys; // including default key.
final int maxLeftKeys = coordXInParent / keyWidth;
final int maxRightKeys = Math.max(1, (parentKeyboardWidth - coordXInParent) / keyWidth);
+ int leftKeys, rightKeys;
if (numLeftKeys > maxLeftKeys) {
- mLeftKeys = maxLeftKeys;
- mRightKeys = numColumns - maxLeftKeys;
+ leftKeys = maxLeftKeys;
+ rightKeys = numColumns - maxLeftKeys;
} else if (numRightKeys > maxRightKeys) {
- mLeftKeys = numColumns - maxRightKeys;
- mRightKeys = maxRightKeys;
+ leftKeys = numColumns - maxRightKeys;
+ rightKeys = maxRightKeys;
} else {
- mLeftKeys = numLeftKeys;
- mRightKeys = numRightKeys;
+ leftKeys = numLeftKeys;
+ rightKeys = numRightKeys;
+ }
+ // Shift right if the left edge of mini keyboard is on the edge of parent keyboard
+ // unless the parent key is on the left edge.
+ if (leftKeys * keyWidth >= coordXInParent && leftKeys > 0) {
+ leftKeys--;
+ rightKeys++;
+ }
+ // Shift left if the right edge of mini keyboard is on the edge of parent keyboard
+ // unless the parent key is on the right edge.
+ if (rightKeys * keyWidth + coordXInParent >= parentKeyboardWidth && rightKeys > 1) {
+ leftKeys++;
+ rightKeys--;
+ }
+ mLeftKeys = leftKeys;
+ mRightKeys = rightKeys;
+
+ // Centering of the top row.
+ final boolean onEdge = (leftKeys == 0 || rightKeys == 1);
+ if (numRows < 2 || onEdge || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
+ mTopRowAdjustment = 0;
+ } else if (mLeftKeys < mRightKeys - 1) {
+ mTopRowAdjustment = 1;
+ } else {
+ mTopRowAdjustment = -1;
}
}
@@ -113,14 +136,32 @@ public class MiniKeyboardBuilder {
return pos;
}
+ private static int getTopRowEmptySlots(int numKeys, int numColumns) {
+ final int remainingKeys = numKeys % numColumns;
+ if (remainingKeys == 0) {
+ return 0;
+ } else {
+ return numColumns - remainingKeys;
+ }
+ }
+
+ private int getOptimizedColumns(int numKeys, int maxColumns) {
+ int numColumns = Math.min(numKeys, maxColumns);
+ while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) {
+ numColumns--;
+ }
+ return numColumns;
+ }
+
public int getDefaultKeyCoordX() {
return mLeftKeys * mKeyWidth;
}
public int getX(int n, int row) {
final int x = getColumnPos(n) * mKeyWidth + getDefaultKeyCoordX();
- if (isLastRow(row) && mTopRowNeedsCentering)
- return x - mKeyWidth / 2;
+ if (isTopRow(row)) {
+ return x + mTopRowAdjustment * (mKeyWidth / 2);
+ }
return x;
}
@@ -131,27 +172,27 @@ public class MiniKeyboardBuilder {
public int getRowFlags(int row) {
int rowFlags = 0;
if (row == 0) rowFlags |= Keyboard.EDGE_TOP;
- if (isLastRow(row)) rowFlags |= Keyboard.EDGE_BOTTOM;
+ if (isTopRow(row)) rowFlags |= Keyboard.EDGE_BOTTOM;
return rowFlags;
}
- private boolean isLastRow(int rowCount) {
+ private boolean isTopRow(int rowCount) {
return rowCount == mNumRows - 1;
}
}
- public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key popupKey) {
+ public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey) {
final Context context = view.getContext();
mRes = context.getResources();
final MiniKeyboard keyboard = new MiniKeyboard(context, layoutTemplateResId, null);
mKeyboard = keyboard;
- mPopupCharacters = popupKey.mPopupCharacters;
+ mPopupCharacters = parentKey.mPopupCharacters;
final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, keyboard.getKeyWidth());
final MiniKeyboardLayoutParams params = new MiniKeyboardLayoutParams(
- mPopupCharacters.length, popupKey.mMaxPopupColumn,
+ mPopupCharacters.length, parentKey.mMaxPopupColumn,
keyWidth, keyboard.getRowHeight(),
- popupKey.mX + (popupKey.mWidth + popupKey.mGap) / 2 - keyWidth / 2,
+ parentKey.mX + (parentKey.mWidth + parentKey.mGap) / 2 - keyWidth / 2,
view.getMeasuredWidth());
mParams = params;
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
index a8750d378..c4459f616 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
@@ -16,9 +16,9 @@
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;
@@ -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 = 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 746857819..953d487dc 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -19,12 +19,14 @@ 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 com.android.inputmethod.latin.SubtypeSwitcher;
import android.content.res.Resources;
import android.util.Log;
import android.view.MotionEvent;
import java.util.Arrays;
+import java.util.List;
public class PointerTracker {
private static final String TAG = PointerTracker.class.getSimpleName();
@@ -36,9 +38,9 @@ public class PointerTracker {
public interface UIProxy {
public void invalidateKey(Key key);
- public void showPreview(int keyIndex, PointerTracker tracker);
+ public void showKeyPreview(int keyIndex, PointerTracker tracker);
+ public void dismissKeyPreview(PointerTracker tracker);
public boolean hasDistinctMultitouch();
- public boolean isAccessibilityEnabled();
}
public final int mPointerId;
@@ -48,9 +50,7 @@ public class PointerTracker {
private final int mLongPressKeyTimeout;
private final int mLongPressShiftKeyTimeout;
- // Miscellaneous constants
- private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY;
-
+ private final KeyboardView mKeyboardView;
private final UIProxy mProxy;
private final UIHandler mHandler;
private final KeyDetector mKeyDetector;
@@ -63,15 +63,12 @@ public class PointerTracker {
private final int mTouchNoiseThresholdDistanceSquared;
private Keyboard mKeyboard;
- private Key[] mKeys;
+ private List<Key> mKeys;
private int mKeyHysteresisDistanceSquared = -1;
private int mKeyQuarterWidthSquared;
private final PointerTrackerKeyState mKeyState;
- // true if accessibility is enabled in the parent keyboard
- private boolean mIsAccessibilityEnabled;
-
// true if keyboard layout has been changed.
private boolean mKeyboardLayoutHasBeenChanged;
@@ -87,8 +84,14 @@ public class PointerTracker {
// 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 final SubtypeSwitcher mSubtypeSwitcher;
// Empty {@link KeyboardActionListener}
private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener() {
@@ -106,18 +109,19 @@ public class PointerTracker {
public void onSwipeDown() {}
};
- public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy,
- Resources res) {
+ public PointerTracker(int id, KeyboardView keyboardView, UIHandler handler,
+ KeyDetector keyDetector, UIProxy proxy) {
if (proxy == null || handler == null || keyDetector == null)
throw new NullPointerException();
mPointerId = id;
+ mKeyboardView = keyboardView;
mProxy = proxy;
mHandler = handler;
mKeyDetector = keyDetector;
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mKeyState = new PointerTrackerKeyState(keyDetector);
- mIsAccessibilityEnabled = proxy.isAccessibilityEnabled();
mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
+ final Resources res = mKeyboardView.getResources();
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);
@@ -127,20 +131,21 @@ public class PointerTracker {
R.dimen.config_touch_noise_threshold_distance);
mTouchNoiseThresholdDistanceSquared = (int)(
touchNoiseThresholdDistance * touchNoiseThresholdDistance);
+ mSubtypeSwitcher = SubtypeSwitcher.getInstance();
}
public void setOnKeyboardActionListener(KeyboardActionListener listener) {
mListener = listener;
}
- public void setAccessibilityEnabled(boolean accessibilityEnabled) {
- mIsAccessibilityEnabled = accessibilityEnabled;
- }
-
// 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);
+ Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding
+ + " ignoreModifier=" + ignoreModifierKey);
+ if (ignoreModifierKey)
+ return false;
if (key.mEnabled) {
mListener.onPress(key.mCode, withSliding);
final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
@@ -153,9 +158,13 @@ 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);
+ + " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y
+ + " ignoreModifier=" + ignoreModifierKey);
+ if (ignoreModifierKey)
+ return;
if (key.mEnabled)
mListener.onCodeInput(primaryCode, keyCodes, x, y);
}
@@ -170,8 +179,12 @@ 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 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);
+ Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding="
+ + withSliding + " ignoreModifier=" + ignoreModifierKey);
+ if (ignoreModifierKey)
+ return;
if (key.mEnabled)
mListener.onRelease(primaryCode, withSliding);
}
@@ -182,11 +195,11 @@ public class PointerTracker {
mListener.onCancelInput();
}
- public void setKeyboard(Keyboard keyboard, Key[] keys, float keyHysteresisDistance) {
- if (keyboard == null || keys == null || keyHysteresisDistance < 0)
+ public void setKeyboard(Keyboard keyboard, float keyHysteresisDistance) {
+ if (keyboard == null || keyHysteresisDistance < 0)
throw new IllegalArgumentException();
mKeyboard = keyboard;
- mKeys = keys;
+ mKeys = keyboard.getKeys();
mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
final int keyQuarterWidth = keyboard.getKeyWidth() / 4;
mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
@@ -199,11 +212,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) {
@@ -229,34 +242,33 @@ 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(mKeyState.getKeyIndex());
}
- 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();
+ mProxy.invalidateKey(key);
}
}
- public void setAlreadyProcessed() {
- mKeyAlreadyProcessed = true;
+ private void setPressedKeyGraphics(int keyIndex) {
+ final Key key = getKey(keyIndex);
+ if (key != null && key.mEnabled) {
+ key.onPressed();
+ mProxy.invalidateKey(key);
+ }
}
private void checkAssertion(PointerTrackerQueue queue) {
@@ -302,7 +314,7 @@ public class PointerTracker {
if (DEBUG_MODE)
Log.w(TAG, "onDownEvent: ignore potential noise: time=" + deltaT
+ " distance=" + distanceSquared);
- setAlreadyProcessed();
+ mKeyAlreadyProcessed = true;
return;
}
}
@@ -321,32 +333,33 @@ public class PointerTracker {
private void onDownEventInternal(int x, int y, long eventTime) {
int keyIndex = mKeyState.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.
+ // from modifier key, or 3) this pointer is on mini-keyboard.
mIsAllowedSlidingKeyInput = mConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
- || mKeyDetector instanceof MiniKeyboardKeyDetector
- || mIsAccessibilityEnabled;
+ || 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))
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(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;
- }
+
+ startRepeatKey(keyIndex);
startLongPressTimer(keyIndex);
+ showKeyPreview(keyIndex);
+ setPressedKeyGraphics(keyIndex);
}
- showKeyPreviewAndUpdateKeyGraphics(keyIndex);
+ }
+
+ private void startSlidingKeyInput(Key key) {
+ if (!mIsInSlidingKeyInput)
+ mIgnoreModifierKey = isModifierCode(key.mCode);
+ mIsInSlidingKeyInput = true;
}
public void onMoveEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
@@ -357,10 +370,17 @@ public class PointerTracker {
return;
final PointerTrackerKeyState keyState = mKeyState;
+ // TODO: Remove this hacking code
+ if (mIsInSlidingLanguageSwitch) {
+ ((LatinKeyboard)mKeyboard).updateSpacebarPreviewIcon(x - keyState.getKeyX());
+ showKeyPreview(mSpaceKeyIndex);
+ return;
+ }
final int lastX = keyState.getLastX();
final int lastY = keyState.getLastY();
+ final int oldKeyIndex = keyState.getKeyIndex();
+ final Key oldKey = getKey(oldKeyIndex);
int keyIndex = keyState.onMoveKey(x, y);
- final Key oldKey = getKey(keyState.getKeyIndex());
if (isValidKeyIndex(keyIndex)) {
if (oldKey == null) {
// The pointer has been slid in to the new key, but the finger was not on any keys.
@@ -372,13 +392,17 @@ public class PointerTracker {
keyIndex = keyState.onMoveKey(x, y);
keyState.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);
+ mHandler.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
@@ -387,6 +411,8 @@ public class PointerTracker {
keyIndex = keyState.onMoveKey(x, y);
keyState.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,32 +424,50 @@ 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 (mSubtypeSwitcher.useSpacebarLanguageSwitcher()
+ && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
+ final int diff = x - keyState.getKeyX();
+ if (keyboard.shouldTriggerSpacebarSlidingLanguageSwitch(diff)) {
+ // Detect start sliding language switch.
+ mIsInSlidingLanguageSwitch = true;
+ mSpaceKeyIndex = keyIndex;
+ keyboard.updateSpacebarPreviewIcon(diff);
+ // Display spacebar slide language switcher.
+ showKeyPreview(keyIndex);
+ 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);
+ startSlidingKeyInput(oldKey);
mHandler.cancelLongPressTimers();
if (mIsAllowedSlidingKeyInput) {
- keyState.onMoveToNewKey(keyIndex, x ,y);
+ keyState.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) {
@@ -435,42 +479,69 @@ public class PointerTracker {
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;
+ private void onUpEventInternal(int x, int y, long eventTime,
+ boolean updateReleasedKeyGraphics) {
mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
- showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
+ mHandler.cancelShowKeyPreview(this);
mIsInSlidingKeyInput = false;
+ final PointerTrackerKeyState keyState = mKeyState;
+ final int keyX, keyY;
+ if (isMajorEnoughMoveToBeOnNewKey(x, y, keyState.onMoveKey(x, y))) {
+ keyX = x;
+ keyY = y;
+ } else {
+ // Use previous fixed key coordinates.
+ keyX = keyState.getKeyX();
+ keyY = keyState.getKeyY();
+ }
+ final int keyIndex = keyState.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(PointerTrackerQueue queue) {
+ mKeyAlreadyProcessed = true;
+ if (queue != null)
+ queue.remove(this);
}
public void onCancelEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
@@ -478,22 +549,34 @@ public class PointerTracker {
if (DEBUG_EVENT)
printTouchEvent("onCancelEvt:", x, y, eventTime);
- if (queue != null)
+ if (queue != null) {
+ queue.releaseAllPointersExcept(this, eventTime, true);
queue.remove(this);
+ }
onCancelEventInternal();
}
private void onCancelEventInternal() {
mHandler.cancelKeyTimers();
- mHandler.cancelPopupPreview();
- showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
+ mHandler.cancelShowKeyPreview(this);
+ dismissKeyPreview();
+ setReleasedKeyGraphics(mKeyState.getKeyIndex());
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);
+ mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, 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);
@@ -512,39 +595,46 @@ public class PointerTracker {
return mKeyState.getDownTime();
}
- private boolean isMinorMoveBounce(int x, int y, int newKey) {
+ private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, int newKey) {
if (mKeys == null || mKeyHysteresisDistanceSquared < 0)
throw new IllegalStateException("keyboard and/or hysteresis not set");
int curKey = mKeyState.getKeyIndex();
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) >= mKeyHysteresisDistanceSquared;
} 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.mEnabled)
+ 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;
- }
+ mProxy.showKeyPreview(keyIndex, this);
+ }
+
+ private void dismissKeyPreview() {
+ mProxy.dismissKeyPreview(this);
+ }
+
+ private void startLongPressTimer(int keyIndex) {
Key key = getKey(keyIndex);
+ if (!key.mEnabled)
+ return;
if (key.mCode == Keyboard.CODE_SHIFT) {
mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
} else if (key.mManualTemporaryUpperCaseCode != Keyboard.CODE_DUMMY
@@ -552,7 +642,7 @@ public class PointerTracker {
// 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 (mKeyboardSwitcher.isInMomentarySwitchState()) {
// We use longer timeout for sliding finger input started from the symbols mode key.
mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
} else {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
index a62ed96a3..b3ed1e26f 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
@@ -92,6 +92,7 @@ package com.android.inputmethod.keyboard;
public int onUpKey(int x, int y, long eventTime) {
mUpTime = eventTime;
+ mKeyIndex = KeyDetector.NOT_A_KEY;
return onMoveKeyInternal(x, y);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
index 928f3cdc1..68de8df8a 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
@@ -29,29 +29,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)
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..12031f1ea
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -0,0 +1,124 @@
+/*
+ * 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 com.android.inputmethod.latin.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.PopupWindow;
+
+/**
+ * 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 int mOriginX;
+ private int mOriginY;
+ private int mTrackerId;
+ private long mDownTime;
+
+ public PopupMiniKeyboardView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.keyboardViewStyle);
+ }
+
+ public PopupMiniKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ 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
+ mGestureDetector = null;
+ setKeyPreviewEnabled(false);
+ }
+
+ @Override
+ public void setKeyPreviewEnabled(boolean previewEnabled) {
+ // Mini keyboard needs no pop-up key preview displayed.
+ super.setKeyPreviewEnabled(false);
+ }
+
+ @Override
+ public void showPanel(KeyboardView parentKeyboardView, Key parentKey,
+ PointerTracker tracker, int keyPreviewY, PopupWindow window) {
+ 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 miniKeyboardX = pointX - miniKeyboard.getDefaultCoordX()
+ - container.getPaddingLeft()
+ + parentKeyboardView.getPaddingLeft() + mCoordinates[0];
+ final int miniKeyboardY = pointY - parentKeyboard.getVerticalGap()
+ - (container.getMeasuredHeight() - container.getPaddingBottom())
+ + parentKeyboardView.getPaddingTop() + mCoordinates[1];
+ final int x = miniKeyboardX;
+ final int y = parentKeyboardView.isKeyPreviewEnabled() && miniKeyboard.isOneRowKeyboard()
+ ? keyPreviewY : miniKeyboardY;
+
+ 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];
+ mTrackerId = tracker.mPointerId;
+ mDownTime = SystemClock.uptimeMillis();
+
+ // Inject down event on the key to mini keyboard.
+ final MotionEvent downEvent = translateMotionEvent(MotionEvent.ACTION_DOWN, pointX,
+ pointY + parentKey.mHeight / 2, mDownTime);
+ onTouchEvent(downEvent);
+ downEvent.recycle();
+ }
+
+ private MotionEvent translateMotionEvent(int action, float x, float y, long eventTime) {
+ return MotionEvent.obtain(mDownTime, eventTime, action, x - mOriginX, y - mOriginY, 0);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent me) {
+ final int index = me.getActionIndex();
+ final int id = me.getPointerId(index);
+ if (id == mTrackerId) {
+ final MotionEvent translated = translateMotionEvent(me.getAction(), me.getX(index),
+ me.getY(index), me.getEventTime());
+ super.onTouchEvent(translated);
+ translated.recycle();
+ }
+ return true;
+ }
+}
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..6f2b16148
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
@@ -0,0 +1,46 @@
+/*
+ * 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.view.MotionEvent;
+import android.widget.PopupWindow;
+
+public interface PopupPanel {
+ /**
+ * 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 keyPreviewY the Y-coordinate of key preview
+ * @param window PopupWindow to be used to show this popup panel
+ */
+ public void showPanel(KeyboardView parentKeyboardView, Key parentKey,
+ PointerTracker tracker, int keyPreviewY, PopupWindow window);
+
+ /**
+ * Check if the pointer is in siding key input mode.
+ * @return true if the pointer is sliding key input mode.
+ */
+ public boolean isInSlidingKeyInput();
+
+ /**
+ * The motion event handler.
+ * @param me the MotionEvent to be processed.
+ * @return true if the motion event is processed and should be consumed.
+ */
+ public boolean onTouchEvent(MotionEvent me);
+}
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 87f3e1497..000000000
--- a/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * 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/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
index 41f8c2a7c..b279c1c7e 100644
--- a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
+++ b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
@@ -23,6 +23,7 @@ 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;
@@ -63,9 +64,8 @@ public class SlidingLocaleDrawable extends Drawable {
mHeight = height;
final TextPaint textPaint = new TextPaint();
textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18));
- textPaint.setColor(R.color.latinkeyboard_transparent);
+ textPaint.setColor(Color.TRANSPARENT);
textPaint.setTextAlign(Align.CENTER);
- textPaint.setAlpha(LatinKeyboard.OPACITY_FULLY_OPAQUE);
textPaint.setAntiAlias(true);
mTextPaint = textPaint;
mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2;
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 a00b0915c..307b81d43 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;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 08ddd25fa..d95fb9638 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,12 @@ 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);
return getSuggestionsNative(
mNativeDict, keyboard.getProximityInfo(),
codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize,
- mFlags, outputChars, frequencies);
+ mFlags, outputChars, scores);
}
@Override
@@ -247,10 +209,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 +218,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..562580d41
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ return BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Unable to create dictionary file from provider for locale "
+ + locale.toString() + ": falling back to internal dictionary");
+ return Arrays.asList(loadFallbackResource(context, fallbackResId));
+ } 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 5719b9012..abdf30e6b 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -133,7 +133,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
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);
@@ -151,7 +150,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
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);
+ divider.setVisibility(i == 0 ? INVISIBLE : VISIBLE);
mWords.add(v);
}
@@ -180,7 +179,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
private void updateSuggestions() {
final SuggestedWords suggestions = mSuggestions;
clear();
- final int count = suggestions.size();
+ final int count = Math.min(mWords.size(), suggestions.size());
for (int i = 0; i < count; i++) {
CharSequence word = suggestions.getWord(i);
if (word == null) continue;
diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java
index 048f72dc5..b057cf4e3 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 = {
@@ -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();
@@ -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;
}
}
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..3fcb6ed55
--- /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 (final Dictionary dict : mDictionaries)
+ if (dict.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..605676d70
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -0,0 +1,158 @@
+/*
+ * 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: 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 0ca06ddfc..39e7e402f 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..26391fe46 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;
}
}
@@ -301,7 +304,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 +331,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);
@@ -462,6 +466,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,18 +481,15 @@ 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);
}
}
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/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 6e76cadf2..8b130aecd 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -16,14 +16,20 @@
package com.android.inputmethod.latin;
+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.deprecated.LanguageSwitcherProxy;
+import com.android.inputmethod.deprecated.VoiceProxy;
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 android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -42,7 +48,6 @@ 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;
@@ -51,7 +56,6 @@ 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;
@@ -61,27 +65,19 @@ 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 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 {
private static final String TAG = LatinIME.class.getSimpleName();
private static final boolean PERF_DEBUG = false;
private static final boolean TRACE = false;
@@ -94,6 +90,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 +106,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 +113,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 +133,45 @@ 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 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.
private int mCorrectionMode;
private int mCommittedLength;
@@ -189,7 +179,6 @@ 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;
@@ -199,66 +188,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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 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();
@@ -270,6 +211,7 @@ 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;
@Override
public void handleMessage(Message msg) {
@@ -280,34 +222,43 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
updateSuggestions();
break;
case MSG_UPDATE_OLD_SUGGESTIONS:
- setOldSuggestions();
+ mRecorrection.setRecorrectionSuggestions(mVoiceProxy, mCandidateView, mSuggest,
+ mKeyboardSwitcher, mWord, mHasUncommittedTypedChars, mLastSelectionStart,
+ mLastSelectionEnd, mSettingsValues.mWordSeparators);
break;
case MSG_UPDATE_SHIFT_STATE:
switcher.updateShiftState();
break;
+ case MSG_SET_BIGRAM_PREDICTIONS:
+ updateBigramPredictions();
+ break;
case MSG_VOICE_RESULTS:
- mVoiceConnector.handleVoiceResults(preferCapitalization()
+ mVoiceProxy.handleVoiceResults(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 + mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar) / 2,
(LatinKeyboard)msg.obj);
+ }
sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj),
- mConfigDurationOfFadeoutLanguageOnSpacebar);
+ mSettingsValues.mDurationOfFadeoutLanguageOnSpacebar);
break;
case MSG_DISMISS_LANGUAGE_ON_SPACEBAR:
- if (inputView != null)
+ if (inputView != null) {
inputView.setSpacebarTextFadeFactor(
- mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj);
+ 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),
+ mSettingsValues.mDelayUpdateSuggestions);
}
public void cancelUpdateSuggestions() {
@@ -321,7 +272,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);
+ mSettingsValues.mDelayUpdateOldSuggestions);
}
public void cancelUpdateOldSuggestions() {
@@ -330,13 +281,24 @@ 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),
+ mSettingsValues.mDelayUpdateShiftState);
}
public void cancelUpdateShiftState() {
removeMessages(MSG_UPDATE_SHIFT_STATE);
}
+ public void postUpdateBigramPredictions() {
+ removeMessages(MSG_SET_BIGRAM_PREDICTIONS);
+ sendMessageDelayed(obtainMessage(MSG_SET_BIGRAM_PREDICTIONS),
+ mSettingsValues.mDelayUpdateSuggestions);
+ }
+
+ public void cancelUpdateBigramPredictions() {
+ removeMessages(MSG_SET_BIGRAM_PREDICTIONS);
+ }
+
public void updateVoiceResults() {
sendMessage(obtainMessage(MSG_VOICE_RESULTS));
}
@@ -347,14 +309,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
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);
// The language is always displayed when the delay is negative.
- if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) {
+ final boolean needsToDisplayLanguage = localeChanged
+ || mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar < 0;
+ // The language is never displayed when the delay is zero.
+ if (mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar != 0) {
+ inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f
+ : mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, keyboard);
+ }
+ // The fadeout animation will start when the delay is positive.
+ if (localeChanged && mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar > 0) {
sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard),
- mConfigDelayBeforeFadeoutLanguageOnSpacebar);
+ mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar);
}
}
}
@@ -362,7 +328,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void startDoubleSpacesTimer() {
removeMessages(MSG_SPACE_TYPED);
sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED),
- mConfigDoubleSpacesTurnIntoPeriodTimeout);
+ mSettingsValues.mDoubleSpacesTurnIntoPeriodTimeout);
}
public void cancelDoubleSpacesTimer() {
@@ -379,43 +345,24 @@ 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);
- AccessibilityUtils.init(this, prefs);
+ Recorrection.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();
+
+ 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) {
@@ -428,49 +375,73 @@ 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());
}
private void initSuggest() {
- String locale = mSubtypeSwitcher.getInputLocaleStr();
+ final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
+ final Locale keyboardLocale = new Locale(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);
- 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);
+ }
+
+ /* package private */ void resetSuggestMainDict() {
+ final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
+ final Locale keyboardLocale = new Locale(localeStr);
+ int mainDicResId = Utils.getMainDictionaryResourceId(mResources);
+ mSuggest.resetMainDict(this, mainDicResId, keyboardLocale);
}
@Override
@@ -480,7 +451,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSuggest = null;
}
unregisterReceiver(mReceiver);
- mVoiceConnector.destroy();
+ unregisterReceiver(mDictionaryPackInstallReceiver);
+ mVoiceProxy.destroy();
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
super.onDestroy();
@@ -501,8 +473,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
@@ -515,12 +490,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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);
- }
+ mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height);
mCandidateView = (CandidateView) container.findViewById(R.id.candidates);
mCandidateView.setService(this);
setCandidatesViewShown(true);
@@ -532,7 +502,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final KeyboardSwitcher switcher = mKeyboardSwitcher;
LatinKeyboardView inputView = switcher.getInputView();
- if(DEBUG) {
+ if (DEBUG) {
Log.d(TAG, "onStartInputView: " + inputView);
}
// In landscape mode, this method gets called without the input view being created.
@@ -547,20 +517,31 @@ 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;
+ mHasUncommittedTypedChars = false;
mDeleteCount = 0;
- mJustAddedAutoSpace = false;
+ mJustAddedMagicSpace = 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(),
@@ -568,20 +549,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
switcher.updateShiftState();
}
- setCandidatesViewShownInternal(isCandidateStripVisible(),
- false /* needsInputViewShown */ );
+ setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ );
// 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.setKeyPreviewEnabled(mSettingsValues.mPopupOn);
inputView.setProximityCorrectionEnabled(true);
- inputView.setAccessibilityEnabled(accessibilityEnabled);
// If we just entered a text field, maybe it has some old text that requires correction
- checkRecorrectionOnStart();
+ mRecorrection.checkRecorrectionOnStart();
inputView.setForeground(true);
voiceIme.onStartInputView(inputView.getWindowToken());
@@ -594,7 +571,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;
@@ -603,17 +580,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;
@@ -644,34 +621,6 @@ 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 onFinishInput() {
super.onFinishInput();
@@ -679,7 +628,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
LatinImeLogger.commit();
mKeyboardSwitcher.onAutoCorrectionStateChanged(false);
- mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging);
+ mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
KeyboardView inputView = mKeyboardSwitcher.getInputView();
if (inputView != null) inputView.closing();
@@ -700,7 +649,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
@@ -721,36 +670,41 @@ 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 (((mComposing.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.saveWordInHistory(mWord, mComposing);
}
mComposing.setLength(0);
- mHasValidSuggestions = false;
- mHandler.postUpdateSuggestions();
+ mHasUncommittedTypedChars = false;
+ if (isCursorTouchingWord()) {
+ mHandler.cancelUpdateBigramPredictions();
+ mHandler.postUpdateSuggestions();
+ } else {
+ setPunctuationSuggestions();
+ }
TextEntryState.reset();
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.finishComposingText();
}
- mVoiceConnector.setVoiceInputHighlighted(false);
- } else if (!mHasValidSuggestions && !mJustAccepted) {
+ mVoiceProxy.setVoiceInputHighlighted(false);
+ } else if (!mHasUncommittedTypedChars && !mJustAccepted) {
if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) {
if (TextEntryState.isAcceptedDefault())
TextEntryState.reset();
- mJustAddedAutoSpace = false; // The user moved the cursor.
+ mJustAddedMagicSpace = false; // The user moved the cursor.
}
}
mJustAccepted = false;
@@ -760,28 +714,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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;
}
/**
@@ -794,7 +735,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
@Override
public void onExtractedTextClicked() {
- if (mRecorrectionEnabled && isSuggestionsRequested()) return;
+ if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return;
super.onExtractedTextClicked();
}
@@ -810,7 +751,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);
}
@@ -825,8 +766,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mOptionsDialog.dismiss();
mOptionsDialog = null;
}
- mVoiceConnector.hideVoiceWindow(mConfigurationChanging);
- mWordHistory.clear();
+ mVoiceProxy.hideVoiceWindow(mConfigurationChanging);
+ mRecorrection.clearWordsInHistory();
super.hideWindow();
}
@@ -859,10 +800,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) {
- // TODO: Remove this if we support candidates with hard keyboard
+ // TODO: Modify this if we support candidates with hard keyboard
if (onEvaluateInputViewShown()) {
- super.setCandidatesViewShown(shown
- && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true));
+ final boolean shouldShowCandidates = shown
+ && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true);
+ if (isExtractViewShown()) {
+ // No need to have extra space to show the key preview.
+ mCandidateViewContainer.setMinimumHeight(0);
+ super.setCandidatesViewShown(shown);
+ } 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);
+ super.setCandidatesViewShown(true);
+ }
}
}
@@ -874,37 +826,28 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onComputeInsets(InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
- if (!isFullscreenMode()) {
- outInsets.contentTopInsets = outInsets.visibleTopInsets;
- }
- KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ final KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ if (inputView == 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
@@ -960,8 +903,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void commitTyped(InputConnection inputConnection) {
- if (mHasValidSuggestions) {
- mHasValidSuggestions = false;
+ if (mHasUncommittedTypedChars) {
+ mHasUncommittedTypedChars = false;
if (mComposing.length() > 0) {
if (inputConnection != null) {
inputConnection.commitText(mComposing, 1);
@@ -977,45 +920,29 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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;
@@ -1031,7 +958,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ic.commitText(". ", 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
- mJustAddedAutoSpace = true;
} else {
mHandler.startDoubleSpacesTimer();
}
@@ -1080,7 +1006,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void onSettingsKeyPressed() {
if (!isShowingOptionDialog()) {
- if (!mConfigEnableShowSubtypeSettings) {
+ if (!mSettingsValues.mEnableShowSubtypeSettings) {
showSubtypeSelectorAndSettings();
} else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) {
showOptionsMenu();
@@ -1113,7 +1039,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mLastKeyTime = when;
KeyboardSwitcher switcher = mKeyboardSwitcher;
- final boolean accessibilityEnabled = switcher.isAccessibilityEnabled();
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
switch (primaryCode) {
case Keyboard.CODE_DELETE:
@@ -1123,12 +1048,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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:
@@ -1142,29 +1067,24 @@ 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();
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);
}
@@ -1176,10 +1096,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);
@@ -1187,7 +1107,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY);
- mJustAddedAutoSpace = false;
+ mJustAddedMagicSpace = false;
mEnteredText = text;
}
@@ -1198,25 +1118,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void handleBackspace() {
- if (mVoiceConnector.logAndRevertVoiceInput()) return;
+ if (mVoiceProxy.logAndRevertVoiceInput()) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
- mVoiceConnector.handleBackspace();
+ mVoiceProxy.handleBackspace();
boolean deleteChar = false;
- if (mHasValidSuggestions) {
+ if (mHasUncommittedTypedChars) {
final int length = mComposing.length();
if (length > 0) {
mComposing.delete(length - 1, length);
mWord.deleteLast();
ic.setComposingText(mComposing, 1);
if (mComposing.length() == 0) {
- mHasValidSuggestions = false;
+ 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);
}
@@ -1256,9 +1183,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;
}
@@ -1269,37 +1195,33 @@ 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) {
+ EditorInfoCompatUtils.performEditorActionNext(ic);
ic.performEditorAction(EditorInfo.IME_ACTION_NEXT);
- } else if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0
+ } 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;
+ if (!mHasUncommittedTypedChars) {
+ mHasUncommittedTypedChars = true;
mComposing.setLength(0);
- saveWordInHistory(mBestWord);
+ mRecorrection.saveWordInHistory(mWord, mBestWord);
mWord.reset();
clearSuggestions();
}
@@ -1323,7 +1245,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
}
- if (mHasValidSuggestions) {
+ if (mHasUncommittedTypedChars) {
if (mComposing.length() == 0 && switcher.isAlphabetMode()
&& switcher.isShiftedOrShiftLocked()) {
mWord.setFirstCharCapitalized(true);
@@ -1342,16 +1264,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} 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();
}
@@ -1360,54 +1289,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();
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();
@@ -1418,45 +1354,29 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void handleClose() {
commitTyped(getCurrentInputConnection());
- mVoiceConnector.handleClose();
+ mVoiceProxy.handleClose();
requestHideSelf(0);
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
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())
@@ -1491,7 +1411,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void setSuggestions(SuggestedWords words) {
- if (mVoiceConnector.getAndResetIsShowingHint()) {
+ if (mVoiceProxy.getAndResetIsShowingHint()) {
setCandidatesView(mCandidateViewContainer);
}
@@ -1507,31 +1427,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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) {
// 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);
@@ -1559,14 +1469,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable);
} else {
final SuggestedWords previousSuggestions = mCandidateView.getSuggestions();
- if (previousSuggestions == mSuggestPuncList)
+ 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)) {
@@ -1582,27 +1492,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setCandidatesViewShown(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);
+ TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord, separatorCode);
mJustAccepted = true;
pickSuggestion(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;
}
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();
@@ -1627,21 +1537,34 @@ 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 int toLeft = (ic == null) ? 0 : ic.getTextBeforeCursor(1, 0).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;
}
+ 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.
+ mWord.reset();
+ }
mJustAccepted = true;
pickSuggestion(suggestion);
// Add the word to the auto dictionary if it's not a known word
@@ -1654,9 +1577,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
index, suggestions.mWords);
TextEntryState.acceptedSuggestion(mComposing.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:
@@ -1678,8 +1600,9 @@ 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();
+ TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true,
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
+ // From there on onUpdateSelection() will fire so suggestions will be updated
} else 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.
@@ -1706,97 +1629,40 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
- mVoiceConnector.rememberReplacedWord(suggestion, mWordSeparators);
+ mVoiceProxy.rememberReplacedWord(suggestion, mSettingsValues.mWordSeparators);
ic.commitText(suggestion, 1);
}
- saveWordInHistory(suggestion);
- mHasValidSuggestions = false;
+ mRecorrection.saveWordInHistory(mWord, suggestion);
+ mHasUncommittedTypedChars = false;
mCommittedLength = suggestion.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();
+ private 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.getInputView(), 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);
+ public void setPunctuationSuggestions() {
+ setSuggestions(mSettingsValues.mSuggestPuncList);
setCandidatesViewShown(isCandidateStripVisible());
}
@@ -1835,27 +1701,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,53 +1737,49 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void revertLastWord(boolean deleteChar) {
final int length = mComposing.length();
- if (!mHasValidSuggestions && length > 0) {
+ if (!mHasUncommittedTypedChars && 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))) {
+ if (!TextUtils.isEmpty(toTheLeft)
+ && mSettingsValues.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.isEmpty(punctuation)
+ && mSettingsValues.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);
+ TextEntryState.typedCharacter(punctuation.charAt(0), true,
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
// Clear composing text
mComposing.setLength(0);
} else {
- mHasValidSuggestions = true;
+ mHasUncommittedTypedChars = true;
ic.setComposingText(mComposing, 1);
TextEntryState.backspace();
}
+ mHandler.cancelUpdateBigramPredictions();
mHandler.postUpdateSuggestions();
} else {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
}
}
- protected String getWordSeparators() {
- return mWordSeparators;
- }
-
public boolean isWordSeparator(int code) {
- String separators = getWordSeparators();
- return separators.contains(String.valueOf((char)code));
- }
-
- private boolean isSentenceSeparator(int code) {
- return mSentenceSeparators.contains(String.valueOf((char)code));
+ return mSettingsValues.isWordSeparator(code);
}
- private void sendSpace() {
+ private void sendMagicSpace() {
sendKeyChar((char)Keyboard.CODE_SPACE);
+ mJustAddedMagicSpace = true;
mKeyboardSwitcher.updateShiftState();
}
@@ -1922,28 +1787,31 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mWord.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);
- }
// 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();
}
+ // "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.
+ onRefreshKeyboard();
+ }
+
@Override
public void onSwipeDown() {
- if (mConfigSwipeDownDismissKeyboardEnabled)
+ if (mSettingsValues.mSwipeDownDismissKeyboardEnabled)
handleClose();
}
@@ -1962,21 +1830,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);
}
@@ -1999,7 +1864,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);
}
}
@@ -2011,7 +1876,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
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;
@@ -2031,7 +1896,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void vibrate() {
- if (!mVibrateOn) {
+ if (!mSettingsValues.mVibrateOn) {
return;
}
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
@@ -2052,18 +1917,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public boolean getPopupOn() {
- return mPopupOn;
+ return mSettingsValues.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);
@@ -2072,12 +1941,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));
@@ -2105,121 +1973,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[] {
@@ -2233,13 +1986,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:
@@ -2305,14 +2055,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
p.println(" mComposing=" + mComposing.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(" mPopupOn=" + mSettingsValues.mPopupOn);
}
// Characters per second measurement
@@ -2332,9 +2082,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..e460471a5 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -45,10 +45,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 +57,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/Recorrection.java b/java/src/com/android/inputmethod/latin/Recorrection.java
new file mode 100644
index 000000000..3fa6292ba
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/Recorrection.java
@@ -0,0 +1,255 @@
+/*
+ * 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.InputConnectionCompatUtils;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+
+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 {
+ private static final Recorrection sInstance = new Recorrection();
+
+ private LatinIME mService;
+ private boolean mRecorrectionEnabled = false;
+ private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>();
+
+ 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) {
+ final Resources res = context.getResources();
+ // 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);
+ }
+ mService = context;
+ }
+
+ public void checkRecorrectionOnStart() {
+ if (!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 (mRecorrectionEnabled && mService.isShowingSuggestionsStrip()) {
+ // Don't look for corrections if the keyboard is not visible
+ if (keyboardSwitcher.isInputViewShown()) {
+ // Check if we should go in or out of correction mode.
+ if (mService.isSuggestionsRequested()
+ && (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 saveWordInHistory(WordComposer word, CharSequence result) {
+ 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();
+ WordAlternatives entry = new WordAlternatives(resultCopy, new WordComposer(word));
+ mWordHistory.add(entry);
+ }
+
+ public void clearWordsInHistory() {
+ mWordHistory.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 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)) {
+ 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 WordAlternatives(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,
+ WordAlternatives alternatives) {
+ SuggestedWords.Builder builder = alternatives.getAlternatives(suggest, keyboardSwitcher);
+ builder.setTypedWordValid(false).setHasMinimalSuggestion(false);
+ mService.showSuggestions(builder.build(), alternatives.getOriginalWord());
+ }
+
+ public void setRecorrectionSuggestions(VoiceProxy voiceProxy, CandidateView candidateView,
+ Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word,
+ boolean hasUncommittedTypedChars, int lastSelectionStart, int lastSelectionEnd,
+ String wordSeparators) {
+ if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) 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.setPunctuationSuggestions(); // Show the punctuation suggestions list
+ }
+ } else {
+ abortRecorrection(true);
+ }
+ }
+
+ public void abortRecorrection(boolean force) {
+ if (force || TextEntryState.isRecorrecting()) {
+ TextEntryState.onAbortRecorrection();
+ mService.setCandidatesViewShown(mService.isCandidateStripVisible());
+ mService.getCurrentInputConnection().finishComposingText();
+ mService.clearSuggestions();
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 341d5add0..5eb365774 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -16,17 +16,21 @@
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 android.app.AlertDialog;
import android.app.Dialog;
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;
@@ -41,6 +45,7 @@ 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
@@ -60,29 +65,223 @@ 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_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_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 boolean mEnableShowSubtypeSettings;
+ public final boolean mSwipeDownDismissKeyboardEnabled;
+ 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 mPopupOn; // Warning : this escapes through LatinIME#isPopupOn
+ 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 Values(final SharedPreferences prefs, final Context context,
+ final String localeStr) {
+ final Resources res = context.getResources();
+ final Locale savedLocale;
+ if (null != localeStr) {
+ final Locale keyboardLocale = new Locale(localeStr);
+ savedLocale = Utils.setSystemLocale(res, keyboardLocale);
+ } else {
+ savedLocale = null;
+ }
+
+ // Get the resources
+ mEnableShowSubtypeSettings = res.getBoolean(
+ R.bool.config_enable_show_subtype_settings);
+ mSwipeDownDismissKeyboardEnabled = res.getBoolean(
+ R.bool.config_swipe_down_dismiss_keyboard_enabled);
+ 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));
+
+ mPopupOn = isPopupEnabled(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);
+ }
+
+ 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);
+ }
+ private static boolean isPopupEnabled(SharedPreferences sp, Resources resources) {
+ final boolean showPopupOption = resources.getBoolean(
+ R.bool.config_enable_show_popup_on_keypress_option);
+ if (!showPopupOption) return resources.getBoolean(R.bool.config_default_popup_preview);
+ return sp.getBoolean(Settings.PREF_POPUP_ON,
+ resources.getBoolean(R.bool.config_default_popup_preview));
+ }
+ 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.build();
+ }
+ }
+
private PreferenceScreen mInputLanguageSelection;
private CheckBoxPreference mQuickFixes;
private ListPreference mVoicePreference;
private ListPreference mSettingsKeyPreference;
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThreshold;
+ // 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,6 +291,7 @@ 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));
}
@Override
@@ -111,16 +311,26 @@ 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(this);
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(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 PreferenceGroup bigramGroup =
+ (PreferenceGroup) findPreference(PREF_NGRAM_SETTINGS_KEY);
final boolean showSettingsKeyOption = getResources().getBoolean(
R.bool.config_enable_show_settings_key_option);
@@ -134,14 +344,14 @@ public class Settings extends PreferenceActivity
generalSettings.removePreference(mVoicePreference);
}
- Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
- if (vibrator == null || !vibrator.hasVibrator()) {
+ if (!VibratorCompatWrapper.getInstance(this).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
+ && !showSubtypeSettings) {
generalSettings.removePreference(findPreference(PREF_SUBTYPES));
}
@@ -167,6 +377,7 @@ public class Settings extends PreferenceActivity
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(
@@ -181,10 +392,10 @@ public class Settings extends PreferenceActivity
super.onResume();
int autoTextSize = AutoText.getSize(getListView());
if (autoTextSize < 1) {
- ((PreferenceGroup) findPreference(PREF_PREDICTION_SETTINGS_KEY))
+ ((PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY))
.removePreference(mQuickFixes);
}
- if (!VoiceIMEConnector.VOICE_INSTALLED
+ if (!VoiceProxy.VOICE_INSTALLED
|| !SpeechRecognizer.isRecognitionAvailable(this)) {
getPreferenceScreen().removePreference(mVoicePreference);
} else {
@@ -222,16 +433,9 @@ public class Settings extends PreferenceActivity
@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(this),
+ getApplicationInfo().packageName), 0));
return true;
}
return false;
@@ -277,10 +481,10 @@ 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();
}
@@ -311,7 +515,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 +525,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 +535,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/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index dc14d770a..d8012087b 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;
@@ -100,9 +104,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 +115,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 +134,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 +149,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 +171,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 +187,10 @@ 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);
+ 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 +209,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 +246,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.
@@ -303,25 +307,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 +386,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;
}
@@ -398,11 +429,7 @@ public class SubtypeSwitcher {
//////////////////////////////////
public int getEnabledKeyboardLocaleCount() {
- if (mConfigUseSpacebarLanguageSwitcher) {
- return mLanguageSwitcher.getLocaleCount();
- } else {
- return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
- }
+ return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
}
public boolean useSpacebarLanguageSwitcher() {
@@ -414,90 +441,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 +484,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,9 +502,14 @@ 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,
+ VoiceProxy.getInstance().startListening(false,
KeyboardSwitcher.getInstance().getInputView().getWindowToken());
}
@@ -535,7 +517,70 @@ public class SubtypeSwitcher {
// 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 = new Locale(mNextKeyboardSubtype.getLocale());
+ mNextLanguage = getDisplayLanguage(locale);
+ mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal(
+ mCurrentKeyboardSubtypeIndex);
+ locale = new Locale(mPreviousKeyboardSubtype.getLocale());
+ mPreviousLanguage = getDisplayLanguage(locale);
+ }
+
+ 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) {
@@ -549,6 +594,10 @@ public class SubtypeSwitcher {
return toTitleCase(locale.getDisplayLanguage(locale));
}
+ public static String getMiddleDisplayLanguage(Locale locale) {
+ return toTitleCase((new Locale(locale.getLanguage()).getDisplayLanguage(locale)));
+ }
+
public static String getShortDisplayLanguage(Locale locale) {
return toTitleCase(locale.getLanguage());
}
@@ -560,32 +609,16 @@ public class SubtypeSwitcher {
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()));
- }
-
public String getInputLanguageName() {
return getDisplayLanguage(getInputLocale());
}
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 +645,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..ca75866c0 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,13 +75,11 @@ 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>();
@@ -92,13 +91,13 @@ public class Suggest implements Dictionary.WordCallback {
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,15 +105,18 @@ 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) {
+ private void init(Context context, Dictionary mainDict) {
if (mainDict != null) {
mMainDict = mainDict;
mUnigramDictionaries.put(DICT_KEY_MAIN, mainDict);
@@ -128,6 +130,19 @@ public class Suggest implements Dictionary.WordCallback {
initPool();
}
+ public void resetMainDict(Context context, int dictionaryResId, Locale locale) {
+ final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager(
+ context, locale, dictionaryResId);
+ mMainDict = newMainDict;
+ if (null == newMainDict) {
+ mUnigramDictionaries.remove(DICT_KEY_MAIN);
+ mBigramDictionaries.remove(DICT_KEY_MAIN);
+ } else {
+ mUnigramDictionaries.put(DICT_KEY_MAIN, newMainDict);
+ mBigramDictionaries.put(DICT_KEY_MAIN, newMainDict);
+ }
+ }
+
private void initPool() {
for (int i = 0; i < mPrefMaxSuggestions; i++) {
StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
@@ -148,7 +163,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() {
@@ -207,8 +222,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());
@@ -248,6 +263,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 +281,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 +308,26 @@ 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);
+ 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,8 +514,8 @@ 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());
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index fe7aac7c2..a8cdfc02e 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -32,14 +32,14 @@ public class SuggestedWords {
public final List<SuggestedWordInfo> mSuggestedWordInfoList;
private SuggestedWords(List<CharSequence> words, boolean typedWordValid,
- boolean hasMinamlSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) {
+ boolean hasMinimalSuggestion, List<SuggestedWordInfo> suggestedWordInfoList) {
if (words != null) {
mWords = words;
} else {
mWords = Collections.emptyList();
}
mTypedWordValid = typedWordValid;
- mHasMinimalSuggestion = hasMinamlSuggestion;
+ mHasMinimalSuggestion = hasMinimalSuggestion;
mSuggestedWordInfoList = suggestedWordInfoList;
}
@@ -113,8 +113,8 @@ public class SuggestedWords {
return this;
}
- public Builder setHasMinimalSuggestion(boolean hasMinamlSuggestion) {
- mHasMinimalSuggestion = hasMinamlSuggestion;
+ public Builder setHasMinimalSuggestion(boolean hasMinimalSuggestion) {
+ mHasMinimalSuggestion = hasMinimalSuggestion;
return this;
}
diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java
index 63196430b..de13f3ae4 100644
--- a/java/src/com/android/inputmethod/latin/TextEntryState.java
+++ b/java/src/com/android/inputmethod/latin/TextEntryState.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.latin.Utils.RingCharBuffer;
+
import android.util.Log;
public class TextEntryState {
@@ -43,10 +45,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,7 +99,7 @@ public class TextEntryState {
if (DEBUG) displayState("onAbortRecorrection");
}
- public static void typedCharacter(char c, boolean isSeparator) {
+ public static void typedCharacter(char c, boolean isSeparator, int x, int y) {
final boolean isSpace = (c == ' ');
switch (sState) {
case IN_WORD:
@@ -149,13 +153,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 4750fb991..a32a6461a 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;
@@ -168,6 +162,10 @@ public class UserBigramDictionary extends ExpandableDictionary {
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/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 727e3f16d..d165de32d 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -16,8 +16,14 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+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;
@@ -28,8 +34,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 java.io.BufferedReader;
import java.io.File;
@@ -40,11 +44,13 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
+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 +107,22 @@ public class Utils {
}
}
- public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm) {
+ public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManagerCompatWrapper imm) {
return imm.getEnabledInputMethodList().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 +213,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 +238,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 +262,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,14 +279,29 @@ 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 +320,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 +330,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 +341,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 +349,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 +529,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;
@@ -503,31 +547,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;
- }
-
- // 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;
@@ -551,7 +570,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() {
@@ -561,4 +582,84 @@ 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;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/WordAlternatives.java b/java/src/com/android/inputmethod/latin/WordAlternatives.java
new file mode 100644
index 000000000..0e9914400
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/WordAlternatives.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.latin;
+
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+
+import android.text.TextUtils;
+
+public class WordAlternatives {
+ public final CharSequence mChosenWord;
+ public final WordComposer mWordComposer;
+
+ public WordAlternatives(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.getInputView(), word, null);
+ }
+} \ No newline at end of file
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 02583895b..cf0592920 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;
@@ -63,6 +63,10 @@ public class WordComposer {
}
WordComposer(WordComposer source) {
+ init(source);
+ }
+
+ public void init(WordComposer source) {
mCodes = new ArrayList<int[]>(source.mCodes);
mPreferredWord = source.mPreferredWord;
mTypedWord = new StringBuilder(source.mTypedWord);