aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/res/color/emoji_tab_label_color_gb.xml33
-rw-r--r--java/res/color/emoji_tab_label_color_ics.xml33
-rw-r--r--java/res/drawable-hdpi/btn_center_default.9.pngbin168 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_center_pressed.9.pngbin194 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_center_selected.9.pngbin194 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.pngbin462 -> 474 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.pngbin435 -> 463 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin547 -> 578 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin587 -> 639 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin553 -> 537 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin668 -> 655 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin707 -> 670 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.pngbin1785 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin1701 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.pngbin468 -> 474 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.pngbin547 -> 517 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.pngbin2389 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.pngbin2409 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.pngbin2211 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.pngbin282 -> 272 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_dark.pngbin1858 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_nature_light_activated.pngbin0 -> 1850 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_nature_light_normal.pngbin0 -> 1800 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_objects_light_activated.pngbin0 -> 1744 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_objects_light_normal.pngbin0 -> 1581 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_people_light_activated.pngbin0 -> 1767 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_people_light_normal.png (renamed from java/res/drawable-hdpi/ic_emoji_light.png)bin1820 -> 1820 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_places_light_activated.pngbin0 -> 1418 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_places_light_normal.pngbin0 -> 1341 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_recent_light_activated.pngbin0 -> 1667 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_recent_light_normal.pngbin0 -> 1703 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_symbols_light_activated.pngbin0 -> 1087 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_symbols_light_normal.pngbin0 -> 1053 bytes
-rw-r--r--java/res/drawable-hdpi/ic_ime_switcher_dark.pngbin0 -> 947 bytes
-rw-r--r--java/res/drawable-hdpi/ic_settings_language.pngbin986 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_keyboard.pngbin812 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_mic_dark.pngbin0 -> 1005 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background.9.pngbin207 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background_gb.9.png (renamed from java/res/drawable-hdpi/keyboard_dark_background.9.png)bin210 -> 210 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.pngbin2080 -> 2138 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.pngbin1990 -> 2105 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin2152 -> 2164 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.pngbin2256 -> 2225 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.pngbin1993 -> 2061 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin2163 -> 2133 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background_gb.9.png (renamed from java/res/drawable-hdpi/keyboard_popup_panel_background.9.png)bin1204 -> 1204 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.pngbin856 -> 874 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip_gb.9.png (renamed from java/res/drawable-hdpi/keyboard_suggest_strip.9.png)bin248 -> 248 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.pngbin160 -> 156 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_delete.pngbin2314 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_label_mic.pngbin905 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_mic.pngbin1410 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_return.pngbin1111 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_search.pngbin1612 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_settings.pngbin729 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_shift.pngbin1474 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_shift_locked.pngbin1115 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_space.pngbin358 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_tab.pngbin1008 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_bkeyboard_voice_off.pngbin1587 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete.pngbin4003 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_holo.pngbin1248 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 1024 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_label_mic.pngbin1417 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_label_mic_holo.pngbin771 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_switch.pngbin1788 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_switch_dark.pngbin0 -> 1773 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic.pngbin3893 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 778 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return.pngbin4024 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return_holo.pngbin1216 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return_holo_dark.pngbin0 -> 1011 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search.pngbin4248 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search_holo.pngbin1607 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search_holo_dark.pngbin0 -> 1220 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings.pngbin4015 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings_holo.pngbin787 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 889 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift.pngbin3740 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_holo.pngbin1290 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 936 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked.pngbin3686 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.pngbin1036 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 730 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_holo.pngbin630 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_holo_dark.pngbin0 -> 593 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_led_gb.9.png (renamed from java/res/drawable-hdpi/sym_keyboard_space_led.9.png)bin557 -> 557 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab.pngbin3792 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab_holo.pngbin1142 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 937 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_holo.pngbin1889 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 1083 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo.pngbin1741 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 941 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwj_holo.pngbin973 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 973 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwnj_holo.pngbin961 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 975 bytes
-rw-r--r--java/res/drawable-hdpi/tab_selected.9.pngbin0 -> 145 bytes
-rw-r--r--java/res/drawable-hdpi/tab_unselected.9.pngbin0 -> 150 bytes
-rw-r--r--java/res/drawable-mdpi/btn_center_default.9.pngbin182 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_center_pressed.9.pngbin200 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_center_selected.9.pngbin200 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.pngbin345 -> 338 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.pngbin334 -> 355 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin407 -> 428 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin411 -> 453 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin394 -> 380 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin505 -> 468 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin489 -> 458 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.pngbin1553 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin1461 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.pngbin332 -> 339 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.pngbin381 -> 368 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.pngbin2389 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.pngbin2409 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.pngbin2212 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.pngbin236 -> 222 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_dark.pngbin1182 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_nature_light_activated.pngbin0 -> 1213 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_nature_light_normal.pngbin0 -> 1130 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_objects_light_activated.pngbin0 -> 1193 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_objects_light_normal.pngbin0 -> 1092 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_people_light_activated.pngbin0 -> 1170 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_people_light_normal.png (renamed from java/res/drawable-mdpi/ic_emoji_light.png)bin1132 -> 1132 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_places_light_activated.pngbin0 -> 1032 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_places_light_normal.pngbin0 -> 963 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_recent_light_activated.pngbin0 -> 1105 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_recent_light_normal.pngbin0 -> 1106 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_symbols_light_activated.pngbin0 -> 805 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_symbols_light_normal.pngbin0 -> 775 bytes
-rw-r--r--java/res/drawable-mdpi/ic_ime_switcher_dark.pngbin0 -> 784 bytes
-rw-r--r--java/res/drawable-mdpi/ic_settings_language.pngbin756 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/ic_subtype_keyboard.pngbin644 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_background.9.pngbin214 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_background_gb.9.png (renamed from java/res/drawable-mdpi/keyboard_dark_background.9.png)bin196 -> 196 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.pngbin1313 -> 1383 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.pngbin1297 -> 1305 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin1437 -> 1425 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.pngbin1457 -> 1454 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.pngbin1288 -> 1314 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin1423 -> 1427 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_popup_panel_background_gb.9.png (renamed from java/res/drawable-mdpi/keyboard_popup_panel_background.9.png)bin1726 -> 1726 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.pngbin571 -> 590 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_suggest_strip_gb.9.png (renamed from java/res/drawable-mdpi/keyboard_suggest_strip.9.png)bin205 -> 205 bytes
-rw-r--r--java/res/drawable-mdpi/suggestions_strip_divider.pngbin264 -> 324 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_delete.pngbin800 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_label_mic.pngbin539 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_mic.pngbin838 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_return.pngbin834 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_search.pngbin1042 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_settings.pngbin729 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_shift.pngbin998 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_shift_locked.pngbin787 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_space.pngbin411 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_tab.pngbin627 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_bkeyboard_voice_off.pngbin1587 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete.pngbin3432 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_holo.pngbin813 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 773 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_label_mic.pngbin542 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_label_mic_holo.pngbin576 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.pngbin0 -> 498 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_switch.pngbin1113 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_switch_dark.pngbin0 -> 1121 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic.pngbin3439 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 590 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic_holo_light.pngbin0 -> 525 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return.pngbin3380 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return_holo.pngbin870 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return_holo_dark.pngbin0 -> 796 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search.pngbin3535 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search_holo.pngbin991 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search_holo_dark.pngbin0 -> 861 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings.pngbin3448 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings_holo.pngbin585 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 708 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift.pngbin3217 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_holo.pngbin940 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 756 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked.pngbin3188 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.pngbin850 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 668 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.pngbin0 -> 897 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_holo.pngbin505 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_holo_dark.pngbin0 -> 505 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_led_gb.9.png (renamed from java/res/drawable-mdpi/sym_keyboard_space_led.9.png)bin365 -> 365 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab.pngbin3269 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab_holo.pngbin801 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 752 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_holo.pngbin1166 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 781 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo.pngbin1105 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 699 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwj_holo.pngbin733 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 746 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwnj_holo.pngbin704 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 721 bytes
-rw-r--r--java/res/drawable-mdpi/tab_selected.9.pngbin0 -> 140 bytes
-rw-r--r--java/res/drawable-mdpi/tab_unselected.9.pngbin0 -> 138 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_center_default.9.pngbin178 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_center_pressed.9.pngbin196 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_center_selected.9.pngbin196 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.pngbin601 -> 603 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.pngbin568 -> 589 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin722 -> 732 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin745 -> 787 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin737 -> 657 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin953 -> 848 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin945 -> 867 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.pngbin1441 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.pngbin1869 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.pngbin591 -> 594 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.pngbin668 -> 634 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.pngbin2833 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.pngbin2867 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.pngbin2658 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin351 -> 323 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_dark.pngbin2631 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_nature_light_activated.pngbin0 -> 2437 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_nature_light_normal.pngbin0 -> 2371 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_objects_light_activated.pngbin0 -> 2319 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_objects_light_normal.pngbin0 -> 2074 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_people_light_activated.pngbin0 -> 2519 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_people_light_normal.png (renamed from java/res/drawable-xhdpi/ic_emoji_light.png)bin2526 -> 2526 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_places_light_activated.pngbin0 -> 1828 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_places_light_normal.pngbin0 -> 1667 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_recent_light_activated.pngbin0 -> 2459 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_recent_light_normal.pngbin0 -> 2346 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.pngbin0 -> 1457 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.pngbin0 -> 1267 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_ime_switcher_dark.pngbin0 -> 1276 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_settings_language.pngbin1267 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_subtype_keyboard.pngbin1056 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_subtype_mic_dark.pngbin0 -> 1259 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_background.9.pngbin222 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_background_gb.9.png (renamed from java/res/drawable-xhdpi/keyboard_dark_background.9.png)bin241 -> 241 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.pngbin2916 -> 3326 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.pngbin2873 -> 3169 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin3176 -> 3374 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.pngbin3184 -> 3525 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.pngbin2818 -> 3218 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin3102 -> 3424 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_popup_panel_background_gb.9.png (renamed from java/res/drawable-xhdpi/keyboard_popup_panel_background.9.png)bin1365 -> 1365 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.pngbin1178 -> 1249 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_suggest_strip_gb.9.png (renamed from java/res/drawable-xhdpi/keyboard_suggest_strip.9.png)bin289 -> 289 bytes
-rw-r--r--java/res/drawable-xhdpi/suggestions_strip_divider.pngbin267 -> 330 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_delete.pngbin2413 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_label_mic.pngbin2112 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_mic.pngbin2090 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_return.pngbin2018 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_search.pngbin2889 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_settings.pngbin2539 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_shift.pngbin2640 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.pngbin2076 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_space.pngbin1072 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_tab.pngbin1544 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_bkeyboard_voice_off.pngbin1137 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete.pngbin4589 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_holo.pngbin1584 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 1318 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_label_mic.pngbin2086 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.pngbin929 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_language_switch.pngbin2512 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.pngbin0 -> 2505 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_mic.pngbin4487 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 942 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return.pngbin4559 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return_holo.pngbin1452 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.pngbin0 -> 1206 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search.pngbin4990 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search_holo.pngbin2070 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.pngbin0 -> 1576 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings.pngbin4639 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings_holo.pngbin1062 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 1309 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift.pngbin4186 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_holo.pngbin1592 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 1090 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked.pngbin4119 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.pngbin1295 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 860 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.pngbin0 -> 1851 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_holo.pngbin675 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.pngbin0 -> 646 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_led_gb.9.png (renamed from java/res/drawable-xhdpi/sym_keyboard_space_led.9.png)bin617 -> 617 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab.pngbin4157 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab_holo.pngbin1336 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 1179 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_holo.pngbin2393 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 1421 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.pngbin2196 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 1248 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwj_holo.pngbin1185 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 1184 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.pngbin1148 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 1171 bytes
-rw-r--r--java/res/drawable-xhdpi/tab_selected.9.pngbin0 -> 148 bytes
-rw-r--r--java/res/drawable-xhdpi/tab_unselected.9.pngbin0 -> 155 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.pngbin1805 -> 1803 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.pngbin1693 -> 1718 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin1913 -> 1905 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin2039 -> 1998 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin1863 -> 1861 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin2196 -> 2073 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin2210 -> 2091 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.pngbin1775 -> 1787 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.pngbin1840 -> 1799 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin1293 -> 1261 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.pngbin0 -> 3150 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.pngbin0 -> 2999 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.pngbin0 -> 2831 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.pngbin0 -> 2656 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_people_light_activated.pngbin0 -> 3118 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_people_light_normal.pngbin0 -> 3097 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_places_light_activated.pngbin0 -> 2256 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_places_light_normal.pngbin0 -> 2169 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.pngbin0 -> 3152 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.pngbin0 -> 2943 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.pngbin0 -> 1939 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.pngbin0 -> 1784 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_ime_switcher_dark.pngbin0 -> 1309 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_subtype_keyboard.pngbin1218 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_subtype_mic_dark.pngbin0 -> 1846 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.pngbin5212 -> 7452 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.pngbin4941 -> 7089 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin5188 -> 7197 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.pngbin5373 -> 5450 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.pngbin4964 -> 7023 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin5118 -> 7153 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.pngbin2712 -> 2722 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_delete_holo.pngbin2860 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 1729 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.pngbin615 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_language_switch.pngbin3031 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.pngbin0 -> 3251 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 1566 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_return_holo.pngbin2788 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.pngbin0 -> 1717 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_search_holo.pngbin4210 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.pngbin0 -> 2208 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_settings_holo.pngbin1455 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 1471 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_holo.pngbin2855 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 1427 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.pngbin2346 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 1367 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.pngbin0 -> 2571 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_space_holo.pngbin1499 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.pngbin0 -> 1186 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_tab_holo.pngbin2671 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 1577 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_holo.pngbin3102 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 1907 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.pngbin2749 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 1791 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.pngbin1436 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 1589 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.pngbin1452 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 1591 bytes
-rw-r--r--java/res/drawable-xxhdpi/tab_selected.9.pngbin0 -> 1030 bytes
-rw-r--r--java/res/drawable-xxhdpi/tab_unselected.9.pngbin0 -> 1048 bytes
-rw-r--r--java/res/drawable/btn_keyboard_key.xml38
-rw-r--r--java/res/drawable/btn_keyboard_key3.xml36
-rw-r--r--java/res/drawable/btn_keyboard_key_functional_gb.xml22
-rw-r--r--java/res/drawable/btn_keyboard_key_functional_ics.xml22
-rw-r--r--java/res/drawable/btn_keyboard_key_gb.xml (renamed from java/res/drawable/btn_keyboard_key_gingerbread.xml)9
-rw-r--r--java/res/drawable/btn_keyboard_key_ics.xml9
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_gb.xml (renamed from java/res/drawable/btn_keyboard_key_popup.xml)0
-rw-r--r--java/res/drawable/btn_keyboard_key_stone.xml50
-rw-r--r--java/res/drawable/btn_suggestion_gb.xml (renamed from java/res/drawable/btn_suggestion.xml)0
-rw-r--r--java/res/drawable/ic_emoji_nature_light.xml (renamed from java/res/drawable/btn_center.xml)23
-rw-r--r--java/res/drawable/ic_emoji_objects_light.xml32
-rw-r--r--java/res/drawable/ic_emoji_people_light.xml32
-rw-r--r--java/res/drawable/ic_emoji_places_light.xml32
-rw-r--r--java/res/drawable/ic_emoji_recent_light.xml32
-rw-r--r--java/res/drawable/ic_emoji_symbols_light.xml32
-rw-r--r--java/res/drawable/keyboard_key_feedback_gb.xml (renamed from java/res/drawable/keyboard_key_feedback.xml)0
-rw-r--r--java/res/layout/emoji_keyboard_page.xml33
-rw-r--r--java/res/layout/emoji_keyboard_tab_icon.xml (renamed from java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml)14
-rw-r--r--java/res/layout/emoji_keyboard_tab_label.xml (renamed from java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml)14
-rw-r--r--java/res/layout/emoji_keyboard_view.xml110
-rw-r--r--java/res/layout/hint_add_to_dictionary.xml2
-rw-r--r--java/res/layout/input_view.xml49
-rw-r--r--java/res/layout/key_preview_gb.xml (renamed from java/res/layout/key_preview.xml)2
-rw-r--r--java/res/layout/more_keys_keyboard.xml22
-rw-r--r--java/res/layout/more_suggestions.xml28
-rw-r--r--java/res/layout/suggestion_info.xml2
-rw-r--r--java/res/layout/suggestion_word.xml2
-rw-r--r--java/res/raw/main_fr.dictbin1329175 -> 1329179 bytes
-rw-r--r--java/res/raw/main_pt_br.dictbin1091988 -> 1091987 bytes
-rw-r--r--java/res/raw/main_ru.dictbin2229294 -> 2229294 bytes
-rw-r--r--java/res/values-af/strings.xml20
-rw-r--r--java/res/values-am/strings.xml20
-rw-r--r--java/res/values-ar/strings.xml20
-rw-r--r--java/res/values-be/strings.xml31
-rw-r--r--java/res/values-bg/strings.xml20
-rw-r--r--java/res/values-ca/strings.xml20
-rw-r--r--java/res/values-cs/strings.xml20
-rw-r--r--java/res/values-da/strings.xml20
-rw-r--r--java/res/values-de/strings.xml20
-rw-r--r--java/res/values-el/strings.xml20
-rw-r--r--java/res/values-en-rGB/strings.xml34
-rw-r--r--java/res/values-es-rUS/strings.xml20
-rw-r--r--java/res/values-es/strings.xml20
-rw-r--r--java/res/values-et-rEE/strings.xml244
-rw-r--r--java/res/values-et/strings.xml18
-rw-r--r--java/res/values-fa/strings.xml24
-rw-r--r--java/res/values-fi/strings.xml104
-rw-r--r--java/res/values-fr-rCA/donottranslate.xml31
-rw-r--r--java/res/values-fr/strings.xml20
-rw-r--r--java/res/values-hi/strings.xml68
-rw-r--r--java/res/values-hr/strings.xml20
-rw-r--r--java/res/values-hu/strings.xml20
-rw-r--r--java/res/values-hy/donottranslate.xml29
-rw-r--r--java/res/values-in/strings.xml20
-rw-r--r--java/res/values-it/strings.xml20
-rw-r--r--java/res/values-iw/strings.xml56
-rw-r--r--java/res/values-ja/strings.xml20
-rw-r--r--java/res/values-ka-rGE/strings.xml244
-rw-r--r--java/res/values-ka/strings-appname.xml27
-rw-r--r--java/res/values-ka/strings.xml18
-rw-r--r--java/res/values-km/donottranslate.xml23
-rw-r--r--java/res/values-ko/strings.xml20
-rw-r--r--java/res/values-land/dimens.xml21
-rw-r--r--java/res/values-lo/donottranslate.xml23
-rw-r--r--java/res/values-lt/strings.xml20
-rw-r--r--java/res/values-lv/strings.xml20
-rw-r--r--java/res/values-mn-rMN/strings.xml244
-rw-r--r--java/res/values-mn/strings.xml18
-rw-r--r--java/res/values-ms-rMY/strings.xml244
-rw-r--r--java/res/values-ms/strings.xml18
-rw-r--r--java/res/values-nb/strings.xml20
-rw-r--r--java/res/values-nl/strings.xml20
-rw-r--r--java/res/values-pl/strings.xml20
-rw-r--r--java/res/values-pt-rPT/strings.xml22
-rw-r--r--java/res/values-pt/strings.xml22
-rw-r--r--java/res/values-rm/strings.xml22
-rw-r--r--java/res/values-ro/strings.xml34
-rw-r--r--java/res/values-ru/strings.xml20
-rw-r--r--java/res/values-sk/strings.xml20
-rw-r--r--java/res/values-sl/strings.xml20
-rw-r--r--java/res/values-sr/strings.xml20
-rw-r--r--java/res/values-sv/strings.xml20
-rw-r--r--java/res/values-sw/strings.xml20
-rw-r--r--java/res/values-sw600dp-land/dimens.xml20
-rw-r--r--java/res/values-sw600dp/config.xml2
-rw-r--r--java/res/values-sw600dp/dimens.xml24
-rw-r--r--java/res/values-sw600dp/touch-position-correction.xml4
-rw-r--r--java/res/values-sw768dp-land/dimens.xml18
-rw-r--r--java/res/values-sw768dp/config.xml2
-rw-r--r--java/res/values-sw768dp/dimens.xml23
-rw-r--r--java/res/values-th/donottranslate.xml23
-rw-r--r--java/res/values-th/strings.xml20
-rw-r--r--java/res/values-tl/strings.xml20
-rw-r--r--java/res/values-tr/strings.xml20
-rw-r--r--java/res/values-uk/strings.xml20
-rw-r--r--java/res/values-v18/emoji-categories.xml909
-rw-r--r--java/res/values-v19/emoji-categories.xml909
-rw-r--r--java/res/values-vi/strings.xml20
-rw-r--r--java/res/values-zh-rCN/strings.xml22
-rw-r--r--java/res/values-zh-rTW/strings.xml54
-rw-r--r--java/res/values-zu/strings.xml20
-rw-r--r--java/res/values/attrs.xml81
-rw-r--r--java/res/values/colors.xml87
-rw-r--r--java/res/values/config-additional-features.xml24
-rw-r--r--java/res/values/config.xml2
-rw-r--r--java/res/values/dimens.xml28
-rw-r--r--java/res/values/donottranslate.xml60
-rw-r--r--java/res/values/emoji-categories.xml127
-rw-r--r--java/res/values/keyboard-icons-black.xml44
-rw-r--r--java/res/values/keyboard-icons-ics.xml41
-rw-r--r--java/res/values/keyboard-icons-white.xml40
-rw-r--r--java/res/values/keypress-vibration-durations.xml4
-rw-r--r--java/res/values/setup-styles.xml30
-rw-r--r--java/res/values/strings.xml6
-rw-r--r--java/res/values/styles.xml415
-rw-r--r--java/res/values/themes-basic-highcontrast.xml29
-rw-r--r--java/res/values/themes-basic.xml29
-rw-r--r--java/res/values/themes-common.xml131
-rw-r--r--java/res/values/themes-gb.xml146
-rw-r--r--java/res/values/themes-gingerbread.xml29
-rw-r--r--java/res/values/themes-ics.xml166
-rw-r--r--java/res/values/themes-stone-bold.xml29
-rw-r--r--java/res/values/themes-stone.xml29
-rw-r--r--java/res/values/touch-position-correction.xml4
-rw-r--r--java/res/xml-sw600dp/key_apostrophe.xml49
-rw-r--r--java/res/xml-sw600dp/key_dash.xml49
-rw-r--r--java/res/xml-sw600dp/key_f1.xml5
-rw-r--r--java/res/xml-sw600dp/key_f2.xml45
-rw-r--r--java/res/xml-sw600dp/key_space_5kw.xml (renamed from java/res/xml-sw600dp/key_space.xml)0
-rw-r--r--java/res/xml-sw600dp/key_space_symbols.xml (renamed from java/res/xml/kbd_10_10_7_symbols.xml)7
-rw-r--r--java/res/xml-sw600dp/key_styles_common.xml3
-rw-r--r--java/res/xml-sw600dp/keys_comma_period.xml46
-rw-r--r--java/res/xml-sw600dp/keys_exclamation_question.xml28
-rw-r--r--java/res/xml-sw600dp/keys_pcqwerty2_right3.xml32
-rw-r--r--java/res/xml-sw600dp/keys_pcqwerty3_right2.xml23
-rw-r--r--java/res/xml-sw600dp/keys_pcqwerty4_right3.xml44
-rw-r--r--java/res/xml-sw600dp/row_dvorak4.xml9
-rw-r--r--java/res/xml-sw600dp/row_hebrew4.xml44
-rw-r--r--java/res/xml-sw600dp/row_pcqwerty5.xml22
-rw-r--r--java/res/xml-sw600dp/row_qwerty4.xml6
-rw-r--r--java/res/xml-sw600dp/row_symbols4.xml48
-rw-r--r--java/res/xml-sw600dp/row_symbols_shift4.xml40
-rw-r--r--java/res/xml-sw600dp/rowkeys_pcqwerty1.xml172
-rw-r--r--java/res/xml-sw600dp/rowkeys_symbols2.xml75
-rw-r--r--java/res/xml-sw600dp/rowkeys_symbols3.xml57
-rw-r--r--java/res/xml-sw600dp/rowkeys_symbols_shift1.xml56
-rw-r--r--java/res/xml-sw600dp/rowkeys_symbols_shift2.xml52
-rw-r--r--java/res/xml-sw600dp/rowkeys_symbols_shift3.xml46
-rw-r--r--java/res/xml-sw600dp/rows_10_10_7_symbols_shift.xml60
-rw-r--r--java/res/xml-sw600dp/rows_armenian_phonetic.xml (renamed from java/res/xml-sw768dp/rows_colemak.xml)38
-rw-r--r--java/res/xml-sw600dp/rows_azerty.xml2
-rw-r--r--java/res/xml-sw600dp/rows_bulgarian.xml2
-rw-r--r--java/res/xml-sw600dp/rows_bulgarian_bds.xml2
-rw-r--r--java/res/xml-sw600dp/rows_colemak.xml2
-rw-r--r--java/res/xml-sw600dp/rows_east_slavic.xml2
-rw-r--r--java/res/xml-sw600dp/rows_georgian.xml2
-rw-r--r--java/res/xml-sw600dp/rows_greek.xml2
-rw-r--r--java/res/xml-sw600dp/rows_hebrew.xml2
-rw-r--r--java/res/xml-sw600dp/rows_hindi.xml2
-rw-r--r--java/res/xml-sw600dp/rows_khmer.xml (renamed from java/res/xml-sw768dp/rows_azerty.xml)46
-rw-r--r--java/res/xml-sw600dp/rows_lao.xml (renamed from java/res/xml-sw768dp/rows_georgian.xml)48
-rw-r--r--java/res/xml-sw600dp/rows_mongolian.xml2
-rw-r--r--java/res/xml-sw600dp/rows_nepali_romanized.xml (renamed from java/res/xml-sw600dp/rows_10_10_7_symbols.xml)25
-rw-r--r--java/res/xml-sw600dp/rows_nepali_traditional.xml (renamed from java/res/xml-sw768dp/rows_farsi.xml)30
-rw-r--r--java/res/xml-sw600dp/rows_nordic.xml2
-rw-r--r--java/res/xml-sw600dp/rows_pcqwerty.xml19
-rw-r--r--java/res/xml-sw600dp/rows_qwerty.xml2
-rw-r--r--java/res/xml-sw600dp/rows_qwertz.xml2
-rw-r--r--java/res/xml-sw600dp/rows_south_slavic.xml2
-rw-r--r--java/res/xml-sw600dp/rows_spanish.xml2
-rw-r--r--java/res/xml-sw600dp/rows_symbols.xml15
-rw-r--r--java/res/xml-sw600dp/rows_symbols_shift.xml17
-rw-r--r--java/res/xml-sw600dp/rows_thai.xml13
-rw-r--r--java/res/xml-sw768dp-land/kbd_phone_symbols.xml31
-rw-r--r--java/res/xml-sw768dp/kbd_number.xml28
-rw-r--r--java/res/xml-sw768dp/kbd_phone.xml28
-rw-r--r--java/res/xml-sw768dp/kbd_phone_symbols.xml29
-rw-r--r--java/res/xml-sw768dp/key_space.xml63
-rw-r--r--java/res/xml-sw768dp/key_styles_common.xml186
-rw-r--r--java/res/xml-sw768dp/row_dvorak4.xml51
-rw-r--r--java/res/xml-sw768dp/row_hebrew4.xml49
-rw-r--r--java/res/xml-sw768dp/row_pcqwerty5.xml59
-rw-r--r--java/res/xml-sw768dp/row_qwerty4.xml51
-rw-r--r--java/res/xml-sw768dp/row_symbols4.xml48
-rw-r--r--java/res/xml-sw768dp/row_symbols_shift4.xml38
-rw-r--r--java/res/xml-sw768dp/rows_10_10_7_symbols.xml69
-rw-r--r--java/res/xml-sw768dp/rows_10_10_7_symbols_shift.xml69
-rw-r--r--java/res/xml-sw768dp/rows_bulgarian.xml68
-rw-r--r--java/res/xml-sw768dp/rows_bulgarian_bds.xml68
-rw-r--r--java/res/xml-sw768dp/rows_dvorak.xml66
-rw-r--r--java/res/xml-sw768dp/rows_east_slavic.xml70
-rw-r--r--java/res/xml-sw768dp/rows_greek.xml70
-rw-r--r--java/res/xml-sw768dp/rows_hebrew.xml61
-rw-r--r--java/res/xml-sw768dp/rows_hindi.xml68
-rw-r--r--java/res/xml-sw768dp/rows_mongolian.xml68
-rw-r--r--java/res/xml-sw768dp/rows_nordic.xml71
-rw-r--r--java/res/xml-sw768dp/rows_number_normal.xml175
-rw-r--r--java/res/xml-sw768dp/rows_number_password.xml79
-rw-r--r--java/res/xml-sw768dp/rows_pcqwerty.xml71
-rw-r--r--java/res/xml-sw768dp/rows_pcqwerty_symbols.xml67
-rw-r--r--java/res/xml-sw768dp/rows_phone.xml138
-rw-r--r--java/res/xml-sw768dp/rows_qwerty.xml68
-rw-r--r--java/res/xml-sw768dp/rows_qwertz.xml68
-rw-r--r--java/res/xml-sw768dp/rows_south_slavic.xml68
-rw-r--r--java/res/xml-sw768dp/rows_spanish.xml69
-rw-r--r--java/res/xml-sw768dp/rows_symbols.xml68
-rw-r--r--java/res/xml-sw768dp/rows_symbols_shift.xml68
-rw-r--r--java/res/xml-sw768dp/rows_thai.xml74
-rw-r--r--java/res/xml-sw768dp/rows_thai_symbols.xml76
-rw-r--r--java/res/xml-sw768dp/rows_thai_symbols_shift.xml76
-rw-r--r--java/res/xml-v16/key_devanagari_sign_anusvara.xml (renamed from java/res/xml-v16/key_hindi3_shift_left.xml)10
-rw-r--r--java/res/xml-v16/key_devanagari_sign_candrabindu.xml48
-rw-r--r--java/res/xml-v16/key_devanagari_sign_nukta.xml (renamed from java/res/xml-v16/key_hindi3_right.xml)27
-rw-r--r--java/res/xml-v16/key_devanagari_vowel_sign_candra_o.xml (renamed from java/res/xml-v16/keys_hindi3_left2.xml)8
-rw-r--r--java/res/xml-v16/key_devanagari_vowel_sign_vocalic_r.xml55
-rw-r--r--java/res/xml-v16/keys_hindi1_left5.xml75
-rw-r--r--java/res/xml-v16/keys_hindi2_left5.xml59
-rw-r--r--java/res/xml-v16/keystyle_devanagari_sign_virama.xml (renamed from java/res/xml-v16/key_hindi3_shift_right.xml)13
-rw-r--r--java/res/xml-v16/keystyle_devanagari_sign_visarga.xml (renamed from java/res/xml-v16/key_hindi1_shift.xml)7
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml49
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml56
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml48
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml57
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml48
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml48
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml50
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml49
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml49
-rw-r--r--java/res/xml/kbd_armenian_phonetic.xml (renamed from java/res/xml-sw768dp/kbd_thai_symbols_shift.xml)4
-rw-r--r--java/res/xml/kbd_emoji_category1.xml (renamed from java/res/xml-sw600dp/kbd_10_10_7_symbols.xml)12
-rw-r--r--java/res/xml/kbd_emoji_category2.xml (renamed from java/res/xml-sw600dp/kbd_10_10_7_symbols_shift.xml)12
-rw-r--r--java/res/xml/kbd_emoji_category3.xml (renamed from java/res/xml-sw768dp-land/kbd_number.xml)15
-rw-r--r--java/res/xml/kbd_emoji_category4.xml (renamed from java/res/xml-sw768dp-land/kbd_phone.xml)15
-rw-r--r--java/res/xml/kbd_emoji_category5.xml31
-rw-r--r--java/res/xml/kbd_emoji_category6.xml32
-rw-r--r--java/res/xml/kbd_emoji_recents.xml32
-rw-r--r--java/res/xml/kbd_khmer.xml (renamed from java/res/xml-sw768dp/kbd_thai_symbols.xml)4
-rw-r--r--java/res/xml/kbd_lao.xml (renamed from java/res/xml/kbd_pcqwerty_symbols.xml)4
-rw-r--r--java/res/xml/kbd_nepali_romanized.xml (renamed from java/res/xml/kbd_thai_symbols_shift.xml)5
-rw-r--r--java/res/xml/kbd_nepali_traditional.xml (renamed from java/res/xml/kbd_10_10_7_symbols_shift.xml)5
-rw-r--r--java/res/xml/key_armenian_sha.xml28
-rw-r--r--java/res/xml/key_armenian_xeh.xml28
-rw-r--r--java/res/xml/key_devanagari_sign_anusvara.xml (renamed from java/res/xml/key_hindi3_shift_left.xml)12
-rw-r--r--java/res/xml/key_devanagari_sign_candrabindu.xml (renamed from java/res/xml/key_hindi3_right.xml)30
-rw-r--r--java/res/xml/key_devanagari_sign_nukta.xml52
-rw-r--r--java/res/xml/key_devanagari_vowel_sign_candra_o.xml (renamed from java/res/xml/keys_hindi3_left2.xml)10
-rw-r--r--java/res/xml/key_devanagari_vowel_sign_vocalic_r.xml58
-rw-r--r--java/res/xml/key_f2.xml (renamed from java/res/xml-sw768dp/key_shortcut.xml)10
-rw-r--r--java/res/xml/key_nepali_traditional_period.xml49
-rw-r--r--java/res/xml/key_space_3kw.xml (renamed from java/res/xml-sw768dp/key_settings.xml)14
-rw-r--r--java/res/xml/key_space_5kw.xml (renamed from java/res/xml/key_space.xml)4
-rw-r--r--java/res/xml/key_space_symbols.xml (renamed from java/res/xml/kbd_thai_symbols.xml)7
-rw-r--r--java/res/xml/key_styles_common.xml48
-rw-r--r--java/res/xml/key_styles_currency.xml10
-rw-r--r--java/res/xml/key_symbols_period.xml47
-rw-r--r--java/res/xml/keyboard_layout_set_armenian_phonetic.xml42
-rw-r--r--java/res/xml/keyboard_layout_set_azerty.xml4
-rw-r--r--java/res/xml/keyboard_layout_set_colemak.xml4
-rw-r--r--java/res/xml/keyboard_layout_set_dvorak.xml4
-rw-r--r--java/res/xml/keyboard_layout_set_emoji.xml44
-rw-r--r--java/res/xml/keyboard_layout_set_hebrew.xml4
-rw-r--r--java/res/xml/keyboard_layout_set_khmer.xml58
-rw-r--r--java/res/xml/keyboard_layout_set_lao.xml58
-rw-r--r--java/res/xml/keyboard_layout_set_nepali_romanized.xml58
-rw-r--r--java/res/xml/keyboard_layout_set_nepali_traditional.xml58
-rw-r--r--java/res/xml/keyboard_layout_set_pcqwerty.xml6
-rw-r--r--java/res/xml/keyboard_layout_set_spanish.xml4
-rw-r--r--java/res/xml/keyboard_layout_set_thai.xml4
-rw-r--r--java/res/xml/keys_comma_period.xml103
-rw-r--r--java/res/xml/keys_hindi1_left5.xml85
-rw-r--r--java/res/xml/keys_hindi2_left5.xml69
-rw-r--r--java/res/xml/keys_less_greater.xml4
-rw-r--r--java/res/xml/keys_pcqwerty2_right3.xml13
-rw-r--r--java/res/xml/keys_pcqwerty3_right2.xml7
-rw-r--r--java/res/xml/keys_pcqwerty4_right3.xml13
-rw-r--r--java/res/xml/keys_pcqwerty_symbols2.xml59
-rw-r--r--java/res/xml/keys_pcqwerty_symbols3.xml54
-rw-r--r--java/res/xml/keys_pcqwerty_symbols4.xml49
-rw-r--r--java/res/xml/keystyle_devanagari_sign_virama.xml (renamed from java/res/xml/key_hindi3_shift_right.xml)17
-rw-r--r--java/res/xml/keystyle_devanagari_sign_visarga.xml (renamed from java/res/xml/key_hindi1_shift.xml)7
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_aa.xml52
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_ai.xml59
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_au.xml50
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_e.xml59
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_i.xml51
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_ii.xml51
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_o.xml53
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_u.xml52
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_uu.xml52
-rw-r--r--java/res/xml/method.xml295
-rw-r--r--java/res/xml/prefs.xml8
-rw-r--r--java/res/xml/row_dvorak4.xml2
-rw-r--r--java/res/xml/row_pcqwerty5.xml55
-rw-r--r--java/res/xml/row_qwerty4.xml17
-rw-r--r--java/res/xml/row_symbols4.xml59
-rw-r--r--java/res/xml/row_symbols_shift4.xml35
-rw-r--r--java/res/xml/rowkeys_armenian_phonetic1.xml84
-rw-r--r--java/res/xml/rowkeys_armenian_phonetic2.xml66
-rw-r--r--java/res/xml/rowkeys_armenian_phonetic3.xml (renamed from java/res/xml-sw768dp/rowkeys_thai_digits.xml)42
-rw-r--r--java/res/xml/rowkeys_armenian_phonetic4.xml52
-rw-r--r--java/res/xml/rowkeys_hindi1.xml60
-rw-r--r--java/res/xml/rowkeys_hindi2.xml36
-rw-r--r--java/res/xml/rowkeys_hindi3.xml26
-rw-r--r--java/res/xml/rowkeys_khmer1.xml194
-rw-r--r--java/res/xml/rowkeys_khmer2.xml144
-rw-r--r--java/res/xml/rowkeys_khmer3.xml138
-rw-r--r--java/res/xml/rowkeys_khmer4.xml113
-rw-r--r--java/res/xml/rowkeys_lao1.xml164
-rw-r--r--java/res/xml/rowkeys_lao2.xml127
-rw-r--r--java/res/xml/rowkeys_lao3.xml110
-rw-r--r--java/res/xml/rowkeys_lao4.xml103
-rw-r--r--java/res/xml/rowkeys_nepali_romanized1.xml177
-rw-r--r--java/res/xml/rowkeys_nepali_romanized2.xml126
-rw-r--r--java/res/xml/rowkeys_nepali_romanized3.xml114
-rw-r--r--java/res/xml/rowkeys_nepali_traditional1.xml175
-rw-r--r--java/res/xml/rowkeys_nepali_traditional2.xml139
-rw-r--r--java/res/xml/rowkeys_nepali_traditional3_left6.xml83
-rw-r--r--java/res/xml/rowkeys_nepali_traditional3_right3.xml65
-rw-r--r--java/res/xml/rowkeys_nepali_traditional3_right5.xml91
-rw-r--r--java/res/xml/rowkeys_pcqwerty1.xml120
-rw-r--r--java/res/xml/rowkeys_pcqwerty1_shift.xml (renamed from java/res/xml/keys_pcqwerty_symbols1.xml)25
-rw-r--r--java/res/xml/rowkeys_pcqwerty2.xml20
-rw-r--r--java/res/xml/rowkeys_pcqwerty3.xml18
-rw-r--r--java/res/xml/rowkeys_pcqwerty4.xml18
-rw-r--r--java/res/xml/rowkeys_symbols2.xml3
-rw-r--r--java/res/xml/rowkeys_symbols3.xml9
-rw-r--r--java/res/xml/rowkeys_symbols_shift1.xml18
-rw-r--r--java/res/xml/rowkeys_symbols_shift2.xml16
-rw-r--r--java/res/xml/rowkeys_symbols_shift3.xml20
-rw-r--r--java/res/xml/rows_armenian_phonetic.xml (renamed from java/res/xml-sw600dp/rows_pcqwerty_symbols.xml)43
-rw-r--r--java/res/xml/rows_khmer.xml56
-rw-r--r--java/res/xml/rows_lao.xml56
-rw-r--r--java/res/xml/rows_nepali_romanized.xml (renamed from java/res/xml-sw768dp/rows_arabic.xml)35
-rw-r--r--java/res/xml/rows_nepali_traditional.xml (renamed from java/res/xml/rows_pcqwerty_symbols.xml)32
-rw-r--r--java/res/xml/rows_pcqwerty.xml15
-rw-r--r--java/res/xml/rows_symbols.xml14
-rw-r--r--java/res/xml/rows_symbols_shift.xml12
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java12
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java18
-rw-r--r--java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java46
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java67
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java766
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java90
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java164
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java7
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java54
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java14
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java17
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java55
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java58
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java53
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java11
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java50
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java34
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/CodesArrayParser.java85
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java223
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java25
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java352
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java137
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java28
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java264
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java212
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ScrollViewWithNotifier.java66
-rw-r--r--java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java24
-rw-r--r--java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java12
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java105
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java36
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java16
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java31
-rw-r--r--java/src/com/android/inputmethod/latin/DicTraverseSession.java10
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java67
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryCollection.java6
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryWriter.java15
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java618
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java147
-rw-r--r--java/src/com/android/inputmethod/latin/InputPointers.java11
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java760
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java73
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java30
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java88
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java62
-rw-r--r--java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java40
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java4
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java624
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java936
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java869
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java1838
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictDecoder.java394
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictEncoder.java38
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java502
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java256
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java357
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java (renamed from java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java)6
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java234
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java255
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java259
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java269
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java183
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java335
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java32
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegister.java37
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java74
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java (renamed from java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java)53
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java9
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java3
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java55
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java24
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java100
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java14
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java2
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java3
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java2
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java24
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java8
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AsyncResultHolder.java71
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ByteArrayDictBuffer.java (renamed from java/src/com/android/inputmethod/latin/utils/ByteArrayWrapper.java)6
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java11
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CollectionUtils.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java6
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java10
-rw-r--r--java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java108
-rw-r--r--java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java147
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java9
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java247
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java1
-rw-r--r--java/src/com/android/inputmethod/latin/utils/TextRange.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java47
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java12
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java4
-rw-r--r--java/src/com/android/inputmethod/research/JsonUtils.java12
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java2
806 files changed, 19445 insertions, 10753 deletions
diff --git a/java/res/color/emoji_tab_label_color_gb.xml b/java/res/color/emoji_tab_label_color_gb.xml
new file mode 100644
index 000000000..e1d2f715e
--- /dev/null
+++ b/java/res/color/emoji_tab_label_color_gb.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:color="@color/key_text_color_gb" />
+ <item
+ android:state_pressed="true"
+ android:color="@color/key_text_color_gb" />
+ <item
+ android:state_selected="true"
+ android:color="@color/key_text_color_gb" />
+ <item
+ android:color="@color/key_text_inactivated_color_gb" />
+</selector>
diff --git a/java/res/color/emoji_tab_label_color_ics.xml b/java/res/color/emoji_tab_label_color_ics.xml
new file mode 100644
index 000000000..36e1d3020
--- /dev/null
+++ b/java/res/color/emoji_tab_label_color_ics.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:color="@color/key_text_color_ics" />
+ <item
+ android:state_pressed="true"
+ android:color="@color/key_text_color_ics" />
+ <item
+ android:state_selected="true"
+ android:color="@color/key_text_color_ics" />
+ <item
+ android:color="@color/key_text_inactivated_color_ics" />
+</selector>
diff --git a/java/res/drawable-hdpi/btn_center_default.9.png b/java/res/drawable-hdpi/btn_center_default.9.png
deleted file mode 100644
index 4f5f01cb8..000000000
--- a/java/res/drawable-hdpi/btn_center_default.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_center_pressed.9.png b/java/res/drawable-hdpi/btn_center_pressed.9.png
deleted file mode 100644
index 213b482d4..000000000
--- a/java/res/drawable-hdpi/btn_center_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_center_selected.9.png b/java/res/drawable-hdpi/btn_center_selected.9.png
deleted file mode 100644
index 213b482d4..000000000
--- a/java/res/drawable-hdpi/btn_center_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
index 9aa8db60e..87211a502 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
index 5e6a9d6a4..fa2cb8542 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index a3ba2230d..b1af23b6c 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index 9f4587b4a..814e40235 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 7ec33dd20..90abe3940 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 655bc01b1..48eeb3f54 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 138e915d9..71e0683cd 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
deleted file mode 100644
index 116329016..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png
+++ /dev/null
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
deleted file mode 100644
index 207c90d6c..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
index baff85873..6da273b09 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
index 5612c51a1..6768241a7 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
deleted file mode 100644
index cdd6c8b79..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png
+++ /dev/null
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
deleted file mode 100644
index d8421746a..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png
+++ /dev/null
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
deleted file mode 100644
index 671d4e5d6..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
index c2e8b3779..10f8e97e4 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_dark.png b/java/res/drawable-hdpi/ic_emoji_dark.png
deleted file mode 100644
index a9f18cde0..000000000
--- a/java/res/drawable-hdpi/ic_emoji_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png
new file mode 100644
index 000000000..5525df2f7
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png
new file mode 100644
index 000000000..34e16b9de
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png
new file mode 100644
index 000000000..c3c7ec1b8
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png
new file mode 100644
index 000000000..f012d7707
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_people_light_activated.png b/java/res/drawable-hdpi/ic_emoji_people_light_activated.png
new file mode 100644
index 000000000..cfacbc2e7
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_people_light_activated.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_light.png b/java/res/drawable-hdpi/ic_emoji_people_light_normal.png
index 2e3638bf3..c54dbc1f5 100644
--- a/java/res/drawable-hdpi/ic_emoji_light.png
+++ b/java/res/drawable-hdpi/ic_emoji_people_light_normal.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_places_light_activated.png b/java/res/drawable-hdpi/ic_emoji_places_light_activated.png
new file mode 100644
index 000000000..959dfdfd5
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_places_light_activated.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_places_light_normal.png b/java/res/drawable-hdpi/ic_emoji_places_light_normal.png
new file mode 100644
index 000000000..fc0d9711d
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_places_light_normal.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png
new file mode 100644
index 000000000..de570a185
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png
new file mode 100644
index 000000000..b2562088d
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png
new file mode 100644
index 000000000..af1fd27ec
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png
new file mode 100644
index 000000000..02b84d51b
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_ime_switcher_dark.png b/java/res/drawable-hdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..7506af5a3
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_settings_language.png b/java/res/drawable-hdpi/ic_settings_language.png
deleted file mode 100644
index f635b2e7a..000000000
--- a/java/res/drawable-hdpi/ic_settings_language.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png
deleted file mode 100644
index 484305655..000000000
--- a/java/res/drawable-hdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_mic_dark.png b/java/res/drawable-hdpi/ic_subtype_mic_dark.png
new file mode 100644
index 000000000..eacbcd255
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_subtype_mic_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background.9.png
deleted file mode 100644
index d57463fb6..000000000
--- a/java/res/drawable-hdpi/keyboard_background.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_dark_background.9.png b/java/res/drawable-hdpi/keyboard_background_gb.9.png
index fa3d449f7..fa3d449f7 100644
--- a/java/res/drawable-hdpi/keyboard_dark_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_background_gb.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 28b406a5c..50ed568ff 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
index e42cd88dc..9fa6d0003 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
index 160344073..c73269b7e 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
index a40d4277c..fffd4021e 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
index 1f6807376..61c23c19b 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
index ec53593d9..827d74363 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
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_gb.9.png
index baff80950..baff80950 100644
--- a/java/res/drawable-hdpi/keyboard_popup_panel_background.9.png
+++ b/java/res/drawable-hdpi/keyboard_popup_panel_background_gb.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png
index 53d7b6fb3..dc2fc7dfc 100644
--- a/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.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_gb.9.png
index 7cab5a899..7cab5a899 100644
--- a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip_gb.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
index e173beb73..32f426402 100644
--- a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_delete.png b/java/res/drawable-hdpi/sym_bkeyboard_delete.png
deleted file mode 100644
index 1d24cc85c..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png
deleted file mode 100644
index 25702cf73..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_mic.png
deleted file mode 100644
index 512f46080..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_return.png b/java/res/drawable-hdpi/sym_bkeyboard_return.png
deleted file mode 100644
index 426e1599e..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_search.png b/java/res/drawable-hdpi/sym_bkeyboard_search.png
deleted file mode 100644
index 1b6f884fa..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_settings.png b/java/res/drawable-hdpi/sym_bkeyboard_settings.png
deleted file mode 100644
index 08ba18f28..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift.png b/java/res/drawable-hdpi/sym_bkeyboard_shift.png
deleted file mode 100644
index 5a22dd309..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_shift.png
+++ /dev/null
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
deleted file mode 100644
index 566449126..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_space.png b/java/res/drawable-hdpi/sym_bkeyboard_space.png
deleted file mode 100644
index cd0ebe2f4..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_space.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_tab.png b/java/res/drawable-hdpi/sym_bkeyboard_tab.png
deleted file mode 100644
index 3466e1271..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-hdpi/sym_bkeyboard_voice_off.png
deleted file mode 100644
index 081a13096..000000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_voice_off.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png
deleted file mode 100644
index 0591b82cd..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index d3e108846..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..d2d3560a3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic.png b/java/res/drawable-hdpi/sym_keyboard_label_mic.png
deleted file mode 100644
index 4e0a8ed8e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index f8df44741..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch.png b/java/res/drawable-hdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index 7b980a0c8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..78d3a1fc5
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png
deleted file mode 100644
index 520a40f09..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..3c5469403
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png
deleted file mode 100644
index 9743c7f2f..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo.png b/java/res/drawable-hdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index 8978934b8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..60d893cf3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png
deleted file mode 100644
index 8cd28c64a..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-hdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index b987a20f1..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..fa0d1bde1
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png
deleted file mode 100644
index 1e5bf939e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 5af09ad8c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..c76008ab3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png
deleted file mode 100644
index 8e3d0320c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index c58f9ab5c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..544b7e141
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.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
deleted file mode 100644
index d345634a6..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 7a5c03713..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..9b1d6a015
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-hdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index e8bc3902d..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..12e27ade7
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.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_gb.9.png
index c76f64b94..c76f64b94 100644
--- a/java/res/drawable-hdpi/sym_keyboard_space_led.9.png
+++ b/java/res/drawable-hdpi/sym_keyboard_space_led_gb.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
deleted file mode 100644
index 3d1c5c0ea..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 8d10d057c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..2e5f811f3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index 8a6336a57..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..c1e16a651
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.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
deleted file mode 100644
index edf1379ab..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..26d068490
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 5fa30ceb8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..9f9bc173b
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index 91367f3d2..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..f0f832e13
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/tab_selected.9.png b/java/res/drawable-hdpi/tab_selected.9.png
new file mode 100644
index 000000000..84e63df17
--- /dev/null
+++ b/java/res/drawable-hdpi/tab_selected.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/tab_unselected.9.png b/java/res/drawable-hdpi/tab_unselected.9.png
new file mode 100644
index 000000000..bbcfb2c64
--- /dev/null
+++ b/java/res/drawable-hdpi/tab_unselected.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_center_default.9.png b/java/res/drawable-mdpi/btn_center_default.9.png
deleted file mode 100644
index d5ec36ba4..000000000
--- a/java/res/drawable-mdpi/btn_center_default.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_center_pressed.9.png b/java/res/drawable-mdpi/btn_center_pressed.9.png
deleted file mode 100644
index 593a679d0..000000000
--- a/java/res/drawable-mdpi/btn_center_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_center_selected.9.png b/java/res/drawable-mdpi/btn_center_selected.9.png
deleted file mode 100644
index f1914a886..000000000
--- a/java/res/drawable-mdpi/btn_center_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
index e810c7789..f98653ea1 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
index d449d7600..8e9a34957 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index fa24d5987..58a316fba 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index f3fc64114..b7b2dca43 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 8f340d355..4a92b80dd 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 53ea5f894..72125a065 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 69c84e7ec..82413d4cc 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
deleted file mode 100644
index 4b1a78cfb..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
deleted file mode 100644
index 697683e29..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
index 976083fdf..2915588bf 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
index c39dd4a94..049385984 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
deleted file mode 100644
index cdd6c8b79..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
deleted file mode 100644
index d8421746a..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
deleted file mode 100644
index 73cf35df0..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
index 93a6e7921..ee0aae28b 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_dark.png b/java/res/drawable-mdpi/ic_emoji_dark.png
deleted file mode 100644
index d0047a437..000000000
--- a/java/res/drawable-mdpi/ic_emoji_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png
new file mode 100644
index 000000000..d4c8d8da8
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png
new file mode 100644
index 000000000..1555aa7a9
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png
new file mode 100644
index 000000000..081dc66c2
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png
new file mode 100644
index 000000000..58e6f6e75
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_people_light_activated.png b/java/res/drawable-mdpi/ic_emoji_people_light_activated.png
new file mode 100644
index 000000000..067ad5496
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_people_light_activated.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_light.png b/java/res/drawable-mdpi/ic_emoji_people_light_normal.png
index a3195041a..d835d4ec7 100644
--- a/java/res/drawable-mdpi/ic_emoji_light.png
+++ b/java/res/drawable-mdpi/ic_emoji_people_light_normal.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_places_light_activated.png b/java/res/drawable-mdpi/ic_emoji_places_light_activated.png
new file mode 100644
index 000000000..1aecec598
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_places_light_activated.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_places_light_normal.png b/java/res/drawable-mdpi/ic_emoji_places_light_normal.png
new file mode 100644
index 000000000..c70e484e1
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_places_light_normal.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png
new file mode 100644
index 000000000..8009e932f
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png
new file mode 100644
index 000000000..c2e598dfb
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png
new file mode 100644
index 000000000..caea87191
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png
new file mode 100644
index 000000000..0edada626
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_ime_switcher_dark.png b/java/res/drawable-mdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..152f65300
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_settings_language.png b/java/res/drawable-mdpi/ic_settings_language.png
deleted file mode 100644
index f8aca679b..000000000
--- a/java/res/drawable-mdpi/ic_settings_language.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_subtype_keyboard.png b/java/res/drawable-mdpi/ic_subtype_keyboard.png
deleted file mode 100644
index d28efc106..000000000
--- a/java/res/drawable-mdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_background.9.png b/java/res/drawable-mdpi/keyboard_background.9.png
deleted file mode 100644
index 2bd4b628d..000000000
--- a/java/res/drawable-mdpi/keyboard_background.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_dark_background.9.png b/java/res/drawable-mdpi/keyboard_background_gb.9.png
index 4f81704c4..4f81704c4 100644
--- a/java/res/drawable-mdpi/keyboard_dark_background.9.png
+++ b/java/res/drawable-mdpi/keyboard_background_gb.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
index 7a9f640d1..564f5460c 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
index 5b06f09bb..427c87061 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
index fd992d6f4..ea757296d 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
index 128dcd6ad..1911c429f 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
index 0b08d1747..cdef116d2 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
index cf0b33c1d..dea5d076c 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png b/java/res/drawable-mdpi/keyboard_popup_panel_background_gb.9.png
index 0d9ab97f0..0d9ab97f0 100644
--- a/java/res/drawable-mdpi/keyboard_popup_panel_background.9.png
+++ b/java/res/drawable-mdpi/keyboard_popup_panel_background_gb.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png
index 61988a8e1..441edc30b 100644
--- a/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip.9.png b/java/res/drawable-mdpi/keyboard_suggest_strip_gb.9.png
index fa6c0feff..fa6c0feff 100644
--- a/java/res/drawable-mdpi/keyboard_suggest_strip.9.png
+++ b/java/res/drawable-mdpi/keyboard_suggest_strip_gb.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/suggestions_strip_divider.png b/java/res/drawable-mdpi/suggestions_strip_divider.png
index 2dbe2f94b..21e904939 100644
--- a/java/res/drawable-mdpi/suggestions_strip_divider.png
+++ b/java/res/drawable-mdpi/suggestions_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_delete.png b/java/res/drawable-mdpi/sym_bkeyboard_delete.png
deleted file mode 100644
index 1a5ff439e..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png
deleted file mode 100644
index 7f0b1355f..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_mic.png b/java/res/drawable-mdpi/sym_bkeyboard_mic.png
deleted file mode 100644
index a6cb1cc01..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_return.png b/java/res/drawable-mdpi/sym_bkeyboard_return.png
deleted file mode 100644
index e76225d0f..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_search.png b/java/res/drawable-mdpi/sym_bkeyboard_search.png
deleted file mode 100644
index 1f180155d..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_settings.png b/java/res/drawable-mdpi/sym_bkeyboard_settings.png
deleted file mode 100644
index 08ba18f28..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_shift.png b/java/res/drawable-mdpi/sym_bkeyboard_shift.png
deleted file mode 100644
index c981188dd..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png
deleted file mode 100644
index b8cebd060..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_space.png b/java/res/drawable-mdpi/sym_bkeyboard_space.png
deleted file mode 100644
index 4da7ee86e..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_space.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_tab.png b/java/res/drawable-mdpi/sym_bkeyboard_tab.png
deleted file mode 100644
index 2cb991cbf..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-mdpi/sym_bkeyboard_voice_off.png
deleted file mode 100644
index 081a13096..000000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_voice_off.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete.png b/java/res/drawable-mdpi/sym_keyboard_delete.png
deleted file mode 100644
index 1b0f3f836..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index 86be35185..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..edd9d164e
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic.png b/java/res/drawable-mdpi/sym_keyboard_label_mic.png
deleted file mode 100644
index a354d5321..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index 15606e95f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png
new file mode 100644
index 000000000..537f39b02
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch.png b/java/res/drawable-mdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index f840a631d..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..828929bc8
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic.png b/java/res/drawable-mdpi/sym_keyboard_mic.png
deleted file mode 100644
index e926b3fa6..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..5e58866a7
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png
new file mode 100644
index 000000000..84a63dc7f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return.png b/java/res/drawable-mdpi/sym_keyboard_return.png
deleted file mode 100644
index 0c10f004a..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-mdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index bfcb91328..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..e10103caf
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search.png b/java/res/drawable-mdpi/sym_keyboard_search.png
deleted file mode 100644
index 614f85f5e..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-mdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index dd3c83a84..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..290cde41b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings.png b/java/res/drawable-mdpi/sym_keyboard_settings.png
deleted file mode 100644
index ad7618fa0..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 36c8c9623..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..a76a976c5
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift.png b/java/res/drawable-mdpi/sym_keyboard_shift.png
deleted file mode 100644
index 5109b0471..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 621946455..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..37375d935
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png
deleted file mode 100644
index 244179c2d..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index fb3a020d8..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..3654868dc
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png
new file mode 100644
index 000000000..71272bb88
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-mdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 1f787d573..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..a38f99496
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_led.9.png b/java/res/drawable-mdpi/sym_keyboard_space_led_gb.9.png
index 1c1ca2cc7..1c1ca2cc7 100644
--- a/java/res/drawable-mdpi/sym_keyboard_space_led.9.png
+++ b/java/res/drawable-mdpi/sym_keyboard_space_led_gb.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab.png b/java/res/drawable-mdpi/sym_keyboard_tab.png
deleted file mode 100644
index eddb9a592..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 8d20153ee..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..f883807f2
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index 0795fcc9b..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..16be37d05
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.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
deleted file mode 100644
index f76da5797..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..95d718a46
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 70370d83d..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..8957e282b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index a69eade17..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..5f49e64aa
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/tab_selected.9.png b/java/res/drawable-mdpi/tab_selected.9.png
new file mode 100644
index 000000000..4b00f350a
--- /dev/null
+++ b/java/res/drawable-mdpi/tab_selected.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/tab_unselected.9.png b/java/res/drawable-mdpi/tab_unselected.9.png
new file mode 100644
index 000000000..bb45ab960
--- /dev/null
+++ b/java/res/drawable-mdpi/tab_unselected.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_center_default.9.png b/java/res/drawable-xhdpi/btn_center_default.9.png
deleted file mode 100644
index e847425f8..000000000
--- a/java/res/drawable-xhdpi/btn_center_default.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_center_pressed.9.png b/java/res/drawable-xhdpi/btn_center_pressed.9.png
deleted file mode 100644
index facfd4323..000000000
--- a/java/res/drawable-xhdpi/btn_center_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_center_selected.9.png b/java/res/drawable-xhdpi/btn_center_selected.9.png
deleted file mode 100644
index facfd4323..000000000
--- a/java/res/drawable-xhdpi/btn_center_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
index d990c0258..738316d66 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
index d2cd029bb..a2f6ac0e2 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index bca39cf17..2f00fc623 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index ab8fb2e86..20251a000 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 3871689ef..84d173967 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 912506368..ee4490eac 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 35ce67fdc..e8124776c 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png
deleted file mode 100644
index f7e32f764..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png
deleted file mode 100644
index df3b5ba2d..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
index b26f1d27a..0ef4a4b5f 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
index c23a4b225..f770962c3 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png
deleted file mode 100644
index dec219304..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png
deleted file mode 100644
index 3c77b3ccd..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png
deleted file mode 100644
index 5cdfc4201..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
index 0c7bfdace..891d00024 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_dark.png b/java/res/drawable-xhdpi/ic_emoji_dark.png
deleted file mode 100644
index 22daec22e..000000000
--- a/java/res/drawable-xhdpi/ic_emoji_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png
new file mode 100644
index 000000000..3e6744343
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png
new file mode 100644
index 000000000..5344a9ee9
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png
new file mode 100644
index 000000000..75695d43d
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png
new file mode 100644
index 000000000..2adb186e6
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png
new file mode 100644
index 000000000..e6baa2e59
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_light.png b/java/res/drawable-xhdpi/ic_emoji_people_light_normal.png
index 21bc9090d..c26aa4efb 100644
--- a/java/res/drawable-xhdpi/ic_emoji_light.png
+++ b/java/res/drawable-xhdpi/ic_emoji_people_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png
new file mode 100644
index 000000000..eaa3b86cf
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png
new file mode 100644
index 000000000..d6e1eaa35
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png
new file mode 100644
index 000000000..06003b82d
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png
new file mode 100644
index 000000000..da2effedb
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png
new file mode 100644
index 000000000..438fde2b4
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png
new file mode 100644
index 000000000..757863233
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..c567077e5
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_settings_language.png b/java/res/drawable-xhdpi/ic_settings_language.png
deleted file mode 100644
index 2c42db3aa..000000000
--- a/java/res/drawable-xhdpi/ic_settings_language.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_subtype_keyboard.png b/java/res/drawable-xhdpi/ic_subtype_keyboard.png
deleted file mode 100644
index a79bb3458..000000000
--- a/java/res/drawable-xhdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png
new file mode 100644
index 000000000..17581ba89
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_background.9.png b/java/res/drawable-xhdpi/keyboard_background.9.png
deleted file mode 100644
index 263996322..000000000
--- a/java/res/drawable-xhdpi/keyboard_background.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_dark_background.9.png b/java/res/drawable-xhdpi/keyboard_background_gb.9.png
index 27b7a108c..27b7a108c 100644
--- a/java/res/drawable-xhdpi/keyboard_dark_background.9.png
+++ b/java/res/drawable-xhdpi/keyboard_background_gb.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
index d999127f2..e8c65f677 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
index c4d694136..543bc763e 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
index 5429c1785..ec42aadb6 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
index 5135a0869..319e9d7cf 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
index 19a77a29f..052032be7 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
index ae2ffff8e..c7e9d1c9e 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_popup_panel_background.9.png b/java/res/drawable-xhdpi/keyboard_popup_panel_background_gb.9.png
index 79f7ab00a..79f7ab00a 100644
--- a/java/res/drawable-xhdpi/keyboard_popup_panel_background.9.png
+++ b/java/res/drawable-xhdpi/keyboard_popup_panel_background_gb.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png
index 1dee699f4..dde1856e3 100644
--- a/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png b/java/res/drawable-xhdpi/keyboard_suggest_strip_gb.9.png
index 1b568df03..1b568df03 100644
--- a/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png
+++ b/java/res/drawable-xhdpi/keyboard_suggest_strip_gb.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/suggestions_strip_divider.png b/java/res/drawable-xhdpi/suggestions_strip_divider.png
index 0d8b98437..4101ebc59 100644
--- a/java/res/drawable-xhdpi/suggestions_strip_divider.png
+++ b/java/res/drawable-xhdpi/suggestions_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_delete.png b/java/res/drawable-xhdpi/sym_bkeyboard_delete.png
deleted file mode 100644
index b84ee76dc..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png
deleted file mode 100644
index 9bd1d65b4..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_mic.png
deleted file mode 100644
index 8c3f11dd4..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_return.png b/java/res/drawable-xhdpi/sym_bkeyboard_return.png
deleted file mode 100644
index 1632ecd8e..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_search.png b/java/res/drawable-xhdpi/sym_bkeyboard_search.png
deleted file mode 100644
index 69d8b22d1..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_settings.png b/java/res/drawable-xhdpi/sym_bkeyboard_settings.png
deleted file mode 100644
index 050154a3a..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_shift.png b/java/res/drawable-xhdpi/sym_bkeyboard_shift.png
deleted file mode 100644
index d15d11a50..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png
deleted file mode 100644
index 83b287fea..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_space.png b/java/res/drawable-xhdpi/sym_bkeyboard_space.png
deleted file mode 100644
index 5ca62c7b7..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_space.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_tab.png b/java/res/drawable-xhdpi/sym_bkeyboard_tab.png
deleted file mode 100644
index 6ca199755..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png
deleted file mode 100644
index fc6a4eb59..000000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete.png b/java/res/drawable-xhdpi/sym_keyboard_delete.png
deleted file mode 100644
index 3c0b8b186..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index 354c09ee6..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..e3e37d5ff
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic.png
deleted file mode 100644
index 49810a02f..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index 8eeb179f5..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index 6c2fb53ec..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..b8687f550
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic.png b/java/res/drawable-xhdpi/sym_keyboard_mic.png
deleted file mode 100644
index 1323b6d1e..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..566ba1fcd
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return.png b/java/res/drawable-xhdpi/sym_keyboard_return.png
deleted file mode 100644
index ad061227e..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index ba424adfd..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..7b7ad1747
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search.png b/java/res/drawable-xhdpi/sym_keyboard_search.png
deleted file mode 100644
index aa785a221..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index f2fb2a2b5..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..36b1646bb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings.png b/java/res/drawable-xhdpi/sym_keyboard_settings.png
deleted file mode 100644
index 50704255d..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 99ee97dbf..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..05eaffe2e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift.png b/java/res/drawable-xhdpi/sym_keyboard_shift.png
deleted file mode 100644
index 290170619..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 1046b4545..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..5ab549114
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png
deleted file mode 100644
index a5deb60e9..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 6acb565d9..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..b820eaabb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png
new file mode 100644
index 000000000..686831fd3
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 504a3ed45..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..7114b740f
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_led.9.png b/java/res/drawable-xhdpi/sym_keyboard_space_led_gb.9.png
index 6525fefab..6525fefab 100644
--- a/java/res/drawable-xhdpi/sym_keyboard_space_led.9.png
+++ b/java/res/drawable-xhdpi/sym_keyboard_space_led_gb.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab.png b/java/res/drawable-xhdpi/sym_keyboard_tab.png
deleted file mode 100644
index 0ef2ab5b9..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index ff380eeab..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..73ebfe525
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index b2bb9b803..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..944a8524d
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index 23e75bfe7..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..2016caf40
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 26694274e..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..2f9607add
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index 75a22b65f..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..ab07f7549
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/tab_selected.9.png b/java/res/drawable-xhdpi/tab_selected.9.png
new file mode 100644
index 000000000..95e5f4341
--- /dev/null
+++ b/java/res/drawable-xhdpi/tab_selected.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/tab_unselected.9.png b/java/res/drawable-xhdpi/tab_unselected.9.png
new file mode 100644
index 000000000..8cede8d5e
--- /dev/null
+++ b/java/res/drawable-xhdpi/tab_unselected.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
index 680421eaf..b35c29fe6 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
index ae2675053..17f0a7a58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index c92a669f9..b0e815eb2 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index 40f5011c0..97f96258e 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 6ff6319d3..dfb16a76b 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 818ea70fd..bf1d34686 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index a476d2a9e..962277165 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
index 9c280a655..4ddfdcb6c 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png
index 3c17c5eec..17144b673 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png
index 6d2af5942..0cbb2ec84 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png
new file mode 100644
index 000000000..470fd695c
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png
new file mode 100644
index 000000000..a7fde0ec5
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png
new file mode 100644
index 000000000..c582b704a
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png
new file mode 100644
index 000000000..acc95d725
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png
new file mode 100644
index 000000000..5973ac355
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png
new file mode 100644
index 000000000..22e06f808
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png
new file mode 100644
index 000000000..690e95fd5
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png
new file mode 100644
index 000000000..ced4b08cf
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png
new file mode 100644
index 000000000..25e847ef3
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png
new file mode 100644
index 000000000..c86368d73
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png
new file mode 100644
index 000000000..29dfc7118
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png
new file mode 100644
index 000000000..0570567cf
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..f99f7d0c7
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png b/java/res/drawable-xxhdpi/ic_subtype_keyboard.png
deleted file mode 100644
index 0bb4283b0..000000000
--- a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png
new file mode 100644
index 000000000..811103a56
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png
index bd1ef3cd9..11eee94f3 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png
index 65af4b569..2079e0462 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png
index ac6750dcb..c4178d9a8 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png
index cea7c05f6..121411a06 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png
index 520fa7c6b..d3d8733fd 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png
index eee221758..d7ec8bcb2 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png
index 721c24400..ca576deaf 100644
--- a/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index be3cb7ce7..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..92be79241
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index b6d4477bd..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index 7cd0684a0..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..88b55bb37
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..f55af308c
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index 7d9580796..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..46ee50eba
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index 6b09d8e57..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..f518748ce
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 7041bb6ce..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..e4358463b
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 2b4fbbba6..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..523286e6e
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 91c8603fd..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..87926d9a6
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png
new file mode 100644
index 000000000..04b721617
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 65aa5ea9b..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..1dab1f431
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 1f4ae3df7..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..6eb3eb0b3
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index f04cadf6f..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..6809f0711
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index e74d523bc..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..6bd506a11
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 85289b2a3..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..5e225b837
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index e610678b1..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..cdfc0295b
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/tab_selected.9.png b/java/res/drawable-xxhdpi/tab_selected.9.png
new file mode 100644
index 000000000..e5efc5828
--- /dev/null
+++ b/java/res/drawable-xxhdpi/tab_selected.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/tab_unselected.9.png b/java/res/drawable-xxhdpi/tab_unselected.9.png
new file mode 100644
index 000000000..389188695
--- /dev/null
+++ b/java/res/drawable-xxhdpi/tab_unselected.9.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key.xml b/java/res/drawable/btn_keyboard_key.xml
deleted file mode 100644
index 797bc105e..000000000
--- a/java/res/drawable/btn_keyboard_key.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Toggle keys. Use checkable/checked state. -->
-
- <item android:state_checkable="true" android:state_checked="true"
- android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed_on" />
- <item android:state_checkable="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed_off" />
- <item android:state_checkable="true" android:state_checked="true"
- android:drawable="@drawable/btn_keyboard_key_normal_on" />
- <item android:state_checkable="true"
- android:drawable="@drawable/btn_keyboard_key_normal_off" />
-
- <!-- Normal keys -->
-
- <item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed" />
- <item
- android:drawable="@drawable/btn_keyboard_key_normal" />
-
-</selector>
diff --git a/java/res/drawable/btn_keyboard_key3.xml b/java/res/drawable/btn_keyboard_key3.xml
deleted file mode 100644
index dbe82d5fd..000000000
--- a/java/res/drawable/btn_keyboard_key3.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Toggle keys. Use checkable/checked state. -->
-
- <item android:state_checkable="true" android:state_checked="true"
- android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_pressed_on" />
- <item android:state_checkable="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
- <item android:state_checkable="true" android:state_checked="true"
- android:drawable="@drawable/btn_keyboard_key_normal_on" />
- <item android:state_checkable="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
-
- <!-- Normal keys -->
-
- <item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_normal" />
- <item android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
-</selector>
diff --git a/java/res/drawable/btn_keyboard_key_functional_gb.xml b/java/res/drawable/btn_keyboard_key_functional_gb.xml
new file mode 100644
index 000000000..431359c20
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_functional_gb.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Functional keys. -->
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed" />
+ <item android:drawable="@drawable/btn_keyboard_key_dark_normal" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_functional_ics.xml b/java/res/drawable/btn_keyboard_key_functional_ics.xml
new file mode 100644
index 000000000..5dcde5fa9
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_functional_ics.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Functional keys. -->
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_dark_pressed_holo" />
+ <item android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_gingerbread.xml b/java/res/drawable/btn_keyboard_key_gb.xml
index 5b4399e1b..3fc253e85 100644
--- a/java/res/drawable/btn_keyboard_key_gingerbread.xml
+++ b/java/res/drawable/btn_keyboard_key_gb.xml
@@ -15,23 +15,19 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
<!-- Functional keys. -->
-
<item android:state_single="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_dark_pressed" />
<item android:state_single="true"
android:drawable="@drawable/btn_keyboard_key_dark_normal" />
<!-- Action keys. -->
-
<item android:state_active="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_dark_pressed" />
<item android:state_active="true"
android:drawable="@drawable/btn_keyboard_key_dark_normal" />
<!-- Toggle keys. Use checkable/checked state. -->
-
<item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_dark_pressed_on" />
<item android:state_checkable="true" android:state_pressed="true"
@@ -41,8 +37,11 @@
<item android:state_checkable="true"
android:drawable="@drawable/btn_keyboard_key_dark_normal_off" />
- <!-- Normal keys. -->
+ <!-- Empty background keys. -->
+ <item android:state_empty="true"
+ android:drawable="@drawable/transparent" />
+ <!-- Normal keys. -->
<item android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_light_pressed" />
<item android:drawable="@drawable/btn_keyboard_key_light_normal" />
diff --git a/java/res/drawable/btn_keyboard_key_ics.xml b/java/res/drawable/btn_keyboard_key_ics.xml
index e893da133..0c86e163e 100644
--- a/java/res/drawable/btn_keyboard_key_ics.xml
+++ b/java/res/drawable/btn_keyboard_key_ics.xml
@@ -15,23 +15,19 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
<!-- Functional keys. -->
-
<item android:state_single="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_dark_pressed_holo" />
<item android:state_single="true"
android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
<!-- Action keys. -->
-
<item android:state_active="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_dark_pressed_holo" />
<item android:state_active="true"
android:drawable="@drawable/btn_keyboard_key_dark_active_holo" />
<!-- Toggle keys. Use checkable/checked state. -->
-
<item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_dark_pressed_on_holo" />
<item android:state_checkable="true" android:state_pressed="true"
@@ -41,8 +37,11 @@
<item android:state_checkable="true"
android:drawable="@drawable/btn_keyboard_key_dark_normal_off_holo" />
- <!-- Normal keys. -->
+ <!-- Empty background keys. -->
+ <item android:state_empty="true"
+ android:drawable="@drawable/transparent" />
+ <!-- Normal keys. -->
<item android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_light_pressed_holo" />
<item android:drawable="@drawable/btn_keyboard_key_light_normal_holo" />
diff --git a/java/res/drawable/btn_keyboard_key_popup.xml b/java/res/drawable/btn_keyboard_key_popup_gb.xml
index 9e3670d22..9e3670d22 100644
--- a/java/res/drawable/btn_keyboard_key_popup.xml
+++ b/java/res/drawable/btn_keyboard_key_popup_gb.xml
diff --git a/java/res/drawable/btn_keyboard_key_stone.xml b/java/res/drawable/btn_keyboard_key_stone.xml
deleted file mode 100644
index 9bc3f18d6..000000000
--- a/java/res/drawable/btn_keyboard_key_stone.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Functional keys. -->
-
- <item android:state_single="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
- <item android:state_single="true"
- android:drawable="@drawable/btn_keyboard_key_normal_stone" />
-
- <!-- Action keys. -->
-
- <item android:state_active="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
- <item android:state_active="true"
- android:drawable="@drawable/btn_keyboard_key_normal_stone" />
-
- <!-- Toggle keys. Use checkable/checked state. -->
-
- <item android:state_checkable="true" android:state_checked="true"
- android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_normal_on_stone" />
- <item android:state_checkable="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_normal_off_stone" />
- <item android:state_checkable="true" android:state_checked="true"
- android:drawable="@drawable/btn_keyboard_key_normal_on_stone" />
- <item android:state_checkable="true"
- android:drawable="@drawable/btn_keyboard_key_normal_off_stone" />
-
- <!-- Normal keys. -->
-
- <item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_fulltrans_pressed" />
- <item android:drawable="@drawable/btn_keyboard_key_normal_stone" />
-</selector>
diff --git a/java/res/drawable/btn_suggestion.xml b/java/res/drawable/btn_suggestion_gb.xml
index cde12fe55..cde12fe55 100644
--- a/java/res/drawable/btn_suggestion.xml
+++ b/java/res/drawable/btn_suggestion_gb.xml
diff --git a/java/res/drawable/btn_center.xml b/java/res/drawable/ic_emoji_nature_light.xml
index 3ac21297c..543409e03 100644
--- a/java/res/drawable/btn_center.xml
+++ b/java/res/drawable/ic_emoji_nature_light.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,23 +18,16 @@
*/
-->
-<selector
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:state_window_focused="false"
- android:state_enabled="true"
- android:drawable="@drawable/btn_center_default" />
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_nature_light_activated" />
<item
android:state_pressed="true"
- android:drawable="@drawable/btn_center_pressed" />
- <item
- android:state_focused="true"
- android:state_enabled="true"
- android:drawable="@drawable/btn_center_selected" />
+ android:drawable="@drawable/ic_emoji_nature_light_activated" />
<item
- android:state_enabled="true"
- android:drawable="@drawable/btn_center_default" />
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_nature_light_activated" />
<item
- android:drawable="@drawable/btn_center_default" />
+ android:drawable="@drawable/ic_emoji_nature_light_normal" />
</selector>
diff --git a/java/res/drawable/ic_emoji_objects_light.xml b/java/res/drawable/ic_emoji_objects_light.xml
new file mode 100644
index 000000000..4096e695b
--- /dev/null
+++ b/java/res/drawable/ic_emoji_objects_light.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_objects_light_activated" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_objects_light_activated" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_objects_light_activated" />
+ <item android:drawable="@drawable/ic_emoji_objects_light_normal" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_people_light.xml b/java/res/drawable/ic_emoji_people_light.xml
new file mode 100644
index 000000000..ea9e406a4
--- /dev/null
+++ b/java/res/drawable/ic_emoji_people_light.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_people_light_activated" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_people_light_activated" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_people_light_activated" />
+ <item android:drawable="@drawable/ic_emoji_people_light_normal" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_places_light.xml b/java/res/drawable/ic_emoji_places_light.xml
new file mode 100644
index 000000000..312cad9c3
--- /dev/null
+++ b/java/res/drawable/ic_emoji_places_light.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_places_light_activated" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_places_light_activated" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_places_light_activated" />
+ <item android:drawable="@drawable/ic_emoji_places_light_normal" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_recent_light.xml b/java/res/drawable/ic_emoji_recent_light.xml
new file mode 100644
index 000000000..8c2123f83
--- /dev/null
+++ b/java/res/drawable/ic_emoji_recent_light.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_recent_light_activated" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_recent_light_activated" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_recent_light_activated" />
+ <item android:drawable="@drawable/ic_emoji_recent_light_normal" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_symbols_light.xml b/java/res/drawable/ic_emoji_symbols_light.xml
new file mode 100644
index 000000000..79aaf0fc5
--- /dev/null
+++ b/java/res/drawable/ic_emoji_symbols_light.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_symbols_light_activated" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_symbols_light_activated" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_symbols_light_activated" />
+ <item android:drawable="@drawable/ic_emoji_symbols_light_normal" />
+</selector>
diff --git a/java/res/drawable/keyboard_key_feedback.xml b/java/res/drawable/keyboard_key_feedback_gb.xml
index 397e948d8..397e948d8 100644
--- a/java/res/drawable/keyboard_key_feedback.xml
+++ b/java/res/drawable/keyboard_key_feedback_gb.xml
diff --git a/java/res/layout/emoji_keyboard_page.xml b/java/res/layout/emoji_keyboard_page.xml
new file mode 100644
index 000000000..e0b752b32
--- /dev/null
+++ b/java/res/layout/emoji_keyboard_page.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.inputmethod.keyboard.internal.ScrollViewWithNotifier
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/emoji_keyboard_scroller"
+ android:clipToPadding="false"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+>
+ <com.android.inputmethod.keyboard.internal.ScrollKeyboardView
+ android:id="@+id/emoji_keyboard_page"
+ android:layoutDirection="ltr"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+</com.android.inputmethod.keyboard.internal.ScrollViewWithNotifier>
diff --git a/java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml b/java/res/layout/emoji_keyboard_tab_icon.xml
index f89a0a673..d79276eb9 100644
--- a/java/res/xml-sw768dp/kbd_more_keys_keyboard_template.xml
+++ b/java/res/layout/emoji_keyboard_tab_icon.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,9 +18,9 @@
*/
-->
-<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="5.0%p"
- latin:rowHeight="@dimen/popup_key_height"
- style="?attr/moreKeysKeyboardStyle"
- >
-</Keyboard>
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dip"
+ android:layout_weight="1.0"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+/>
diff --git a/java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml b/java/res/layout/emoji_keyboard_tab_label.xml
index f593fa944..62c552dd8 100644
--- a/java/res/xml-sw768dp-land/kbd_more_keys_keyboard_template.xml
+++ b/java/res/layout/emoji_keyboard_tab_label.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2010, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,9 +18,9 @@
*/
-->
-<Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="3.5%p"
- latin:rowHeight="@dimen/popup_key_height"
- style="?attr/moreKeysKeyboardStyle"
- >
-</Keyboard>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dip"
+ android:layout_weight="1.0"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+/>
diff --git a/java/res/layout/emoji_keyboard_view.xml b/java/res/layout/emoji_keyboard_view.xml
new file mode 100644
index 000000000..4566a5a1f
--- /dev/null
+++ b/java/res/layout/emoji_keyboard_view.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.inputmethod.keyboard.EmojiKeyboardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/emoji_keyboard_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?attr/emojiKeyboardViewStyle"
+>
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/suggestions_strip_height"
+ >
+ <TabHost
+ android:id="@+id/emoji_category_tabhost"
+ android:layout_width="0dip"
+ android:layout_weight="87.5"
+ android:layout_height="match_parent"
+ >
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/tab_selected"
+ android:divider="@null"
+ android:tabStripEnabled="true"
+ android:tabStripLeft="@drawable/tab_unselected"
+ android:tabStripRight="@drawable/tab_unselected" />
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ >
+ <!-- Empty placeholder that TabHost requires. But we don't use it to actually
+ display anything. We monitor the tab changes and change the ViewPager.
+ Similarly the ViewPager swipes are intercepted and passed to the TabHost. -->
+ <View
+ android:id="@+id/emoji_keyboard_dummy"
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:visibility="gone" />
+ </FrameLayout>
+ </TabHost>
+ <View
+ android:layout_width="2dip"
+ android:layout_height="match_parent"
+ android:background="@drawable/suggestions_strip_divider" />
+ <ImageButton
+ android:id="@+id/emoji_keyboard_delete"
+ android:layout_width="0dip"
+ android:layout_weight="12.5"
+ android:layout_height="match_parent"
+ android:background="@color/emoji_key_background_color"
+ android:src="@drawable/sym_keyboard_delete_holo_dark" />
+ </LinearLayout>
+ <android.support.v4.view.ViewPager
+ android:id="@+id/emoji_keyboard_pager"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <com.android.inputmethod.keyboard.EmojiCategoryPageIndicatorView
+ android:id="@+id/emoji_category_page_id_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/emoji_category_page_id_view_background" />
+ <LinearLayout
+ android:id="@+id/emoji_action_bar"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ >
+ <ImageButton
+ android:id="@+id/emoji_keyboard_alphabet"
+ android:layout_width="0dip"
+ android:layout_weight="0.15"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_ime_switcher_dark" />
+ <ImageButton
+ android:id="@+id/emoji_keyboard_space"
+ android:layout_width="0dip"
+ android:layout_weight="0.70"
+ android:layout_height="match_parent" />
+ <ImageButton
+ android:id="@+id/emoji_keyboard_send"
+ android:layout_width="0dip"
+ android:layout_weight="0.15"
+ android:layout_height="match_parent"
+ android:src="@drawable/sym_keyboard_return_holo_dark" />
+ </LinearLayout>
+</com.android.inputmethod.keyboard.EmojiKeyboardView>
diff --git a/java/res/layout/hint_add_to_dictionary.xml b/java/res/layout/hint_add_to_dictionary.xml
index 73de44fae..68a9faf19 100644
--- a/java/res/layout/hint_add_to_dictionary.xml
+++ b/java/res/layout/hint_add_to_dictionary.xml
@@ -33,4 +33,4 @@
android:clickable="false"
android:singleLine="true"
android:ellipsize="none"
- style="?attr/suggestionBackgroundStyle" />
+ style="?attr/suggestionWordStyle" />
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index 1ffb8a32a..0b682d198 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -20,34 +20,41 @@
<com.android.inputmethod.latin.InputView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
->
+ android:gravity="bottom|center_horizontal"
+ android:orientation="vertical" >
<!-- The height of key_preview_backing view will automatically be determined by code. -->
<View
android:id="@+id/key_preview_backing"
android:layout_width="match_parent"
android:layout_height="0dp" />
+ <LinearLayout
+ android:id="@+id/main_keyboard_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
- <!-- To ensure that key preview popup is correctly placed when the current system locale is
- one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
- <com.android.inputmethod.latin.suggestions.SuggestionStripView
- android:id="@+id/suggestion_strip_view"
- android:layoutDirection="ltr"
- android:layout_width="match_parent"
- android:layout_height="@dimen/suggestions_strip_height"
- android:gravity="center_vertical"
- android:paddingRight="@dimen/suggestions_strip_padding"
- android:paddingLeft="@dimen/suggestions_strip_padding"
- style="?attr/suggestionStripViewStyle" />
+ <!-- To ensure that key preview popup is correctly placed when the current system locale is
+ one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+ <com.android.inputmethod.latin.suggestions.SuggestionStripView
+ android:id="@+id/suggestion_strip_view"
+ android:layoutDirection="ltr"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/suggestions_strip_height"
+ android:gravity="center_vertical"
+ android:paddingRight="@dimen/suggestions_strip_padding"
+ android:paddingLeft="@dimen/suggestions_strip_padding"
+ style="?attr/suggestionStripViewStyle" />
- <!-- To ensure that key preview popup is correctly placed when the current system locale is
- one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
- <com.android.inputmethod.keyboard.MainKeyboardView
- android:id="@+id/keyboard_view"
- android:layoutDirection="ltr"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <!-- To ensure that key preview popup is correctly placed when the current system locale is
+ one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
+ <com.android.inputmethod.keyboard.MainKeyboardView
+ android:id="@+id/keyboard_view"
+ android:layoutDirection="ltr"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+ <include
+ layout="@layout/emoji_keyboard_view" />
</com.android.inputmethod.latin.InputView>
diff --git a/java/res/layout/key_preview.xml b/java/res/layout/key_preview_gb.xml
index 2fcd0c4dd..2f2a321a3 100644
--- a/java/res/layout/key_preview.xml
+++ b/java/res/layout/key_preview_gb.xml
@@ -21,7 +21,7 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/keyboard_key_feedback"
+ android:background="@drawable/keyboard_key_feedback_gb"
android:minWidth="32dp"
android:gravity="center"
/>
diff --git a/java/res/layout/more_keys_keyboard.xml b/java/res/layout/more_keys_keyboard.xml
index 6b2464b99..6637117e0 100644
--- a/java/res/layout/more_keys_keyboard.xml
+++ b/java/res/layout/more_keys_keyboard.xml
@@ -17,17 +17,17 @@
** limitations under the License.
*/
-->
+
<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- style="?attr/moreKeysKeyboardPanelStyle"
- >
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ style="?attr/moreKeysKeyboardContainerStyle"
+>
<com.android.inputmethod.keyboard.MoreKeysKeyboardView
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/more_keys_keyboard_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ android:id="@+id/more_keys_keyboard_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
</LinearLayout>
diff --git a/java/res/layout/more_suggestions.xml b/java/res/layout/more_suggestions.xml
index b41bb8aa4..8659f0761 100644
--- a/java/res/layout/more_suggestions.xml
+++ b/java/res/layout/more_suggestions.xml
@@ -17,21 +17,21 @@
** limitations under the License.
*/
-->
+
<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ style="?attr/moreKeysKeyboardContainerStyle"
+>
+ <com.android.inputmethod.latin.suggestions.MoreSuggestionsView
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ android:id="@+id/more_suggestions_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- style="?attr/moreKeysKeyboardPanelStyle"
- >
- <com.android.inputmethod.latin.suggestions.MoreSuggestionsView
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- android:id="@+id/more_suggestions_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- latin:keyLetterSize="@dimen/suggestion_text_size"
- latin:keyLabelSize="@dimen/suggestion_text_size"
- latin:keyHintLetterRatio="@fraction/more_suggestions_info_ratio"
- latin:keyHintLetterColor="@android:color/white"
- />
+ latin:keyLetterSize="@dimen/suggestion_text_size"
+ latin:keyLabelSize="@dimen/suggestion_text_size"
+ latin:keyHintLetterRatio="@fraction/more_suggestions_info_ratio"
+ latin:keyHintLetterColor="@android:color/white" />
</LinearLayout>
diff --git a/java/res/layout/suggestion_info.xml b/java/res/layout/suggestion_info.xml
index a4ad6df25..0aa26000d 100644
--- a/java/res/layout/suggestion_info.xml
+++ b/java/res/layout/suggestion_info.xml
@@ -24,4 +24,4 @@
android:layout_height="wrap_content"
android:textSize="6dp"
android:textColor="@android:color/white"
- style="?attr/suggestionBackgroundStyle" />
+ style="?attr/suggestionWordStyle" />
diff --git a/java/res/layout/suggestion_word.xml b/java/res/layout/suggestion_word.xml
index fa00e041e..c82a13c99 100644
--- a/java/res/layout/suggestion_word.xml
+++ b/java/res/layout/suggestion_word.xml
@@ -36,4 +36,4 @@
android:clickable="false"
android:singleLine="true"
android:ellipsize="none"
- style="?attr/suggestionBackgroundStyle" />
+ style="?attr/suggestionWordStyle" />
diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict
index 31fb2af85..10adad092 100644
--- a/java/res/raw/main_fr.dict
+++ b/java/res/raw/main_fr.dict
Binary files differ
diff --git a/java/res/raw/main_pt_br.dict b/java/res/raw/main_pt_br.dict
index 557d46e89..f9ae9b561 100644
--- a/java/res/raw/main_pt_br.dict
+++ b/java/res/raw/main_pt_br.dict
Binary files differ
diff --git a/java/res/raw/main_ru.dict b/java/res/raw/main_ru.dict
index 86c368eb9..7dec62425 100644
--- a/java/res/raw/main_ru.dict
+++ b/java/res/raw/main_ru.dict
Binary files differ
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index 986e29ba9..01a57e7e0 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Spasiebalk en leestekens korrigeer outomaties woorde wat verkeerd gespel is"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Af"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Matig"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Aggressief"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Baie aggressief"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressief"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Baie aggressief"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Stel volgende woord voor"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Gebruik die vorige woord om voorstelle te maak"</string>
<string name="gesture_input" msgid="826951152254563827">"Aktiveer gebaar-tik"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Engels (VK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Engels (VS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spaans (VS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Geen taal nie"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Geen taal (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Geen taal nie (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Geen taal nie (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Geen taal nie (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Geen taal nie (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Geen taal nie (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Tradisioneel)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Geen taal nie (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emosiekone"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Gepasmaakte invoerstyle"</string>
<string name="add_style" msgid="6163126614514489951">"Voeg styl by"</string>
<string name="add" msgid="8299699805688017798">"Voeg by"</string>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index 32faf0fc6..774f2c552 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"የቦታ ቁልፍ እና ሥርዓተ ነጥብ በስህተት የተተየቡ ቃላትን በራስሰር ያስተካክላሉ ።"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ውጪ"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"መጠነኛ"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"ኃይለኛ"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"በጣም ቁጡ"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"ኃይለኛ"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"በጣም ኃይለኛ"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"የቀጣይ ቃል አስተያየቶች"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"አስተያየቶች መስጠት ላይ ቀዳሚውን ቃል ተጠቀም"</string>
<string name="gesture_input" msgid="826951152254563827">"በምልክት መተየብ ያንቁ"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"እንግሊዘኛ (ዩናይትድ ኪንግደም) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"እንግሊዘኛ (አሜሪካ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ስፓኒሽኛ (ዩኤስ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"ምንም ቋንቋ"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"ቋንቋ አልባ (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"ቋንቋ አልባ (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"ቋንቋ አልባ (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"ቋንቋ አልባ (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"ቋንቋ አልባ (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"ቋንቋ አልባ (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (ተለምዷዊ)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ምንም ቋንቋ (ፊደላት)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ፊደላት (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ፊደላት (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"ፊደላት (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"ፊደላት (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"ፊደላት (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"ፊደላት (ፒሲ)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"ኢሞጂ"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"የተበጁ የግቤት ስታይሎች"</string>
<string name="add_style" msgid="6163126614514489951">"ስታይል አክል"</string>
<string name="add" msgid="8299699805688017798">"አክል"</string>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 7079a0ae1..7e39b597e 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"تؤدي المسافة والترقيم إلى تصحيح الكلمات المكتوبة بشكل غير صحيح"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"إيقاف"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"معتدل"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"حاد"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"شديد الصرامة"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"صارم"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"شديد الصرامة"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"اقتراحات الكلمات التالية"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"استخدام الكلمة السابقة في تقديم الاقتراحات"</string>
<string name="gesture_input" msgid="826951152254563827">"تمكين الكتابة بالإيماءة"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"الإنجليزية (المملكة المتحدة) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"الإنجليزية (الولايات المتحدة) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"الإسبانية (الأمريكية) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"بدون لغة"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"بدون لغة (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"بدون لغة (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"بدون لغة (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"بدون لغة (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"بدون لغة (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"بدون لغة (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (التقليدية)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"بدون لغة (أبجدية)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"الأبجدية (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"الأبجدية (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"الأبجدية (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"الأبجدية (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"الأبجدية (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"الأبجدية (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"الرموز التعبيرية"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"أنماط الإدخال المخصصة"</string>
<string name="add_style" msgid="6163126614514489951">"إضافة نمط"</string>
<string name="add" msgid="8299699805688017798">"إضافة"</string>
diff --git a/java/res/values-be/strings.xml b/java/res/values-be/strings.xml
index 68b0b619e..db40c8a72 100644
--- a/java/res/values-be/strings.xml
+++ b/java/res/values-be/strings.xml
@@ -65,8 +65,10 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Прабелы і пунктуацыйныя знакі дазваляюць аўтаматычна выпраўляць памылкова ўведзеныя словы"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Адключаны"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Сціплы"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Агрэсіўны"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Вельмі агрэсіўны"</string>
+ <!-- no translation found for auto_correction_threshold_mode_aggressive (7319007299148899623) -->
+ <skip />
+ <!-- no translation found for auto_correction_threshold_mode_very_aggressive (1853309024129480416) -->
+ <skip />
<string name="bigram_prediction" msgid="1084449187723948550">"Падказкi для наступнага слова"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Выкарыстоўваць папярэдняе слова, каб атрымлiваць падказкi"</string>
<string name="gesture_input" msgid="826951152254563827">"Уключыць набор жэстамі"</string>
@@ -144,13 +146,24 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Англійская (Вялікабрытанія) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Англійская (ЗША) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"iспанская (ЗША) ( <xliff:g id="LAYOUT">%s</xliff:g> )"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Мова не выбрана"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Мова не выбрана (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Няма мовы (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Няма мовы (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Няма мовы (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Няма мовы (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Няма мовы (PC)"</string>
+ <!-- no translation found for subtype_nepali_traditional (9032247506728040447) -->
+ <skip />
+ <!-- no translation found for subtype_no_language (7137390094240139495) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_qwerty (244337630616742604) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_qwertz (443066912507547976) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_azerty (8144348527575640087) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_dvorak (1564494667584718094) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_colemak (5837418400010302623) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_pcqwerty (5354918232046200018) -->
+ <skip />
+ <!-- no translation found for subtype_emoji (7483586578074549196) -->
+ <skip />
<string name="custom_input_styles_title" msgid="8429952441821251512">"Карыстальніцкія стылі ўводу"</string>
<string name="add_style" msgid="6163126614514489951">"Дадаць стыль"</string>
<string name="add" msgid="8299699805688017798">"Дадаць"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 3de6b8ef7..d3879cca5 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Клавишът за интервал и пунктуация авт. поправя сгрешени думи"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Изкл."</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Агресивно"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Много агресивно"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Агресивно"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Много агресивно"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Предложения за следващата дума"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Използване на предишната дума при даване на предложения"</string>
<string name="gesture_input" msgid="826951152254563827">"Активиране на въвеждането чрез жест"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"английски (Великобр.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"английски (САЩ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"испански (САЩ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Без език"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"без език („QWERTY“)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Без език (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Без език (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Без език (Дворак)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Без език (Коулмак)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Без език (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (традиционен)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Без език (латиница)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиница (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиница (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Латиница (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Латиница (Дворак)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Латиница (Коулмак)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Латиница (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Емотикони"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Персон. стилове за въвежд."</string>
<string name="add_style" msgid="6163126614514489951">"+ стил"</string>
<string name="add" msgid="8299699805688017798">"Добавяне"</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index f71838710..03e2f3fdf 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Prémer tecla d\'espai o punt. per corregir errors"</string>
<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_aggressive" msgid="3524029103734923819">"Total"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Molt agressiu"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agressiu"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Molt agressiu"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Suggeriments de paraula següent"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Utilitza la paraula anterior a l\'hora de fer suggeriments"</string>
<string name="gesture_input" msgid="826951152254563827">"Activa l\'escriptura gestual"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Anglès (Regne Unit) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Anglès (Estats Units) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Espanyol (EUA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Cap idioma"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Cap idioma (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Cap idioma (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Cap idioma (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Cap idioma (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Cap idioma (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Cap idioma (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Cap idioma (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Estils d\'entrada personalitzats"</string>
<string name="add_style" msgid="6163126614514489951">"Afeg. estil"</string>
<string name="add" msgid="8299699805688017798">"Afegeix"</string>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index 1089f483e..a707f26a7 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Stisknutím mezerníku a interpunkce se automaticky opravují chybně napsaná slova"</string>
<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_aggressive" msgid="3524029103734923819">"Agresivní"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Velmi agresivní"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresivní"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Velmi agresivní"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Návrhy dalšího slova"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Návrhy na základě předchozího slova"</string>
<string name="gesture_input" msgid="826951152254563827">"Aktivovat psaní gesty"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"angličtina (VB) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"angličtina (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"španělština (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Žádný jazyk"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Žádný jazyk (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Žádný jazyk (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Žádný jazyk (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Žádný jazyk (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Žádný jazyk (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Žádný jazyk (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradiční)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Žádný jazyk (latinka)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinka (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinka (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Latinka (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Latinka (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Latinka (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Latinka (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emodži"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Vlastní styl zadávání"</string>
<string name="add_style" msgid="6163126614514489951">"Přidat styl"</string>
<string name="add" msgid="8299699805688017798">"Přidat"</string>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index 929802f6a..187689559 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Mellemrumstast og tegnsætning retter automatisk forkerte ord"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Fra"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderat"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Aggressiv"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Meget aggressiv"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressiv"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Meget aggressiv"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Forslag til næste ord"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Brug det forrige ord til at give forslag"</string>
<string name="gesture_input" msgid="826951152254563827">"Aktivér skrivning med berøring"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Engelsk (Storbritannien) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Engelsk (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spansk (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Intet sprog"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Ingen sprog (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Intet sprog (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Intet sprog (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Intet sprog (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Intet sprog (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Intet sprog (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditionelt)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Intet sprog (Alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Tilpasset inputtypografi"</string>
<string name="add_style" msgid="6163126614514489951">"Tilføj typografi"</string>
<string name="add" msgid="8299699805688017798">"Tilføj"</string>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index cff23a861..5f3e619ff 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Korrektur fehlerhafter Wörter durch Leertaste und Satzzeichen"</string>
<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_aggressive" msgid="3524029103734923819">"Stark"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Sehr stark"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Stark"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Sehr stark"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Vorschläge für nächstes Wort"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Vorschläge anhand des vorherigen Wortes machen"</string>
<string name="gesture_input" msgid="826951152254563827">"Bewegungseingabe aktivieren"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Englisch (GB) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Englisch (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spanisch (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Keine Sprache"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Keine Sprache (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Keine Sprache (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Keine Sprache (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Keine Sprache (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Keine Sprache (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Keine Sprache (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditionell)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Keine Sprache (lat. Alphabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Lat. Alphabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Lat. Alphabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Lat. Alphabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Lat. Alphabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Lat. Alphabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Lat. Alphabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Benutzerdefinierte Eingabestile"</string>
<string name="add_style" msgid="6163126614514489951">"Stil hinzufügen"</string>
<string name="add" msgid="8299699805688017798">"Hinzufügen"</string>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index a71a5bef8..27eb865ea 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Τα πλήκτρα διαστήματος και στίξης διορθ. αυτόμ. λάθος λέξεις"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Απενεργοποίηση"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Μέτρια"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Υψηλή"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Πολύ επιθετική"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Υψηλή λεπτομέρεια"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Πολύ υψηλή λεπτομέρεια"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Προτάσεις επόμενων λέξεων"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Χρήση της προηγούμενης λέξης για τη δημιουργία προτάσεων"</string>
<string name="gesture_input" msgid="826951152254563827">"Ενεργ. πληκτρολ. με κινήσεις"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Αγγλικά (ΗΒ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Αγγλικά (ΗΠΑ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Ισπανικά (ΗΠΑ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Καμία γλώσσα"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Καμία γλώσσα (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Καμία γλώσσα (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Καμία γλώσσα (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Καμία γλώσσα (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Καμία γλώσσα (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Καμία γλώσσα (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Παραδοσιακά)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Καμία γλώσσα (Αλφάβητο)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Αλφάβητο (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Αλφάβητο (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Αλφάβητο (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Αλφάβητο (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Αλφάβητο (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Αλφάβητο (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoticon"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Προσαρμοσ. στυλ εισαγ."</string>
<string name="add_style" msgid="6163126614514489951">"Προσθ. στυλ"</string>
<string name="add" msgid="8299699805688017798">"Προσθήκη"</string>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index a999a622c..6337aa019 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -24,13 +24,13 @@
<string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Look up contact names"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Spell checker uses entries from your contact list"</string>
- <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on key-press"</string>
- <string name="sound_on_keypress" msgid="6093592297198243644">"Sound on key-press"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on keypress"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Sound on keypress"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Pop-up on key press"</string>
<string name="general_category" msgid="1859088467017573195">"General"</string>
<string name="correction_category" msgid="2236750915056607613">"Text correction"</string>
<string name="gesture_typing_category" msgid="497263612130532630">"Gesture typing"</string>
- <string name="misc_category" msgid="6894192814868233453">"Other Options"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Other options"</string>
<string name="advanced_settings" msgid="362895144495591463">"Advanced settings"</string>
<string name="advanced_settings_summary" msgid="4487980456152830271">"Options for experts"</string>
<string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Switch to other input methods"</string>
@@ -64,9 +64,9 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Correct mistyped words automatically with spacebar and punctuation"</string>
<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_aggressive" msgid="3524029103734923819">"Aggressive"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Very aggressive"</string>
- <string name="bigram_prediction" msgid="1084449187723948550">"Next word suggestions"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressive"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Very aggressive"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Next-word suggestions"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Use the previous word when making suggestions"</string>
<string name="gesture_input" msgid="826951152254563827">"Enable gesture typing"</string>
<string name="gesture_input_summary" msgid="9180350639305731231">"Input a word by sliding through the letters"</string>
@@ -77,7 +77,7 @@
<string name="label_go_key" msgid="1635148082137219148">"Go"</string>
<string name="label_next_key" msgid="362972844525672568">"Next"</string>
<string name="label_previous_key" msgid="1211868118071386787">"Prev"</string>
- <string name="label_done_key" msgid="2441578748772529288">"Done"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Finished"</string>
<string name="label_send_key" msgid="2815056534433717444">"Send"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pause"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Wait"</string>
@@ -143,21 +143,23 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"English (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"English (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spanish (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"No language"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"No language (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"No language (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"No language (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"No language (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"No language (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"No language (PC)"</string>
- <string name="custom_input_styles_title" msgid="8429952441821251512">"Custom input styles"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Traditional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alphabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alphabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alphabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alphabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Customised input styles"</string>
<string name="add_style" msgid="6163126614514489951">"Add style"</string>
<string name="add" msgid="8299699805688017798">"Add"</string>
<string name="remove" msgid="4486081658752944606">"Remove"</string>
<string name="save" msgid="7646738597196767214">"Save"</string>
<string name="subtype_locale" msgid="8576443440738143764">"Language"</string>
<string name="keyboard_layout_set" msgid="4309233698194565609">"Layout"</string>
- <string name="custom_input_style_note_message" msgid="8826731320846363423">"Your custom input style needs to be enabled before you start using it. Do you want to enable it now?"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Your customised input style needs to be enabled before you start using it. Do you want to enable it now?"</string>
<string name="enable" msgid="5031294444630523247">"Enable"</string>
<string name="not_now" msgid="6172462888202790482">"Not now"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index cda4e25f1..b1a421475 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"La barra espaciadora y las teclas de puntuación insertan automáticamente la palabra corregida"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Desactivado"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Moderado"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Total"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Muy agresivo"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Intensa"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Muy intensa"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Suger. de próxima palabra"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Usar la palabra anterior para hacer sugerencias"</string>
<string name="gesture_input" msgid="826951152254563827">"Activar escritura gestual"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglés (Reino Unido) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglés (EE.UU.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Español (EE.UU.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Ningún idioma"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Ningún idioma (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Sin idioma (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Sin idioma (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Sin idioma (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Sin idioma (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Sin idioma (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Ningún idioma (alfabeto)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabeto (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabeto (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabeto (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabeto (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Estilos de entrada personalizados"</string>
<string name="add_style" msgid="6163126614514489951">"Agr. estilo"</string>
<string name="add" msgid="8299699805688017798">"Agregar"</string>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 297db557f..9ff9430de 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Pulsar la tecla de espacio o punto para corregir errores"</string>
<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_aggressive" msgid="3524029103734923819">"Total"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Muy agresiva"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Total"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Casi total"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Sugerir siguiente palabra"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Usar la palabra anterior para hacer sugerencias"</string>
<string name="gesture_input" msgid="826951152254563827">"Habilitar escritura gestual"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglés (Reino Unido) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglés (EE.UU.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Español (EE.UU.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"ningún idioma"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"ningún idioma (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"ningún idioma (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"ningún idioma (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"ningún idioma (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"ningún idioma (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"ningún idioma (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Ningún idioma (alfabeto)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabeto (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabeto (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabeto (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabeto (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Estilos de entrada personalizados"</string>
<string name="add_style" msgid="6163126614514489951">"Añadir estilo"</string>
<string name="add" msgid="8299699805688017798">"Añadir"</string>
diff --git a/java/res/values-et-rEE/strings.xml b/java/res/values-et-rEE/strings.xml
new file mode 100644
index 000000000..62197d772
--- /dev/null
+++ b/java/res/values-et-rEE/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Sisestusvalikud"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Uuringulogi käsud"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontakti nimede kontroll."</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Õigekirjakontroll kasutab teie kontaktisikute loendi sissekandeid"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibreeri klahvivajutusel"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Heli klahvivajutusel"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Klahvivajutusel kuva hüpik"</string>
+ <string name="general_category" msgid="1859088467017573195">"Üldine"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Teksti parandamine"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Joonistusega sisestamine"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Muud valikud"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Täpsemad seaded"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Valikud ekspertidele"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Vaheta sisestusmeetodit"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Keelevahetuse võti hõlmab ka muid sisestusmeetodeid"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Keelevahetuse nupp"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Kuva, kui lubatud on mitu sisendkeelt"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Kuva lohistamisnäidik"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Tõstu- või sümboliklahvidelt lohistades anna visuaalselt märku"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Hüpiku loobumisviivitus"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Viivituseta"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Vaikeseade"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Süsteemi vaikeväärt."</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Soovita kontaktkirjeid"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Kasuta soovitusteks ja parandusteks nimesid kontaktiloendist"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Punkt tühikuklahviga"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Tühikuklahvi kaks korda puudutades sisestatakse punkt ja tühik"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Automaatne suurtähtede kasutamine"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Iga lause esimese sõna kirjutamine suure algustähega"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Isiklik sõnastik"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Pistiksõnaraamatud"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Peamine sõnaraamat"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Kuva parandussoovitusi"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Kuva sisestamise ajal sõnasoovitusi"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Kuva alati"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Kuva vertikaalrežiimis"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Peida alati"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Blokeeri solvavad sõnad"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Ära soovita potentsiaals. solvavaid sõnu"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Automaatparandus"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Tühik ja kirjavahemärgid parand. autom. kirjavigadega sõnad"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Väljas"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mõõdukas"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agressiivne"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Väga agressiivne"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Järgmise sõna soovitused"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Soovituste tegemisel eelmise sõna kasutamine"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Luba joonistusega sisestamine"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Sõna sisestamine tähtede lohistamisega"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Näita liigutuse jälge"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Dünaamiline ujuv eelvaade"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Soovitatud sõna vaatamine joonistusega sisestamise ajal"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : salvestatud"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Mine"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Edasi"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Eelm."</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Valmis"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Saada"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Peata"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Oota"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Ühendage peakomplekt, et kuulata paroole."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Praegune tekst on %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Teksti ei ole sisestatud"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Klahvi kood: %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Tõstuklahv"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Tõstuklahv sees (puudutage keelamiseks)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Suurtähelukk on sees (puudutage keelamiseks)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Kustuta"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Sümbolid"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Tähed"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Numbrid"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Seaded"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tabulaator"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Tühik"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Kõnesisend"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Naerunägu"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Tagasi"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Otsing"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Punkt"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Keele vahetamine"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Järgmine"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Eelmine"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Tõstuklahv on lubatud"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Suurtähelukk on lubatud"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Tõstuklahv on keelatud"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Sümbolite režiim"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Tähtede režiim"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Telefonirežiim"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Telefoni sümbolite režiim"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Klaviatuur on peidetud"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"Näitab klaviatuuri režiimil <xliff:g id="MODE">%s</xliff:g>"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"kuupäev"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"kuupäev ja kellaaeg"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"e-post"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"sõnumiside"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"number"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"telefon"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"tekst"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"aeg"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Häälesisendi klahv"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Peamisel klaviatuuril"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Sümbolite klaviatuuril"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Väljas"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mikrofon peamisel klaviatuuril"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mikr. sümb. klaviat."</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Kõnesisend on keelatud"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Sisestusmeetodite seadistamine"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Sisestuskeeled"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Saatke tagasisidet"</string>
+ <string name="select_language" msgid="3693815588777926848">"Sisestuskeeled"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Salvestamiseks puudutage uuesti"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Sõnastik saadaval"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Luba kasutaja tagasiside"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Aidake seda sisestusmeetodi redigeerijat parandada, saates automaatselt kasutusstatistikat ja krahhiaruandeid."</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Klaviatuuri teema"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"Inglise (UK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"Inglise (USA)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"hispaania (USA)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglise (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglise (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"hispaania (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditsiooniline)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Keel puudub (tähestik)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Tähestik (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Tähestik (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Tähestik (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Tähestik (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Tähestik (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Tähestik (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emotikon"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Kohandage sisendlaadid"</string>
+ <string name="add_style" msgid="6163126614514489951">"Lisage laad"</string>
+ <string name="add" msgid="8299699805688017798">"Lisa"</string>
+ <string name="remove" msgid="4486081658752944606">"Eemalda"</string>
+ <string name="save" msgid="7646738597196767214">"Salvesta"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Keel"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Paigutus"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Kohandatud sisendi laad tuleb enne kasutamist lubada. Lubada?"</string>
+ <string name="enable" msgid="5031294444630523247">"Luba"</string>
+ <string name="not_now" msgid="6172462888202790482">"Mitte kohe"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sama sisendstiil on juba olemas: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kasutatavuse uurimisrežiim"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Pika klahvivajutuse viide"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Klahvivajutuse vibreerimise kestus"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Klahvivajutuse helitugevus"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Välise sõnastikufaili lugemine"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Kaustas Allalaadimised pole ühtegi sõnastikufaili"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Installitava sõnastikufaili valimine"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Kas soovite tõesti installida faili lokaadile <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+ <string name="error" msgid="8940763624668513648">"Ilmnes viga"</string>
+ <string name="button_default" msgid="3988017840431881491">"Vaikeväärtus"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Tere tulemast rakendusse <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"joonistusega sisestamisega"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Alustamine"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Järgmine toiming"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"Rakenduse <xliff:g id="APPLICATION_NAME">%s</xliff:g> seadistamine"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"Lubage <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Märkige oma keele ja sisestamise seadetes rakendus „<xliff:g id="APPLICATION_NAME">%s</xliff:g>”. See lubab rakenduse käitamise teie seadmes."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> on teie keele- ja sisestusseadetes juba lubatud, seega on see toiming tehtud. Asuge järgmise toimingu juurde."</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Luba seadetes"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"Minge üle rakendusele <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Järgmisena valige aktiivseks tekstisisestusmeetodiks rakendus „<xliff:g id="APPLICATION_NAME">%s</xliff:g>”."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Vaheta sisestusmeetodeid"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Õnnitleme. Kõik on valmis!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Nüüd saate rakendusega <xliff:g id="APPLICATION_NAME">%s</xliff:g> sisestada kõikides oma lemmikrakendustes."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Seadista lisakeeled"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Lõpetatud"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Kuva rakenduse ikoon"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Rakenduse ikooni kuvamine käivitajas"</string>
+ <string name="app_name" msgid="6320102637491234792">"Sõnastikupakkuja"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Sõnastikupakkuja"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Sõnastikuteenus"</string>
+ <string name="download_description" msgid="6014835283119198591">"Sõnastiku värskendamisteave"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Pistiksõnastikud"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Sõnastik on saadaval"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Sõnastike seaded"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"Kasutaja sõnastikud"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"Kasutaja sõnastik"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Sõnastik on saadaval"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Praegu allalaadimisel"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Installitud"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Installitud, keelatud"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Probleem sõnastikuga ühendumisel"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Sõnastikke pole"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Värskenda"</string>
+ <string name="last_update" msgid="730467549913588780">"Viimati värskendatud"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Värskenduste otsimine"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Laadimine ..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Peamine sõnastik"</string>
+ <string name="cancel" msgid="6830980399865683324">"Tühista"</string>
+ <string name="install_dict" msgid="180852772562189365">"Installi"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Tühista"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Kustuta"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Mobiilseadmes valitud keelele on saadaval sõnastik.&lt;br/&gt; Teksti mugavamaks sisestamiseks soovitame &lt;b&gt;alla laadida&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> keele sõnastiku.&lt;br/&gt; &lt;br/&gt; 3G kaudu allalaadimisele võib kuluda minut või paar. Kehtida võivad tasud, kui te ei kasuta &lt;b&gt;piiramatut andmepaketti&lt;/b&gt;.&lt;br/&gt; Kui te ei tea, millist andmepaketti kasutate, soovitame allalaadimise automaatseks käivitamiseks leida WiFi-ühenduse.&lt;br/&gt; &lt;br/&gt; Nõuanne: sõnastikke saate alla laadida ja eemaldada, tehes valiku &lt;b&gt;Keel ja sisestamine&lt;/b&gt; mobiilseadme menüüs &lt;b&gt;Seaded&lt;/b&gt;."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Laadi kohe alla (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Laadi alla WiFi kaudu"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"Sõnastik on <xliff:g id="LANGUAGE">%1$s</xliff:g> keele jaoks saadaval"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Vajutage ülevaatamiseks ja allalaadimiseks"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Allalaadimine: <xliff:g id="LANGUAGE">%1$s</xliff:g> keele soovitused on varsti saadaval."</string>
+ <string name="version_text" msgid="2715354215568469385">"Versioon <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Lisa"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Sõnaraamatusse lisamine"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Fraas"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Rohkem valikuid"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Vähem valikuid"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Sõna:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Otsetee:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Keel:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Sisestage sõna"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Valikuline otsetee"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Sõna muutmine"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Muuda"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Kustuta"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"Teie kasutaja sõnaraamatus ei ole ühtegi sõna. Sõna saate lisada, puudutades nuppu Lisa (+)."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Kõikides keeltes"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Rohkem keeli ..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Kustuta"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
+</resources>
diff --git a/java/res/values-et/strings.xml b/java/res/values-et/strings.xml
index 0874a9302..9b9c93a7b 100644
--- a/java/res/values-et/strings.xml
+++ b/java/res/values-et/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Tühik ja kirjavahemärgid parand. autom. kirjavigadega sõnad"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Väljas"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Mõõdukas"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Agressiivne"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Väga agressiivne"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agressiivne"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Väga agressiivne"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Järgmise sõna soovitused"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Soovituste tegemisel eelmise sõna kasutamine"</string>
<string name="gesture_input" msgid="826951152254563827">"Luba joonistusega sisestamine"</string>
@@ -143,13 +143,13 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglise (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglise (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"hispaania (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Keel puudub"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Keel puudub (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Keel puudub (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Keel puudub (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Keel puudub (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Keel puudub (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Keel puudub (PC)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Keel puudub (tähestik)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Tähestik (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Tähestik (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Tähestik (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Tähestik (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Tähestik (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Tähestik (PC)"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Kohandage sisendlaadid"</string>
<string name="add_style" msgid="6163126614514489951">"Lisage laad"</string>
<string name="add" msgid="8299699805688017798">"Lisa"</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 501b678e1..5d8951619 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"کلید فاصله و علائم نگارشی به صورت خودکار کلماتی را که غلط تایپ شده‌اند تصحیح می‌کنند"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"خاموش"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"متوسط"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"فعال"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"بسیار پرخاشگرانه"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"شدید"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"بسیار شدید"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"پیشنهادات کلمه بعدی"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"استفاده از کلمه قبلی در ایجاد پیشنهادات"</string>
<string name="gesture_input" msgid="826951152254563827">"فعال کردن تایپ حرکتی"</string>
@@ -147,13 +147,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"انگلیسی (انگلستان) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"انگلیسی (ایالات متحده) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"اسپانیایی (آمریکا) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"زبانی موجود نیست"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"بدون زبان (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"هیچکدام از زبان‌ها (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"هیچکدام از زبان‌ها (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"هیچکدام از زبان‌ها (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"هیچکدام از زبان‌ها (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"هیچکدام از زبان‌ها (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (سنتی)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"بدون زبان (حروف الفبا)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"حروف الفبا (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"حروف الفبا (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"حروف الفبا (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"حروف الفبا (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"حروف الفبا (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"حروف الفبا (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"سبک‌های ورودی سفارشی"</string>
<string name="add_style" msgid="6163126614514489951">"افزودن سبک"</string>
<string name="add" msgid="8299699805688017798">"افزودن"</string>
@@ -163,7 +165,7 @@
<string name="keyboard_layout_set" msgid="4309233698194565609">"چیدمان"</string>
<string name="custom_input_style_note_message" msgid="8826731320846363423">"سبک ورودی سفارشی شما باید قبل از شروع به استفاده از آن فعال شود. می‌خواهید اکنون آن را فعال کنید؟"</string>
<string name="enable" msgid="5031294444630523247">"فعال کردن"</string>
- <string name="not_now" msgid="6172462888202790482">"اکنون خیر"</string>
+ <string name="not_now" msgid="6172462888202790482">"الآن نه"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"سبک ورودی مشابهی در حال حاضر وجود دارد: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"حالت بررسی قابلیت استفاده"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"تأخیر فشار طولانی کلید"</string>
@@ -205,7 +207,7 @@
<string name="dictionary_available" msgid="4728975345815214218">"فرهنگ لغت موجود است"</string>
<string name="dictionary_downloading" msgid="2982650524622620983">"موارد در حال دانلود فعلی"</string>
<string name="dictionary_installed" msgid="8081558343559342962">"نصب شده"</string>
- <string name="dictionary_disabled" msgid="8950383219564621762">"نصب شد، غیرفعال شد"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"نصب‌شده، غیرفعال شد"</string>
<string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"مشکل اتصال به سرویس فرهنگ لغت"</string>
<string name="no_dictionaries_available" msgid="8039920716566132611">"هیچ فرهنگ لغتی موجود نیست"</string>
<string name="check_for_updates_now" msgid="8087688440916388581">"بازخوانی"</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 069666285..4cdf6210e 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -22,12 +22,12 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Syöttövalinnat"</string>
<string name="english_ime_research_log" msgid="8492602295696577851">"Tutkimuslokin komennot"</string>
- <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Hae kontaktien nimiä"</string>
- <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Oikeinkirjoituksen tarkistus käyttää kontaktiluettelosi tietoja."</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Hae yht.tietojen nimiä"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Oikeinkirjoituksen tarkistus käyttää yhteystietojasi."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Käytä värinää näppäimiä painettaessa"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"Toista ääni näppäimiä painettaessa"</string>
<string name="popup_on_keypress" msgid="123894815723512944">"Ponnahdusikkuna painalluksella"</string>
- <string name="general_category" msgid="1859088467017573195">"Yleinen"</string>
+ <string name="general_category" msgid="1859088467017573195">"Yleiset"</string>
<string name="correction_category" msgid="2236750915056607613">"Tekstin korjaus"</string>
<string name="gesture_typing_category" msgid="497263612130532630">"Piirtokirjoitus"</string>
<string name="misc_category" msgid="6894192814868233453">"Muut vaihtoehdot"</string>
@@ -38,34 +38,34 @@
<string name="show_language_switch_key" msgid="5915478828318774384">"Kielenvaihtonäppäin"</string>
<string name="show_language_switch_key_summary" msgid="7343403647474265713">"Näytä, kun käytössä on useita syöttökieliä"</string>
<string name="sliding_key_input_preview" msgid="6604262359510068370">"Näytä liu\'utuksen tilaosoitin"</string>
- <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Näytä visuaalinen vihje liu\'uttaessasi Shift- tai Symbol-näppäim."</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Näytä visuaalinen vihje Vaihto- tai Symbol-näppäim. liu\'uttam."</string>
<string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Näppäimen hylkäysviive"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Ei viivettä"</string>
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Oletus"</string>
<string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> ms"</string>
- <string name="settings_system_default" msgid="6268225104743331821">"Järjest. oletusarvo"</string>
- <string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yhteystietojen nimiä"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Järjestelmän oletusarvo"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yht.tietojen nimiä"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Käytä yhteystietojen nimiä ehdotuksissa ja korjauksissa"</string>
<string name="use_double_space_period" msgid="8781529969425082860">"Kaksoisvälilyönti = piste"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Välilyönnin kaksoisnapautus lisää tekstiin pisteen ja välilyönnin"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string>
<string name="auto_cap_summary" msgid="7934452761022946874">"Kirjoita jokaisen lauseen ensimmäinen sana isolla alkukirjaimella"</string>
<string name="edit_personal_dictionary" msgid="3996910038952940420">"Oma sanakirja"</string>
- <string name="configure_dictionaries_title" msgid="4238652338556902049">"Lisäsanakirjat"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Sanakirjalisäosat"</string>
<string name="main_dictionary" msgid="4798763781818361168">"Pääsanakirja"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Näytä korjausehdotukset"</string>
<string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Näytä sanaehdotukset kirjoitettaessa"</string>
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Näytä aina"</string>
- <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Näytä pystyasennossa"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Näytä pystysuunnassa"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Piilota aina"</string>
<string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Estä loukkaavat sanat"</string>
- <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Älä ehdota mahdollisesti loukkaavia sanoja"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Älä ehdota mahd. loukkaavia sanoja"</string>
<string name="auto_correction" msgid="7630720885194996950">"Autom. korjaus"</string>
- <string name="auto_correction_summary" msgid="5625751551134658006">"Välilyönnit ja välimerkit korjaavat väärinkirjoitetut sanat automaattisesti"</string>
- <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Älä käytä"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Välilyönti ja välimerkit korjaavat väärinkirjoitetut sanat autom."</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Ei käytössä"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Osittainen"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Täysi"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Hyvin aggressiivinen"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressiivinen"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Hyvin aggressiivinen"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Seuraavan sanan ehdotukset"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Käytä edellistä sanaa ehdotuksien perusteena"</string>
<string name="gesture_input" msgid="826951152254563827">"Ota piirtokirjoitus käyttöön"</string>
@@ -73,38 +73,38 @@
<string name="gesture_preview_trail" msgid="3802333369335722221">"Näytä eleen jälki"</string>
<string name="gesture_floating_preview_text" msgid="4443240334739381053">"Dynaaminen kelluva esikatselu"</string>
<string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Näytä ehdotettu sana piirron aikana"</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="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: tallennettu"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Mene"</string>
<string name="label_next_key" msgid="362972844525672568">"Seur."</string>
- <string name="label_previous_key" msgid="1211868118071386787">"Edell"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Edel."</string>
<string name="label_done_key" msgid="2441578748772529288">"Valmis"</string>
- <string name="label_send_key" msgid="2815056534433717444">"Lähetä"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Läh."</string>
<string name="label_pause_key" msgid="181098308428035340">"Tauko"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Odota"</string>
- <string name="spoken_use_headphones" msgid="896961781287283493">"Liitä kuulokkeet kuullaksesi, mitä näppäimiä painat kirjoittaessasi salasanaa."</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Liitä kuulokkeet, niin kuulet mitä näppäimiä painat kirjoittaessasi salasanaa."</string>
<string name="spoken_current_text_is" msgid="2485723011272583845">"Nykyinen teksti on %s"</string>
<string name="spoken_no_text_entered" msgid="7479685225597344496">"Ei kirjoitettua tekstiä"</string>
<string name="spoken_description_unknown" msgid="3197434010402179157">"Näppäimen koodi %d"</string>
- <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Vaihto päällä (napauta poistaaksesi käytöstä)"</string>
- <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps Lock päällä (napauta poistaaksesi käytöstä)"</string>
- <string name="spoken_description_delete" msgid="8740376944276199801">"Poisto"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Vaihto"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Vaihto päällä (poista käytöstä napauttamalla)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps Lock päällä (poista käytöstä napauttamalla)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Poista"</string>
<string name="spoken_description_to_symbol" msgid="5486340107500448969">"Symbolit"</string>
<string name="spoken_description_to_alpha" msgid="23129338819771807">"Kirjaimet"</string>
<string name="spoken_description_to_numeric" msgid="591752092685161732">"Numerot"</string>
<string name="spoken_description_settings" msgid="4627462689603838099">"Asetukset"</string>
<string name="spoken_description_tab" msgid="2667716002663482248">"Sarkain"</string>
<string name="spoken_description_space" msgid="2582521050049860859">"Välilyönti"</string>
- <string name="spoken_description_mic" msgid="615536748882611950">"Puheohjaus"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Äänisyöte"</string>
<string name="spoken_description_smiley" msgid="2256309826200113918">"Hymiö"</string>
- <string name="spoken_description_return" msgid="8178083177238315647">"Enter"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Takaisin"</string>
<string name="spoken_description_search" msgid="1247236163755920808">"Haku"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"Piste"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"Vaihda kieli"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"Seuraava"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"Edellinen"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Vaihto päällä"</string>
- <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps lock päällä"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock päällä"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Vaihto pois käytöstä"</string>
<string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Symbolit-tila"</string>
<string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Näppäimistötila"</string>
@@ -121,13 +121,13 @@
<string name="keyboard_mode_text" msgid="6479436687899701619">"teksti"</string>
<string name="keyboard_mode_time" msgid="4381856885582143277">"aika"</string>
<string name="keyboard_mode_url" msgid="1519819835514911218">"URL-osoite"</string>
- <string name="voice_input" msgid="3583258583521397548">"Ääniohjausavain"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Äänisyöteavain"</string>
<string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Päänäppäimistössä"</string>
- <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Symbolinäppäimistössä"</string>
- <string name="voice_input_modes_off" msgid="3745699748218082014">"Älä näytä"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Symbolinäppäim."</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Ei käytössä"</string>
<string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mikr. päänäppäim."</string>
- <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mikr. symbolinäppäim."</string>
- <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Ääniohjaus on pois käytöstä"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mikr. symbolinäpp."</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Äänisyöte ei käyt."</string>
<string name="configure_input_method" msgid="373356270290742459">"Määritä syöttötavat"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Syöttökielet"</string>
<string name="send_feedback" msgid="1780431884109392046">"Lähetä palautetta"</string>
@@ -140,16 +140,18 @@
<string name="subtype_en_GB" msgid="88170601942311355">"englanti (Iso-Britannia)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"englanti (Yhdysvallat)"</string>
<string name="subtype_es_US" msgid="5583145191430180200">"espanja (Yhdysvallat)"</string>
- <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"englanti (Iso-Britannia) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"englanti (Iso-Br.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"englanti (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"espanja (Yhdysvallat) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Ei kieltä"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Ei kieltä (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Ei kieltä (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Ei kieltä (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Ei kieltä (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Ei kieltä (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Ei kieltä (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (perinteinen)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Ei kieltä (aakkoset)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Aakkoset (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Aakkoset (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Aakkoset (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Aakkoset (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Aakkoset (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Aakkoset (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Muokatut syöttötyylit"</string>
<string name="add_style" msgid="6163126614514489951">"Lisää tyyli"</string>
<string name="add" msgid="8299699805688017798">"Lisää"</string>
@@ -157,10 +159,10 @@
<string name="save" msgid="7646738597196767214">"Tallenna"</string>
<string name="subtype_locale" msgid="8576443440738143764">"Kieli"</string>
<string name="keyboard_layout_set" msgid="4309233698194565609">"Asettelu"</string>
- <string name="custom_input_style_note_message" msgid="8826731320846363423">"Ota muokattu syötetyyli käyttöön käyttääksesi sitä."</string>
- <string name="enable" msgid="5031294444630523247">"Käyttöön"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Muokattua syöttötyyliä ei ole otettu käyttöön. Haluatko ottaa sen käyttöön nyt?"</string>
+ <string name="enable" msgid="5031294444630523247">"Ota käyttöön"</string>
<string name="not_now" msgid="6172462888202790482">"Ei nyt"</string>
- <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sama tulotyyli on jo olemassa: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Syöttötyyli on jo olemassa: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Käytettävyystutkimustila"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Pitkän painalluksen viive"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Painalluksen värinän kesto"</string>
@@ -172,19 +174,19 @@
<string name="error" msgid="8940763624668513648">"Tapahtui virhe"</string>
<string name="button_default" msgid="3988017840431881491">"Oletusarvot"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Tervetuloa käyttämään sovellusta <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="setup_welcome_additional_description" msgid="8150252008545768953">"sekä piirtokirjoitus"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ja piirtokirjoitus"</string>
<string name="setup_start_action" msgid="8936036460897347708">"Aloita"</string>
<string name="setup_next_action" msgid="371821437915144603">"Seuraava vaihe"</string>
<string name="setup_steps_title" msgid="6400373034871816182">"Sovelluksen <xliff:g id="APPLICATION_NAME">%s</xliff:g> asetukset"</string>
<string name="setup_step1_title" msgid="3147967630253462315">"Ota <xliff:g id="APPLICATION_NAME">%s</xliff:g> käyttöön"</string>
- <string name="setup_step1_instruction" msgid="2578631936624637241">"Valitse <xliff:g id="APPLICATION_NAME">%s</xliff:g> kieli- ja syöttötapa-asetuksissa, mikä valtuuttaa sovel. laitteellesi."</string>
- <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> on jo käytössä Kieli- ja syöttöasetuksissa, joten tämä vaihe on tehty. Siirrytään eteenpäin!"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Valitse <xliff:g id="APPLICATION_NAME">%s</xliff:g> Kieli ja syöttötapa -asetuksissa. Se antaa sovellukselle luvan toimia laitteessasi."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> on jo käytössä Kieli ja syöttötapa -asetuksissa, joten tämä vaihe on tehty. Siirrytään eteenpäin!"</string>
<string name="setup_step1_action" msgid="4366513534999901728">"Ota käyttöön asetuksissa"</string>
<string name="setup_step2_title" msgid="6860725447906690594">"Siirry sovellukseen <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_step2_instruction" msgid="9141481964870023336">"Valitse <xliff:g id="APPLICATION_NAME">%s</xliff:g> käytössä olevaksi tekstinsyöttötavaksi."</string>
<string name="setup_step2_action" msgid="1660330307159824337">"Vaihda syöttötapaa"</string>
<string name="setup_step3_title" msgid="3154757183631490281">"Onneksi olkoon, valmista tuli!"</string>
- <string name="setup_step3_instruction" msgid="8025981829605426000">"Nyt voit kirjoittaa kaikkiin lempisovelluksiisi sovelluksen <xliff:g id="APPLICATION_NAME">%s</xliff:g> avulla."</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Nyt voit kirjoittaa kaikissa lempisovelluksissasi sovelluksen <xliff:g id="APPLICATION_NAME">%s</xliff:g> avulla."</string>
<string name="setup_step3_action" msgid="600879797256942259">"Määritä lisää kieliä"</string>
<string name="setup_finish_action" msgid="276559243409465389">"Valmis"</string>
<string name="show_setup_wizard_icon" msgid="5008028590593710830">"Näytä sovelluskuvake"</string>
@@ -199,11 +201,11 @@
<string name="user_dictionaries" msgid="3582332055892252845">"Käyttäjän sanakirjat"</string>
<string name="default_user_dict_pref_name" msgid="1625055720489280530">"Käyttäjän sanakirja"</string>
<string name="dictionary_available" msgid="4728975345815214218">"Sanakirja saatavilla"</string>
- <string name="dictionary_downloading" msgid="2982650524622620983">"Ladataan parhaillaan"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Ladataan"</string>
<string name="dictionary_installed" msgid="8081558343559342962">"Asennettu"</string>
<string name="dictionary_disabled" msgid="8950383219564621762">"Asennettu, poistettu käytöstä"</string>
- <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Ongelma yhdistettässä sanakirjapalveluun"</string>
- <string name="no_dictionaries_available" msgid="8039920716566132611">"Ei sanakirjoja saatavilla"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Ei yhteyttä sanak."</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Ei sanak. saatavilla"</string>
<string name="check_for_updates_now" msgid="8087688440916388581">"Päivitä"</string>
<string name="last_update" msgid="730467549913588780">"Päivitetty viimeksi"</string>
<string name="message_updating" msgid="4457761393932375219">"Tarkistetaan päivityksiä"</string>
@@ -217,8 +219,8 @@
<string name="download_over_metered" msgid="1643065851159409546">"Lataa nyt (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> Mt)"</string>
<string name="do_not_download_over_metered" msgid="2176209579313941583">"Lataa wifi-yhteydellä"</string>
<string name="dict_available_notification_title" msgid="6514288591959117288">"Kielen <xliff:g id="LANGUAGE">%1$s</xliff:g> sanakirja on saatavilla"</string>
- <string name="dict_available_notification_description" msgid="1075194169443163487">"Paina tätä, jos haluat tarkastella kohdetta tai ladata sen"</string>
- <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Ladataan: pian ehdotuksia näytetään kielellä <xliff:g id="LANGUAGE">%1$s</xliff:g>."</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Paina tätä, jos haluat tarkastella kohdetta ja ladata sen"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Ladataan: ehdotuksia näytetään pian kielellä <xliff:g id="LANGUAGE">%1$s</xliff:g>."</string>
<string name="version_text" msgid="2715354215568469385">"Versio <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
<string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Lisää"</string>
<string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Lisää sanakirjaan"</string>
@@ -227,7 +229,7 @@
<string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Väh. vaihtoeht."</string>
<string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
<string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Sana:"</string>
- <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Pikanäppäin"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Pikanäppäin:"</string>
<string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Kieli:"</string>
<string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Kirjoita sana"</string>
<string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Valinnainen pikanäppäin"</string>
diff --git a/java/res/values-fr-rCA/donottranslate.xml b/java/res/values-fr-rCA/donottranslate.xml
new file mode 100644
index 000000000..21f18d852
--- /dev/null
+++ b/java/res/values-fr-rCA/donottranslate.xml
@@ -0,0 +1,31 @@
+<?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
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
+ <!-- This is similar to French with the exception of "!" "?" and ";" which do not take a space before in Canadian French. Note that ":" does take a space before according to Canadian rules. -->
+ <string name="symbols_preceded_by_space">([{&amp;:</string>
+ <!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
+ <string name="symbols_followed_by_space">.,;:!?)]}&amp;</string>
+ <!-- Symbols that separate words -->
+ <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
+ <string name="symbols_word_separators">"&#x0009;&#x0020;\n"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
+ <!-- Word connectors -->
+ <string name="symbols_word_connectors">\'-</string>
+</resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index b5db430ae..e096a1fb8 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Corriger autom. orthographe (pression sur barre espace/signes ponctuation)"</string>
<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_aggressive" msgid="3524029103734923819">"Proactive"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Très exigeante"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Proactive"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Très proactive"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Suggestions pour le mot suivant"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Utiliser le mot précédent pour les suggestions"</string>
<string name="gesture_input" msgid="826951152254563827">"Activer la saisie gestuelle"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Anglais (Royaume-Uni) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Anglais (États-Unis) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Espagnol (États-Unis) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Aucune langue"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Aucune langue (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Aucune langue (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Aucune langue (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Aucune langue (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Aucune langue (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Aucune langue (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditionnel)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Aucune langue (latin)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet latin (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet latin (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alphabet latin (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alphabet latin (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alphabet latin (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alphabet latin (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Styles saisie personnalisés"</string>
<string name="add_style" msgid="6163126614514489951">"Ajouter style"</string>
<string name="add" msgid="8299699805688017798">"Ajouter"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index ca1c838e0..dcbbcd97c 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -31,7 +31,7 @@
<string name="correction_category" msgid="2236750915056607613">"पाठ सुधार"</string>
<string name="gesture_typing_category" msgid="497263612130532630">"जेस्चर लिखना"</string>
<string name="misc_category" msgid="6894192814868233453">"अन्य विकल्प"</string>
- <string name="advanced_settings" msgid="362895144495591463">"उन्नत सेटिंग"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"अतिरिक्त सेटिंग"</string>
<string name="advanced_settings_summary" msgid="4487980456152830271">"विशेषज्ञों के लिए विकल्‍प"</string>
<string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"अन्‍य इनपुट पद्धतियों पर जाएं"</string>
<string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"भाषा स्‍विच कुंजी में अन्‍य इनपुट पद्धतियां भी शामिल हैं"</string>
@@ -41,7 +41,7 @@
<string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Shift या Symbol कुंजियो से स्लाइड करते समय विज़ुअल क्यू दिखाएं"</string>
<string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"कुंजी पॉपअप खारिज़ विलंब"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"कोई विलंब नहीं"</string>
- <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"डिफ़ॉल्ट"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"सामान्य"</string>
<string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> मिलीसेकंड"</string>
<string name="settings_system_default" msgid="6268225104743331821">"सिस्टम डिफ़ॉल्ट"</string>
<string name="use_contacts_dict" msgid="4435317977804180815">"संपर्क नाम सुझाएं"</string>
@@ -50,8 +50,8 @@
<string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबार पर डबल टैप करने से पीरियड शामिल हो जाता है जिसके बाद एक रिक्ति होती है"</string>
<string name="auto_cap" msgid="1719746674854628252">"स्‍वत: अक्षर बड़े करना"</string>
<string name="auto_cap_summary" msgid="7934452761022946874">"प्रत्येक वाक्य के पहले शब्द को बड़ा लिखें"</string>
- <string name="edit_personal_dictionary" msgid="3996910038952940420">"व्यक्तिगत डिक्शनरी"</string>
- <string name="configure_dictionaries_title" msgid="4238652338556902049">"एड-ऑन डिक्शनरी"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"व्यक्तिगत शब्दकोश"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"एड-ऑन शब्दकोश"</string>
<string name="main_dictionary" msgid="4798763781818361168">"मुख्‍य डिक्‍शनरी"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"सुधार सुझाव दिखाएं"</string>
<string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"लिखते समय सुझाए गए शब्‍द दिखाएं"</string>
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Spacebar और विराम चिह्न गलत लिखे गए शब्‍दों को स्‍वचालित रूप से ठीक करते हैं"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"बंद"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"साधारण"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"तीव्र"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"बहुत तीव्र"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"तेज़"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"बहुत तेज़"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"अगले शब्द के सुझाव"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"सुझाव बनाने में पिछले शब्द का उपयोग करें"</string>
<string name="gesture_input" msgid="826951152254563827">"जेस्‍चर लिखना सक्षम करें"</string>
@@ -130,7 +130,7 @@
<string name="voice_input_modes_summary_off" msgid="63875609591897607">"ध्‍वनि इनपुट अक्षम है"</string>
<string name="configure_input_method" msgid="373356270290742459">"इनपुट पद्धति कॉन्‍फ़िगर करें"</string>
<string name="language_selection_title" msgid="1651299598555326750">"इनपुट भाषा"</string>
- <string name="send_feedback" msgid="1780431884109392046">"फ़ीडबैक भेजें"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"सुझाव भेजें"</string>
<string name="select_language" msgid="3693815588777926848">"इनपुट भाषाएं"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"सहेजने के लिए पुन: स्‍पर्श करें"</string>
<string name="has_dictionary" msgid="6071847973466625007">"शब्‍दकोश उपलब्‍ध है"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"अंग्रेज़ी (यूके) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"अंग्रेज़ी (यूएस) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"स्पेनिश (यूएस) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"कोई भाषा नहीं"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"कोई भाषा नहीं (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"कोई भाषा नहीं (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"कोई भाषा नहीं (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"कोई भाषा नहीं (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"कोई भाषा नहीं (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"कोई भाषा नहीं (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (पारंपरिक)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"भाषा उपलब्ध नहीं है (लैटिन वर्णाक्षर)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णाक्षर (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णाक्षर (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"वर्णाक्षर (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"वर्णाक्षर (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"वर्णाक्षर (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"वर्णाक्षर (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"कस्‍टम इनपुट शैलियां"</string>
<string name="add_style" msgid="6163126614514489951">"शैली जोड़ें"</string>
<string name="add" msgid="8299699805688017798">"जोड़ें"</string>
@@ -164,56 +166,56 @@
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"उपयोगिता अध्ययन मोड"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"कुंजी को देर तक दबाने का विलंब"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"कुंजी-स्पर्श कंपन अवधि"</string>
- <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"कुंजी-स्पर्श ध्वनि वॉल्यूम"</string>
- <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"बाहरी डिक्शनरी फ़ाइल पढ़ें"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"कुंजी-स्पर्श ध्वनि आवाज़"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"बाहरी शब्दकोश फ़ाइल पढ़ें"</string>
<string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"डाउनलोड फ़ोल्डर में कोई शब्दकोश फ़ाइल नहीं है"</string>
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"इंस्टॉल करने के लिए कोई शब्दकोश फ़ाइल चुनें"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"<xliff:g id="LOCALE_NAME">%s</xliff:g> के लिए वास्तव में यह फ़ाइल इंस्टॉल करें?"</string>
<string name="error" msgid="8940763624668513648">"कोई त्रुटि हुई थी"</string>
- <string name="button_default" msgid="3988017840431881491">"डिफ़ॉल्ट"</string>
+ <string name="button_default" msgid="3988017840431881491">"सामान्य"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> में आपका स्वागत है"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"हावभाव लेखन के साथ"</string>
<string name="setup_start_action" msgid="8936036460897347708">"आरंभ करें"</string>
<string name="setup_next_action" msgid="371821437915144603">"अगला चरण"</string>
<string name="setup_steps_title" msgid="6400373034871816182">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> सेट करना"</string>
<string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> को सक्षम करें"</string>
- <string name="setup_step1_instruction" msgid="2578631936624637241">"कृपया अपनी भाषा और इनपुट सेटिंग में \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" को चेक करें. इससे वह आपके उपकरण पर चलने के लिए अधिकृत हो जाएगा."</string>
- <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> आपकी भाषा और इनपुट सेटिंग में पहले से सक्षम है, इसलिए यह चरण पूर्ण हो गया है. अगले चरण पर जाएं!"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"कृपया अपनी भाषा और अक्षर सेटिंग में \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" को चेक करें. इससे वह आपके उपकरण पर चलने के लिए अधिकृत हो जाएगा."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> आपकी भाषा और अक्षर सेटिंग में पहले से सक्षम है, इसलिए यह चरण पूर्ण हो गया है. अगले चरण पर जाएं!"</string>
<string name="setup_step1_action" msgid="4366513534999901728">"सेटिंग में सक्षम करें"</string>
<string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> पर स्विच करें"</string>
<string name="setup_step2_instruction" msgid="9141481964870023336">"इसके बाद, \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" को अपनी सक्रिय पाठ-इनपुट पद्धति के रूप में चुनें."</string>
<string name="setup_step2_action" msgid="1660330307159824337">"इनपुट पद्धतियां स्विच करें"</string>
<string name="setup_step3_title" msgid="3154757183631490281">"बधाई हो, आप बिल्कुल तैयार हैं!"</string>
- <string name="setup_step3_instruction" msgid="8025981829605426000">"अब आप <xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ अपने सभी पसंदीदा एप्लिकेशन में लिख सकते हैं."</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"अब आप <xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ अपने सभी पसंदीदा एप्स में लिख सकते हैं."</string>
<string name="setup_step3_action" msgid="600879797256942259">"अतिरिक्त भाषाएं कॉन्फ़िगर करना"</string>
<string name="setup_finish_action" msgid="276559243409465389">"समाप्त"</string>
- <string name="show_setup_wizard_icon" msgid="5008028590593710830">"एप्लिकेशन आइकन दिखाएं"</string>
- <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"लॉन्चर में एप्लिकेशन आइकन प्रदर्शित करें"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"एप्स आइकन दिखाएं"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"लॉन्चर में एप्स आइकन प्रदर्शित करें"</string>
<string name="app_name" msgid="6320102637491234792">"डिक्‍शनरी प्रदाता"</string>
<string name="dictionary_provider_name" msgid="3027315045397363079">"डिक्‍शनरी प्रदाता"</string>
<string name="dictionary_service_name" msgid="6237472350693511448">"डिक्‍शनरी सेवा"</string>
- <string name="download_description" msgid="6014835283119198591">"डिक्‍शनरी अपडेट जानकारी"</string>
- <string name="dictionary_settings_title" msgid="8091417676045693313">"एड-ऑन डिक्शनरी"</string>
- <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"डिक्शनरी उपलब्‍ध"</string>
+ <string name="download_description" msgid="6014835283119198591">"शब्दकोश की नई जानकारी"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"एड-ऑन शब्दकोश"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"शब्दकोश उपलब्‍ध"</string>
<string name="dictionary_settings_summary" msgid="5305694987799824349">"डिक्‍शनरी की सेटिंग"</string>
- <string name="user_dictionaries" msgid="3582332055892252845">"उपयोगकर्ता डिक्शनरी"</string>
- <string name="default_user_dict_pref_name" msgid="1625055720489280530">"उपयोगकर्ता डिक्शनरी"</string>
- <string name="dictionary_available" msgid="4728975345815214218">"डिक्शनरी उपलब्‍ध"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"उपयोगकर्ता शब्दकोश"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"उपयोगकर्ता शब्दकोश"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"शब्दकोश उपलब्‍ध"</string>
<string name="dictionary_downloading" msgid="2982650524622620983">"वर्तमान में डाउनलोड हो रही है"</string>
<string name="dictionary_installed" msgid="8081558343559342962">"इंस्‍टॉल है"</string>
<string name="dictionary_disabled" msgid="8950383219564621762">"इंस्‍टॉल है, अक्षम है"</string>
- <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"डिक्शनरी सेवा से कनेक्ट करने में समस्या"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"शब्दकोश सेवा से कनेक्ट करने में समस्या"</string>
<string name="no_dictionaries_available" msgid="8039920716566132611">"डिक्‍शनरी अनुपलब्‍ध"</string>
<string name="check_for_updates_now" msgid="8087688440916388581">"रीफ़्रेश करें"</string>
- <string name="last_update" msgid="730467549913588780">"अंतिम अपडेट"</string>
- <string name="message_updating" msgid="4457761393932375219">"अपडेट देखे जा रहे हैं"</string>
+ <string name="last_update" msgid="730467549913588780">"अंतिम बार का नई जानकारी"</string>
+ <string name="message_updating" msgid="4457761393932375219">"नई जानकारी देखा जा रहा हैं"</string>
<string name="message_loading" msgid="8689096636874758814">"लोड हो रही है..."</string>
<string name="main_dict_description" msgid="3072821352793492143">"मुख्‍य डिक्‍शनरी"</string>
<string name="cancel" msgid="6830980399865683324">"रद्द करें"</string>
<string name="install_dict" msgid="180852772562189365">"इंस्टॉल करें"</string>
<string name="cancel_download_dict" msgid="7843340278507019303">"रद्द करें"</string>
<string name="delete_dict" msgid="756853268088330054">"हटाएं"</string>
- <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"आपके मोबाइल उपकरण पर चयनित भाषा में डिक्‍शनरी उपलब्‍ध है.&lt;br/&gt; आपके लेखन अनुभव को बेहतर बनाने के लिए हम <xliff:g id="LANGUAGE">%1$s</xliff:g> डिक्‍शनरी को &lt;b&gt;डाउनलोड करने&lt;/b&gt; की अनुशंसा करते हैं.&lt;br/&gt; &lt;br/&gt; 3G पर डाउनलोड होने में एक या दो मिनट लग सकते हैं. यदि आपके पास &lt;b&gt;असीमित डेटा प्लान&lt;/b&gt; नहीं है, तो शुल्‍क लग सकते हैं.&lt;br/&gt; यदि आप अपने डेटा प्लान के बारे में सुनिश्चित नहीं हैं, तो हम अपने आप डाउनलोड प्रारंभ करने के लिए Wi-Fi कनेक्‍शन ढूंढने की अनुशंसा करते हैं.&lt;br/&gt; &lt;br/&gt; युक्ति: आप अपने मोबाइल उपकरण पर &lt;b&gt;सेटिंग&lt;/b&gt; मेनू में &lt;b&gt;भाषा और इनपुट&lt;/b&gt; पर जाकर डिक्‍शनरी डाउनलोड कर सकते हैं और निकाल सकते हैं."</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"आपके मोबाइल उपकरण पर चयनित भाषा में डिक्‍शनरी उपलब्‍ध है.&lt;br/&gt; आपके लेखन अनुभव को बेहतर बनाने के लिए हम <xliff:g id="LANGUAGE">%1$s</xliff:g> डिक्‍शनरी को &lt;b&gt;डाउनलोड करने&lt;/b&gt; की अनुशंसा करते हैं.&lt;br/&gt; &lt;br/&gt; 3G पर डाउनलोड होने में एक या दो मिनट लग सकते हैं. यदि आपके पास &lt;b&gt;असीमित डेटा प्लान&lt;/b&gt; नहीं है, तो शुल्‍क लग सकते हैं.&lt;br/&gt; यदि आप अपने डेटा प्लान के बारे में सुनिश्चित नहीं हैं, तो हम अपने आप डाउनलोड प्रारंभ करने के लिए Wi-Fi कनेक्‍शन ढूंढने की अनुशंसा करते हैं.&lt;br/&gt; &lt;br/&gt; युक्ति: आप अपने मोबाइल उपकरण पर &lt;b&gt;सेटिंग&lt;/b&gt; मेनू में &lt;b&gt;भाषा और अक्षर&lt;/b&gt; पर जाकर डिक्‍शनरी डाउनलोड कर सकते हैं और निकाल सकते हैं."</string>
<string name="download_over_metered" msgid="1643065851159409546">"अभी डाउनलोड करें (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
<string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi से डाउनलोड करें"</string>
<string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g> के लिए डिक्‍शनरी उपलब्‍ध है"</string>
@@ -225,7 +227,7 @@
<string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"वाक्यांश"</string>
<string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"अधिक विकल्प"</string>
<string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"कम विकल्‍प"</string>
- <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"ठीक"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"ठीक है"</string>
<string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"शब्द:"</string>
<string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"शॉर्टकट:"</string>
<string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"भाषा:"</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 8f64ccf3d..0dca64ef0 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Razmak i interpunkcija automatski ispravljaju krive riječi"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Isključeno"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Skromno"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Agresivno"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Vrlo agresivno"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresivno"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Vrlo agresivno"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Prijedlozi za sljedeću riječ"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Koristi se prethodnom riječi u izradi prijedloga"</string>
<string name="gesture_input" msgid="826951152254563827">"Omogući pisanje kretnjama"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"engleski (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"engleski (SAD) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"španjolski (SAD) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Nema jezika"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nema jezika (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nema jezika (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nema jezika (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nema jezika (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nema jezika (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nema jezika (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicionalni)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Nema jezika (abeceda)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abeceda (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abeceda (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Abeceda (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Abeceda (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Abeceda (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Abeceda (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Prilagođeni stilovi unosa"</string>
<string name="add_style" msgid="6163126614514489951">"Dodaj stil"</string>
<string name="add" msgid="8299699805688017798">"Dodaj"</string>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index 6aaf88c68..2abed7401 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Szóköz és központozás automatikusan javítja az elgépelést"</string>
<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_aggressive" msgid="3524029103734923819">"Agresszív"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Nagyon agresszív"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresszív"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Nagyon agresszív"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Következő szóra vonatkozó javaslatok"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Az előző szó felhasználása a javaslatoknál"</string>
<string name="gesture_input" msgid="826951152254563827">"Kézmozdulatokkal gépelés"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"angol (brit) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"angol (amerikai) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"spanyol (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Nincs nyelv"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nincs nyelv (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nincs nyelv (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nincs nyelv (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nincs nyelv (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nincs nyelv (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nincs nyelv (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (hagyományos)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Nincs nyelv (ábécé)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Ábécé (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Ábécé (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Ábécé (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Ábécé (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Ábécé (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Ábécé (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Hangulatjel"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Egyedi bevitelstílusok"</string>
<string name="add_style" msgid="6163126614514489951">"Új stílus"</string>
<string name="add" msgid="8299699805688017798">"Hozzáadás"</string>
diff --git a/java/res/values-hy/donottranslate.xml b/java/res/values-hy/donottranslate.xml
new file mode 100644
index 000000000..4a6d188fb
--- /dev/null
+++ b/java/res/values-hy/donottranslate.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Same list as in English, but add armenian period and comma: -->
+ <!-- U+055D: "՝" ARMENIAN COMMA -->
+ <!-- U+0589: "։" ARMENIAN FULL STOP -->
+ <!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
+ <string name="symbols_followed_by_space">.,;:!?)]}&amp;&#x0589;&#x055D;</string>
+ <!-- Symbols that separate words. Adding armenian period and comma. -->
+ <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
+ <string name="symbols_word_separators">"&#x0009;&#x0020;\n"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"&#x0589;&#x055D;</string>
+</resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index dbac3620b..c73c26c1a 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Bilah spasi dan tanda baca secara otomatis dikoreksi pada kata yang salah ketik"</string>
<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_aggressive" msgid="3524029103734923819">"Agresif"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Sangat agresif"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresif"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Sangat agresif"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Saran kata berikutnya"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Gunakan kata sebelumnya dalam membuat saran"</string>
<string name="gesture_input" msgid="826951152254563827">"Aktifkan pengetikan isyarat"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inggris (Inggris) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inggris (AS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spanyol (AS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Tidak ada bahasa"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Tanpa bahasa (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Tanpa bahasa (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Tanpa bahasa (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Tanpa bahasa (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Tanpa bahasa (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Tanpa bahasa (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Tradisional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Tidak ada bahasa (Abjad)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Abjad (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Abjad (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Abjad (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Abjad (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Gaya masukan khusus"</string>
<string name="add_style" msgid="6163126614514489951">"Tambah gaya"</string>
<string name="add" msgid="8299699805688017798">"Tambahkan"</string>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index a20acc22f..eb8e1e959 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Barra spaziatrice/punteggiatura correggono parole con errori"</string>
<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_aggressive" msgid="3524029103734923819">"Massima"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Massima"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Molto elevata"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Massima"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Suggerimenti parola successiva"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Usa la parola precedente per i suggerimenti"</string>
<string name="gesture_input" msgid="826951152254563827">"Abilita digitazione a gesti"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglese (Regno Unito) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglese (Stati Uniti) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spagnolo (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Nessuna lingua"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nessuna lingua (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nessuna lingua (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nessuna lingua (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nessuna lingua (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nessuna lingua (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nessuna lingua (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradizionale)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Nessuna lingua (alfabeto)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabeto (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabeto (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabeto (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabeto (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Stili personalizzati"</string>
<string name="add_style" msgid="6163126614514489951">"Aggiungi stile"</string>
<string name="add" msgid="8299699805688017798">"Aggiungi"</string>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 526c43186..e71bd3190 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -39,7 +39,7 @@
<string name="show_language_switch_key_summary" msgid="7343403647474265713">"הצג כאשר ניתן להשתמש בשפות קלט מרובות"</string>
<string name="sliding_key_input_preview" msgid="6604262359510068370">"הצג את סמן ההסטה"</string>
<string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"הצג סימון ויזואלי בעת הסטה מ-Shift או ממקשי סמלים"</string>
- <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"עיכוב סגירת חלון קופץ של מקש"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"עיכוב בסגירת חלון קופץ של מקש"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"ללא עיכוב"</string>
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ברירת מחדל"</string>
<string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> אלפ\' שניה"</string>
@@ -51,7 +51,7 @@
<string name="auto_cap" msgid="1719746674854628252">"הפיכת אותיות לרישיות באופן אוטומטי"</string>
<string name="auto_cap_summary" msgid="7934452761022946874">"השתמש באות גדולה במילה הראשונה של כל משפט"</string>
<string name="edit_personal_dictionary" msgid="3996910038952940420">"מילון אישי"</string>
- <string name="configure_dictionaries_title" msgid="4238652338556902049">"הוספת מילונים"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"תוספי מילונים"</string>
<string name="main_dictionary" msgid="4798763781818361168">"מילון ראשי"</string>
<string name="prefs_show_suggestions" msgid="8026799663445531637">"הצג הצעות לתיקונים"</string>
<string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"הצג הצעות למילים בעת הקלדה"</string>
@@ -64,20 +64,20 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"מקש הרווח ופיסוק מתקנים אוטומטית שגיאות הקלדה"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"כבוי"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"מצומצם"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"מחמיר"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"מחמיר מאוד"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"מחמיר"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"מחמיר מאוד"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"הצעות למילה הבאה"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"השתמש במילה הקודמת ביצירת הצעות"</string>
<string name="gesture_input" msgid="826951152254563827">"אפשר הקלדה ללא הרמת אצבע"</string>
<string name="gesture_input_summary" msgid="9180350639305731231">"הזן מילה על ידי החלקת האצבע מאות לאות"</string>
<string name="gesture_preview_trail" msgid="3802333369335722221">"הצג שובל תנועות"</string>
- <string name="gesture_floating_preview_text" msgid="4443240334739381053">"תצוגה מקדימה דינמית צפה"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"תצוגה צפה דינמית"</string>
<string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"ראה את המילה המוצעת תוך כדי הזזת האצבע"</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_go_key" msgid="1635148082137219148">"התחל"</string>
<string name="label_next_key" msgid="362972844525672568">"הבא"</string>
<string name="label_previous_key" msgid="1211868118071386787">"הקודם"</string>
- <string name="label_done_key" msgid="2441578748772529288">"סיום"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"בוצע"</string>
<string name="label_send_key" msgid="2815056534433717444">"שלח"</string>
<string name="label_pause_key" msgid="181098308428035340">"השהה"</string>
<string name="label_wait_key" msgid="6402152600878093134">"המתן"</string>
@@ -93,18 +93,18 @@
<string name="spoken_description_to_alpha" msgid="23129338819771807">"אותיות"</string>
<string name="spoken_description_to_numeric" msgid="591752092685161732">"מספרים"</string>
<string name="spoken_description_settings" msgid="4627462689603838099">"הגדרות"</string>
- <string name="spoken_description_tab" msgid="2667716002663482248">"טאב"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"כרטיסייה"</string>
<string name="spoken_description_space" msgid="2582521050049860859">"רווח"</string>
<string name="spoken_description_mic" msgid="615536748882611950">"קלט קולי"</string>
- <string name="spoken_description_smiley" msgid="2256309826200113918">"פרצוף סמיילי"</string>
- <string name="spoken_description_return" msgid="8178083177238315647">"חזור"</string>
- <string name="spoken_description_search" msgid="1247236163755920808">"חיפוש"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"סמיילי"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"חזרה"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"חפש"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"נקודה"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"החלף שפה"</string>
<string name="spoken_description_action_next" msgid="8636078276664150324">"הבא"</string>
<string name="spoken_description_action_previous" msgid="800872415009336208">"הקודם"</string>
- <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift מופעל"</string>
- <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock מופעל"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift פועל"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Caps Lock פועל"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift מושבת"</string>
<string name="spoken_description_mode_symbol" msgid="7183343879909747642">"מצב סמלים"</string>
<string name="spoken_description_mode_alpha" msgid="3528307674390156956">"מצב אותיות"</string>
@@ -134,7 +134,7 @@
<string name="select_language" msgid="3693815588777926848">"שפות קלט"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"גע שוב כדי לשמור"</string>
<string name="has_dictionary" msgid="6071847973466625007">"מילון זמין"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"הפוך משוב ממשתמשים לפעיל"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"הפעל משוב ממשתמשים"</string>
<string name="prefs_description_log" msgid="7525225584555429211">"עזור לשפר את עורך שיטת הקלט על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסה."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"עיצוב מקלדת"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"אנגלית (בריטניה)"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"אנגלית (בריטניה) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"אנגלית (ארה\"ב) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ספרדית (ארצות הברית) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"ללא שפה"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"אין שפה (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"אין שפה (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"אין שפה (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"אין שפה (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"אין שפה (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"אין שפה (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (מסורתית)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ללא שפה (אלף-בית)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"אלף-בית (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"אלף-בית (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"אלף-בית (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"אלף-בית (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"אלף-בית (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"אלף-בית (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"אמוג\'י"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"סגנונות קלט מותאמים אישית"</string>
<string name="add_style" msgid="6163126614514489951">"הוסף סגנון"</string>
<string name="add" msgid="8299699805688017798">"הוסף"</string>
@@ -161,7 +163,7 @@
<string name="enable" msgid="5031294444630523247">"הפעל"</string>
<string name="not_now" msgid="6172462888202790482">"לא עכשיו"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"סגנון קלט זהה כבר קיים: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"מצב מחקר שימושיות"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"מצב לחקירת שימושיות"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"השהיית לחיצה ארוכה על מקש"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"משך רטט של לחיצת מקש"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"עוצמת קול של לחיצת מקש"</string>
@@ -173,7 +175,7 @@
<string name="button_default" msgid="3988017840431881491">"ברירת מחדל"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"ברוך הבא אל <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"עם הקלדת החלקה"</string>
- <string name="setup_start_action" msgid="8936036460897347708">"התחל"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"תחילת העבודה"</string>
<string name="setup_next_action" msgid="371821437915144603">"השלב הבא"</string>
<string name="setup_steps_title" msgid="6400373034871816182">"הגדרת <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_step1_title" msgid="3147967630253462315">"הפעל את <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
@@ -184,11 +186,11 @@
<string name="setup_step2_instruction" msgid="9141481964870023336">"בשלב הבא, בחר ב-\'<xliff:g id="APPLICATION_NAME">%s</xliff:g>\' כאמצעי הקלט הפעיל להזנת טקסט."</string>
<string name="setup_step2_action" msgid="1660330307159824337">"החלף שיטות קלט"</string>
<string name="setup_step3_title" msgid="3154757183631490281">"ברכותינו, הכל מוכן!"</string>
- <string name="setup_step3_instruction" msgid="8025981829605426000">"כעת תוכל להקליד בכל היישומים המועדפים עליך באמצעות <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"כעת תוכל להקליד בכל האפליקציות המועדפות עליך באמצעות <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
<string name="setup_step3_action" msgid="600879797256942259">"הגדר שפות נוספות"</string>
<string name="setup_finish_action" msgid="276559243409465389">"סיום"</string>
- <string name="show_setup_wizard_icon" msgid="5008028590593710830">"הצג את סמל היישום"</string>
- <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"הצג את סמל היישום במפעיל"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"הצג את סמל האפליקציה"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"הצג את סמל האפליקציה במפעיל"</string>
<string name="app_name" msgid="6320102637491234792">"ספק המילון"</string>
<string name="dictionary_provider_name" msgid="3027315045397363079">"ספק המילון"</string>
<string name="dictionary_service_name" msgid="6237472350693511448">"שירות מילון"</string>
@@ -209,7 +211,7 @@
<string name="message_updating" msgid="4457761393932375219">"מחפש עדכונים"</string>
<string name="message_loading" msgid="8689096636874758814">"טוען..."</string>
<string name="main_dict_description" msgid="3072821352793492143">"מילון ראשי"</string>
- <string name="cancel" msgid="6830980399865683324">"ביטול"</string>
+ <string name="cancel" msgid="6830980399865683324">"בטל"</string>
<string name="install_dict" msgid="180852772562189365">"התקן"</string>
<string name="cancel_download_dict" msgid="7843340278507019303">"בטל"</string>
<string name="delete_dict" msgid="756853268088330054">"מחק"</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 5a5ff432a..4d3f155bb 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"誤入力をスペースまたは句読点キーで修正する"</string>
<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_aggressive" msgid="3524029103734923819">"強"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"最も強い"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"強"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"最も強い"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"次の入力候補"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"前の単語に基づいて入力候補を表示します"</string>
<string name="gesture_input" msgid="826951152254563827">"ジェスチャー入力を有効にする"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"英語 (英国) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"英語 (米国) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"スペイン語 (米国) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"言語設定なし"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"言語設定なし (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"言語設定なし (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"言語設定なし (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"言語設定なし (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"言語設定なし (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"言語設定なし (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g>(伝統言語)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"言語なし(アルファベット)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"アルファベット(QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"アルファベット(QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"アルファベット(AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"アルファベット(Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"アルファベット(Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"アルファベット(PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"絵文字"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"カスタム入力スタイル"</string>
<string name="add_style" msgid="6163126614514489951">"スタイル追加"</string>
<string name="add" msgid="8299699805688017798">"追加"</string>
diff --git a/java/res/values-ka-rGE/strings.xml b/java/res/values-ka-rGE/strings.xml
new file mode 100644
index 000000000..043c14c94
--- /dev/null
+++ b/java/res/values-ka-rGE/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"შეყვანის მეთოდები"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"კვლევის აღრიცხვის ბრძანებები"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"კონტაქტებში ძებნა"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"კონტაქტების სიის გამოყენება მართლწერის შემოწმებისას"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"ვიბრაცია კლავიშზე დაჭერისას"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"ხმა კლავიშზე დაჭერისას"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"გადიდება ღილაკზე დაჭერისას"</string>
+ <string name="general_category" msgid="1859088467017573195">"ძირითადი"</string>
+ <string name="correction_category" msgid="2236750915056607613">"ტექსტის კორექცია"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"ჟესტებით წერა"</string>
+ <string name="misc_category" msgid="6894192814868233453">"სხვა პარამეტრები"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"გაფართოებული პარამეტრები"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"პარამეტრები ექსპერტთათვის"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"შეყვანის სხვა მეთოდებზე გადართვა"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"ენის გადართვის ღილაკს შეყვანის სხვა მეთოდებსაც შეიცავს"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"ენის გადართვის კლავიში"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"აჩვენე, როდესაც ჩართულია სხვადასხვა შეყვანის ენა"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"გასრიალების ინდიკატ. ჩვენება"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Shift ან Symbol კლავიშებიდან გასრიალებისას ვიზუალური მინიშნების ჩვენება"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"ამომხტ.კლავიშის დაყოვნება"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"არ დაყოვნდეს"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"ნაგულისხმევი"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>მწმ"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"სისტემის ნაგულისხმევი"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"კონტაქტის სახელების შეთავაზება"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"კონტაქტებიდან სახელების გამოყენება შეთავაზებებისთვის და კორექციისთვის"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"წერტილი ორმაგი შორისით"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"შორისზე ორჯერ შეხება დაწერს წერტილს და შორისის სიმბოლოს"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ავტო-კაპიტალიზაცია"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"ყოველი წინადადების პირველი სიტყვის კაპიტალიზაცია"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"პერსონალური ლექსიკონი"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"დამატებითი ლექსიკონები"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"მთავარი ლექსიკონი"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"კორექციის შეთავაზებების ჩვენება"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"წერისას შეთავაზებული სიტყვების ჩვენება"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"ყოველთვის ჩვენება"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"პორტრეტის რეჟიმში ჩვენება"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"ყოველთვის დამალვა"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"შეურაცხმყოფელი სიტყვების დაბლოკვა"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"არ მოხდეს პოტენციურად შეურაცხმყოფელი სიტყვების შეთავაზება"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"ავტოკორექცია"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"შორისი და პუნქტუაცია ავტომატურად ასწორებს არასწორად აკრეფილ სიტყვებს"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"გამორთვა"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"მოკრძალებული"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"აგრესიული"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ძალიან აგრესიული"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"შემდეგი სიტყვის შეთავაზებები"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"შეთავაზებებისას წინა სიტყვის გამოყენება"</string>
+ <string name="gesture_input" msgid="826951152254563827">"ჟესტებით წერის ჩართვა"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"სიტყვის შეყვანა ასო-ნიშნებზე გასრიალებით"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"ჟესტიკულაციის კუდის ჩვენება"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"დინამიურად მოლივლივე გადახედვა"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"ჟესტიკულაციისას შეთავაზებული სიტყვის ნახვა"</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>
+ <string name="label_previous_key" msgid="1211868118071386787">"წინა"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"დასრულდა"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"გაგზ."</string>
+ <string name="label_pause_key" msgid="181098308428035340">"პაუზა"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"მოცდა"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"შეაერთეთ ყურსაცვამი, რათა მოისმინოთ აკრეფილი პაროლის კლავიშების სახელები."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"მიმდინარე ტექსტი არის %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"ტექსტი არ შეყვანილა"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"კლავიატურის კოდი %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift ჩართულია (შეეხეთ გამოსართავად)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"ჩართულია Caps (შეეხეთ გამოსართავად)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Delete"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"სიმბოლოები"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"ასოები"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"ნომრები"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"პარამეტრები"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"შორისი"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"ხმოვანი შეყვანა"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"ღიმილი"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"დაბრუნება"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"ძიება"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"წერტილი"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"ენის გადართვა"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"შემდეგი"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"წინა"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift ჩართულია"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"ჩართულია Caps"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift გამორთულია"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"სიმბოლოების რეჟიმი"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"ასოების რეჟიმი"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"ტელეფონის რეჟიმი"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"ტელეფონის სიმბოლოების რეჟიმი"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"კლავიატურა დამალულია"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"ნაჩვენებია <xliff:g id="MODE">%s</xliff:g> კლავიატურა"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"თარიღი"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"თარიღი და დრო"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"ელფოსტა"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"შეტყობინებები"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"რიცხვები"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"ტელეფონი"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"ტექსტი"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"დრო"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"ხმოვანი შეყვანის კლავიში"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"მთავარ კლავიატურაზე"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"სიმბოლოთა კლავიატურაზე"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"გამორთვა"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"მიკროფონი მთავარ კლავიატურაზე"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"მიკროფონი სიმბოლოთა კლავიატურაზე"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"ხმოვანი შეყვანა გამორთულია"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"შეყვანის მეთოდების კონფიგურაცია"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"შეყვანის ენები"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"უკუკავშირის გაგზავნა"</string>
+ <string name="select_language" msgid="3693815588777926848">"შეყვანის ენები"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"შეეხეთ ისევ შესანახად"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"ხელმისაწვდომია ლექსიკონი"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"მომხმარებლის უკუკავშირის ჩართვა"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"შეიტანეთ წვლილი შეყვანის ამ მეთოდის გაუმჯობესებაში — გააგზავნეთ მოხმარების სტატისტიკა და ავარიული გათიშვების ანგარიშები"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"კლავიატურის თემა"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"ინგლისური (გართ. სამ.)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"ინგლისური (აშშ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"ესპანური (აშშ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"ინგლისური (გაერთ. სამ.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"ინგლისური (აშშ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ესპანური (აშშ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (ტრადიციული)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ენის გარეშე (ანბანი)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ანბანი (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ანბანი (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"ანბანი (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"ანბანი (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"ანბანი (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"ანბანი (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"სიცილაკები"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"შეყვანის სტილების კონფიგურაცია"</string>
+ <string name="add_style" msgid="6163126614514489951">"სტილის დამატება"</string>
+ <string name="add" msgid="8299699805688017798">"დამატება"</string>
+ <string name="remove" msgid="4486081658752944606">"ამოშლა"</string>
+ <string name="save" msgid="7646738597196767214">"შენახვა"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"ენა"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"განლაგება"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"თქვენი მორგებული შეყვანის სტილი გამოყენებამდე უნდა გაააქტიუროთ. გსურთ მისი აქტივაცია ახლა?"</string>
+ <string name="enable" msgid="5031294444630523247">"ჩართვა"</string>
+ <string name="not_now" msgid="6172462888202790482">"ახლა არა"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"შეყვანის იგივე სტილი უკვე არსებობს: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"გამოყენებადობის კვლევის რეჟიმი"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"კლავიშზე გრძელი დაჭერის დაყოვნება"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"კლავიშზე დაჭერის ვიბრაციის ხანგრძლივობა"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"კლავიშზე დაჭერის ხმა"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"გარე ლექსიკონის ფაილის წაკითხვა"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"ჩამოტვირთვების საქაღალდეში ლექსიკონის ფაილები არ არის"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ინსტალაციისათვის აირჩიეთ ლექსიკონის ფაილი"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"ნამდვილად გსურთ ამ ფაილის <xliff:g id="LOCALE_NAME">%s</xliff:g>-ისთვის ინსტალაცია?"</string>
+ <string name="error" msgid="8940763624668513648">"წარმოიშვა შეცდომა"</string>
+ <string name="button_default" msgid="3988017840431881491">"ნაგულისხმევი"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"კეთილი იყოს თქვენი მობრძანება <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ში"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"ჟესტებით წერით"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"დაწყება"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"შემდეგი საფეხური"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"მიმდინარეობს <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ის დაყენება"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-ის ჩართვა"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"გთხოვთ მონიშნოთ „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“ თქვენი ენის და შეყვანის პარამეტრებში. ეს უფლებას მიცემს მას გაეშვას თქვენს მოწყობილობაზე."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> უკვე გააქტიურებულია თქვენი ენის შეყვანის პარამეტრებში, ასე რომ ეს საფეხური დასრულებულია. გადადით შემდეგ საფეხურზე!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"პარამეტრებში გააქტიურება"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"გადართეთ <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ზე"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"შემდეგ, აირჩიეთ „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“ თქვენს აქტიურ შეყვანის მეთოდად."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"შეყვანის მეთოდების გადართვა"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"გილოცავთ, პროცესი დასრულდა!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"ამიერიდან შეძლებთ ყველა სასურველ აპში <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ით წერას."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"დამატებითი ენების კონფიგურაცია"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"დასრულებული"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"აპის ხატულის ჩვენება"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"გაშვების ხატულის ჩვენება გამშვებში"</string>
+ <string name="app_name" msgid="6320102637491234792">"ლექსიკონის პროვაიდერი"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"ლექსიკონის პროვაიდერი"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"ლექსიკონის სერვისი"</string>
+ <string name="download_description" msgid="6014835283119198591">"ლექსიკონის განახლების მონაცემები"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"დამატებითი ლექსიკონები"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"ხელმისაწვდომია ლექსიკონი"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"ლექსიკონების პარამეტრები"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"მომხმარებლის ლექსიკონები"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"მომხმარებლის ლექსიკონი"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"ხელმისაწვდომია ლექსიკონი"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"მიმდინარეობს ჩამოტვირთვა"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"დაყენებულია"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"დაყენებულია, გაუქმებულია"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"ლექსიკონის სერვისთან დაკავშირებით პრობლემა წარმოიშვა"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"ლექსიკონები მიუწვდომელია"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"განახლება"</string>
+ <string name="last_update" msgid="730467549913588780">"ბოლო განახლება"</string>
+ <string name="message_updating" msgid="4457761393932375219">"მიმდინარეობს განახლებების შემოწმება"</string>
+ <string name="message_loading" msgid="8689096636874758814">"იტვირთება…"</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"მთავარი ლექსიკონი"</string>
+ <string name="cancel" msgid="6830980399865683324">"გაუქმება"</string>
+ <string name="install_dict" msgid="180852772562189365">"ინსტალაცია"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"გაუქმება"</string>
+ <string name="delete_dict" msgid="756853268088330054">"წაშლა"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"თქვენ მიერ მობილურ მოწყობილობაზე არჩეული ენისათვის ხელმისაწვდომია ლექსიკონი.&lt;br/&gt; გირჩევთ, &lt;b&gt;ჩამოტვირთოთ&lt;/b&gt; <xliff:g id="LANGUAGE">%1$s</xliff:g> ლექსიკონი, რათა გაიმარტივოთ ტექსტის შეყვანა.&lt;br/&gt; &lt;br/&gt; ჩამოტვირთვას შესაძლოა დაჭირდეს ერთი ან ორი წუთი 3G სისწრაფეზე. თუ ულიმიტო არ გაქვთ &lt;b&gt; მობილური ინტერნეტის ტარიფი&lt;/b&gt;.&lt;br/&amp;gt, შესაძლოა ჩამოტვირთვა დამატებით გადასახადებთან იყოს დაკავშირებული; თუ არ ხართ დარწმუნებული მობილური ინტერნეტის აქტიური ტარიფის შესახებ, გირჩევთ იპოვოთ Wi-Fi კავშირი და ავტომატურად დაიწყოთ ჩამოტვირთვა.&lt;br/&gt; &lt;br/&gt; რჩევა: ლექსიკონების ჩამოტვირთვა და ამოშლა შესაძლებელია სექციიდან &lt;b&gt;ენა და შეყვანა&lt;/b&gt; სექციიდან, თქვენი მობილური მოწყობილობის &lt;b&gt;პარამეტრების&lt;/b&gt; მენიუში."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"ახლა ჩამოტვირთვა (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>მბაიტი)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi კავშირზე ჩამოტვირთვა"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g>-ისთვის ხელმისაწვდომია ლექსიკონი"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"დააჭირეთ განხილვას და ჩამოტვირთეთ"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"ჩამოტვირთვა: <xliff:g id="LANGUAGE">%1$s</xliff:g>-ის შემოთავაზებები მალე მომზადდება."</string>
+ <string name="version_text" msgid="2715354215568469385">"ვერსია <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"დამატება"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"ლექსიკონში დამატება"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"ფრაზა"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"მეტი ვარიანტები"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"ნაკლები ვარიანტები"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"კარგი"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"სიტყვა:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"მალსახმობი:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ენა:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"შიყვანეთ სიტყვა"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"არასავალდებულო მალსა"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"სიტყვის შესწორება"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"რედაქტირება"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"წაშლა"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"თქვენ არ გაქვთ სიტყვები მომხმარებლის ლექსიკონში. დაამატეთ სიტყვები ღილაკ Add (+) შეხებით."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"ყველა ენისთვის"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"სხვა ენები…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"წაშლა"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-ka/strings-appname.xml b/java/res/values-ka/strings-appname.xml
deleted file mode 100644
index 703c66aac..000000000
--- a/java/res/values-ka/strings-appname.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="english_ime_name" msgid="5940510615957428904">"Android-ის კლავიატურა (AOSP)"</string>
- <string name="spell_checker_service_name" msgid="1254221805440242662">"Android-ის მართლწერის შემმოწმებელი (AOSP)"</string>
- <string name="english_ime_settings" msgid="5760361067176802794">"Android-ის კლავიატურის პარამეტრები (AOSP)"</string>
- <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android-ის მართლწერის შემმოწმებლის პარამეტრები (AOSP)"</string>
-</resources>
diff --git a/java/res/values-ka/strings.xml b/java/res/values-ka/strings.xml
index f83e21dd9..211e92328 100644
--- a/java/res/values-ka/strings.xml
+++ b/java/res/values-ka/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"შორისი და პუნქტუაცია ავტომატურად ასწორებს არასწორად აკრეფილ სიტყვებს"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"გამორთულია"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"მოკრძალებული"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"აგრესიული"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"ძალიან აგრესიული"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"აგრესიული"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"ძალიან აგრესიული"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"შემდეგი სიტყვის შეთავაზებები"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"შეთავაზებებისას წინა სიტყვის გამოყენება"</string>
<string name="gesture_input" msgid="826951152254563827">"ჟესტებით წერის ჩართვა"</string>
@@ -143,13 +143,13 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"ინგლისური (გაერთ. სამ.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"ინგლისური (აშშ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"ესპანური (აშშ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"ენის გარეშე"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"ენის გარეშე (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"ენის გარეშე (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"ენის გარეშე (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"ენის გარეშე (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"ენის გარეშე (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"ენის გარეშე (PC)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ენის გარეშე (ანბანი)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ანბანი (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ანბანი (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"ანბანი (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"ანბანი (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"ანბანი (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"ანბანი (PC)"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"შეყვანის სტილების კონფიგურაცია"</string>
<string name="add_style" msgid="6163126614514489951">"სტილის დამატება"</string>
<string name="add" msgid="8299699805688017798">"დამატება"</string>
diff --git a/java/res/values-km/donottranslate.xml b/java/res/values-km/donottranslate.xml
new file mode 100644
index 000000000..a9893feec
--- /dev/null
+++ b/java/res/values-km/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Whether this language uses spaces between words -->
+ <bool name="current_language_has_spaces">false</bool>
+</resources>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index b1bfe1139..a74b4f1f4 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"스페이스바와 문장부호 키를 사용하면 오타가 자동으로 교정됩니다."</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"사용 안함"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"약"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"중"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"강"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"강력"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"매우 강력"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"다음 단어 추천"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"추천할 때 이전 단어를 사용"</string>
<string name="gesture_input" msgid="826951152254563827">"제스처 타이핑 사용"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"영어(영국) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"영어(미국) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"스페인어(미국)(<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"언어가 없음"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"언어가 없음(QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"언어 없음(QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"언어 없음(AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"언어 없음(드보락)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"언어 없음(콜맥)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"언어 없음(PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g>(일반)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"언어 없음(알파벳)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"알파벳(QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"알파벳(QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"알파벳(AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"알파벳(드보락)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"알파벳(콜맥)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"알파벳(PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"이모티콘"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"맞춤 입력 스타일"</string>
<string name="add_style" msgid="6163126614514489951">"스타일 추가"</string>
<string name="add" msgid="8299699805688017798">"추가"</string>
diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index c78c25f86..42a746b60 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -26,14 +26,8 @@
<!-- key_height + key_bottom_gap = popup_key_height -->
<dimen name="popup_key_height">44.8dp</dimen>
- <fraction name="keyboard_top_padding">1.818%p</fraction>
- <fraction name="keyboard_bottom_padding">0.0%p</fraction>
- <fraction name="key_bottom_gap">4.330%p</fraction>
- <fraction name="key_horizontal_gap">0.405%p</fraction>
-
- <fraction name="key_bottom_gap_stone">5.010%p</fraction>
- <fraction name="key_horizontal_gap_stone">1.159%p</fraction>
-
+ <fraction name="keyboard_top_padding_gb">1.818%p</fraction>
+ <fraction name="keyboard_bottom_padding_gb">0.0%p</fraction>
<fraction name="key_bottom_gap_gb">5.941%p</fraction>
<fraction name="key_horizontal_gap_gb">0.997%p</fraction>
@@ -53,7 +47,7 @@
<fraction name="key_uppercase_letter_ratio">40%</fraction>
<fraction name="key_preview_text_ratio">90%</fraction>
<fraction name="spacebar_text_ratio">40.000%</fraction>
- <dimen name="key_preview_offset">0.0dp</dimen>
+ <dimen name="key_preview_offset_gb">0.0dp</dimen>
<!-- For 5-row keyboard -->
<fraction name="key_bottom_gap_5row">3.20%p</fraction>
@@ -72,11 +66,18 @@
<!-- popup_key_height x 1.2 -->
<dimen name="more_keys_keyboard_slide_allowance">53.76dp</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="more_keys_keyboard_vertical_correction">-44.8dp</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction_gb">-44.8dp</dimen>
<!-- Gesture floating preview text parameters -->
<dimen name="gesture_floating_preview_text_size">23dp</dimen>
<dimen name="gesture_floating_preview_text_offset">54dp</dimen>
<dimen name="gesture_floating_preview_horizontal_padding">23dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">15dp</dimen>
+
+ <!-- Emoji keyboard -->
+ <fraction name="emoji_keyboard_key_width">10%p</fraction>
+ <fraction name="emoji_keyboard_row_height">50%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">60%p</fraction>
+ <integer name="emoji_keyboard_max_key_count">20</integer>
+
</resources>
diff --git a/java/res/values-lo/donottranslate.xml b/java/res/values-lo/donottranslate.xml
new file mode 100644
index 000000000..a9893feec
--- /dev/null
+++ b/java/res/values-lo/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Whether this language uses spaces between words -->
+ <bool name="current_language_has_spaces">false</bool>
+</resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 26f1b27ff..6110858dd 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Tarpo kl. ir skyr. ženkl. aut. išt. neteis. įv. žodž."</string>
<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_aggressive" msgid="3524029103734923819">"Atkaklus"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Labai agresyviai"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Atkakliai"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Labai atkakliai"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Kito žodžio pasiūlymai"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Sudarant pasiūlymus naudoti ankstesnį žodį"</string>
<string name="gesture_input" msgid="826951152254563827">"Įgalinti teksto vedimą gestais"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Angliška (JK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Angliška (JAV) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Ispanų k. (JAV) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Kalbos nėra"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nėra kalbos (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nėra kalbos (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nėra kalbos (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nėra kalbos (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nėra kalbos (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nėra kalbos (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicinė)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Kalbos nėra (abėcėlė)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abėcėlė (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abėcėlė (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Abėcėlė (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Abėcėlė (Dvorako)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Abėcėlė („Colemak“)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Abėcėlė (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Jaustukai"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Pasirinkti įvesties stilių"</string>
<string name="add_style" msgid="6163126614514489951">"Prid. stilių"</string>
<string name="add" msgid="8299699805688017798">"Pridėti"</string>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index cdf04cca6..ecd4e511d 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Atstarpes taustiņš un interpunkcija; automātiska kļūdainu vārdu labošana"</string>
<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_aggressive" msgid="3524029103734923819">"Agresīva"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Ļoti radikāla"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresīvi"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Ļoti agresīvi"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Nākamā vārda ieteikumi"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Veidojot ieteikumus, izmantot iepriekšējo vārdu."</string>
<string name="gesture_input" msgid="826951152254563827">"Iespējot ievadi ar žestiem"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Angļu (Lielbritānija) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Angļu (ASV) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spāņu (ASV) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Nav valodas"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nav valodas (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nav valodas (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nav valodas (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nav valodas (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nav valodas (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nav valodas (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicionālā)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Nav valodas (alfabēts)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabēts (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabēts (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabēts (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabēts (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabēts (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabēts (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Japāņu emocijzīmes"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Pielāg. ievades stili"</string>
<string name="add_style" msgid="6163126614514489951">"Piev. stilu"</string>
<string name="add" msgid="8299699805688017798">"Pievienot"</string>
diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml
new file mode 100644
index 000000000..92c2befa2
--- /dev/null
+++ b/java/res/values-mn-rMN/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Оруулах сонголтууд"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Судалгааны протоколын командууд"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Харилцагчийн нэр хайх"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Алдаа шалгагч нь таны харилцагчдын жагсаалтаас ашиглана"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Товч дарахад чичрэх"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Товч дарахад дуу гаргах"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Товч дарахад попап гарна"</string>
+ <string name="general_category" msgid="1859088467017573195">"Ерөнхий"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Текст залруулалт"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Зангаагаар бичих"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Бусад сонголтууд"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Дэлгэрэнгүй тохиргоо"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Экспертүүдэд зориулсан тохиргоо"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Оруулах өөр арга руу шилжүүлэх"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Хэл солих түлхүүрт өөр оруулах аргууд мөн багтсан байгаа"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Хэл солих товч"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Оруулах хэл олныг идэвхжүүлсэн үед харуулах"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Гулсалт заагчийг харуулах"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Сэлгэх буюу Симбол товчуудаас гулсах үед нүдэнд харагдуулах"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Товчны попап арилах хугацаа"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Хүлээхгүй"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Үндсэн"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>мс"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Системийн үндсэн утга"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Харилцагчдын нэрс санал болгох"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Санал болгох, залруулахда Харилцагчдын нэрсээс ашиглах"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Давхар зайтай цэг"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Ардаа зайтай цэг оруулахын тулд Зай авах дээр давхар товшино уу"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Автоматаар томруулах"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Өгүүлбэр бүрийн эхний үгийн эхний үсгийг томруулах"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Хувийн толь бичиг"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Нэмэлт толь бичгүүд"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Үндсэн толь бичиг"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Залруулах санал болголтуудыг харуулах"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Бичих явцад санал болгосон үгсийг харуулах"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Байнга харуулах"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Босоо горимд харуулах"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Байнга нуух"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Доромжилсон үгсийг хаах"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Доромжилсон үгсийг санал болгохгүй байх"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Авто-залруулга"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Хоосон зай болон цэг таслал нь буруу бичсэн үгсийг автоматаар залруулна"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Идэвхгүй"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Хүлээцтэй"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Хүчтэй"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Маш хүчтэй"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Дараагийн-үг санал болгох"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Өмнөх үгийг үг санал болгоход ашиглах"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Зангаагаар бичихийг идэвхжүүлэх"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Үсгүүд дээр гулсуулах замаар үг оруулах"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Зангасан мөрийг харуулах"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Динамик хөвөгчөөр урьдчилан харах"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Зангах явцад санал болгож буй үгийг харах"</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>
+ <string name="label_previous_key" msgid="1211868118071386787">"Өмнөх"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Дууссан"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Илгээх"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Пауз"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Хүлээх"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Нууц үгний товчнуудыг чангаар уншихыг сонсохын тулд чихэвчээ залгана уу."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Одоогийн текст %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Текст оруулаагүй"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Товчийн код %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Сэлгэх"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Сэлгэхийг идэвхжүүлсэн (товшиж идэвхгүйжүүлнэ үү)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Томоор бичихийг асаасан (товшиж идэвхгүйжүүлнэ үү)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Устгах"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Симбол"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Үсэгнүүд"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Тоонууд"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Тохиргоо"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Таб"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Хоосон зай"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Дуугаар оруулах"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Инээсэн царай"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Буцах"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Хайх"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Цэг"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Хэл солих"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Дараах"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Өмнөх"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Сэлгэхийг идэвхжүүлсэн"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Томоор бичихийг идэвхжүүлсэн"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Сэлгэхийг идэвхжүүлээгүй"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Симбол төлөв"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Үсэгнүүд төлөв"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Утасны төлөв"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Утасны символ төлөв"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Гарыг нуусан"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"<xliff:g id="MODE">%s</xliff:g> гарыг харуулж байна"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"огноо"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"огноо болон цаг"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"и"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"зурвас"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"дугаар"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"утас"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"текст"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"цаг"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Дуун оруулгын товч"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Үндсэн гар дээр"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Симбол гар дээр"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Идэвхгүй"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Мик үндсэн гар дээр"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Мик симбол гар дээр"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Дуун оруулах идэвхгүйжсэн"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Оруулах аргуудын тохиргоо"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Оруулах хэл"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Санал хүсэлт илгээх"</string>
+ <string name="select_language" msgid="3693815588777926848">"Оруулах хэл"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Хадгалахын тулд дахин хүрнэ үү"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Толь бичиг байна"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Хэрэглэгчийн санал хүсэлтийг идэвхжүүлэх"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Ашиглалтын статистик болон гацалтын репортуудыг автоматаар илгээснээр энэ оруулах арга засагчийг сайжруулахад туслаарай"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Гарын загвар"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"Англи (ИБ)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"Англи (АНУ)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"Испани (АНУ)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Англи (ИБ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Англи (АНУ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Испани (АНУ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Уламжлалт)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Хэл байхгүй (Цагаан толгой)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Цагаан толгой (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Цагаан толгой (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Цагаан толгой (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Цагаан толгой (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Цагаан толгой (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Цагаан толгой (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Инээмсэглэл"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Өөрийн оруулах загвар"</string>
+ <string name="add_style" msgid="6163126614514489951">"Загвар нэмэх"</string>
+ <string name="add" msgid="8299699805688017798">"Нэмэх"</string>
+ <string name="remove" msgid="4486081658752944606">"Устгах"</string>
+ <string name="save" msgid="7646738597196767214">"Хадгалах"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Хэл"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Байршил"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Та өөрийн оруулах загварыг ашиглахаас өмнө идэвхжүүлэх шаардлагатай. Одоо идэвхжүүлэх үү?"</string>
+ <string name="enable" msgid="5031294444630523247">"Идэвхжүүлэх"</string>
+ <string name="not_now" msgid="6172462888202790482">"Одоо биш"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ижилхэн оруулах загвар байна: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Ашиглалтын судалгааны горим"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Товч удаан дарах хугацааны тохиргоо"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Товч дарах чичиргээний хугацаа"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Товчны дууны хэмжээ"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Толь бичгийн гадны файлыг унших"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Татаж авсан фолдерт толь бичгийн файл байхгүй байна"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Суулгах толь бичгийн файлыг сонгоно уу"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"<xliff:g id="LOCALE_NAME">%s</xliff:g>-д зориулсан энэ файлыг үнэхээр суулгах уу?"</string>
+ <string name="error" msgid="8940763624668513648">"Алдаа гарсан"</string>
+ <string name="button_default" msgid="3988017840431881491">"Үндсэн"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Та <xliff:g id="APPLICATION_NAME">%s</xliff:g>-д тавтай морилно уу"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"Зангаагаар бичихээр"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Эхлэх"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Дараагийн алхам"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-г тохируулж байна"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-г идэвхжүүлэх"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Өөрийн Хэл &amp; оруулах тохиргоон дотроос \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\"-г сонгоно уу. Ингэснээр таны төхөөрөмж дээр ажиллах зөвшөөрлийг өгөх болно."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> таны Хэл &amp;amp оруулах тохиргоонд аль хэдийн идэвхжүүлсэн байгаа учир энэ алхам хийгдсэн. Дараагийн алхам руу!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Тохиргоо дотроос идэвхжүүлэх"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> рүү шилжих"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Дараа нь \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\"-г өөрийн идэвхтэй текст-оруулах аргаар сонгоно уу."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Оруулах аргыг солих"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Баяр хүргэе, та бүгдийг нь тохируулчихлаа!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Та одоо өөрийн дуртай апп-ууд дотроо <xliff:g id="APPLICATION_NAME">%s</xliff:g> ашиглан бичих болохоор боллоо."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Нэмэлт хэлнүүдийг тохируулах"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Дууссан"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Апп дүрсийг харуулах"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Эхлүүлэгч дээр аппликешний дүрсийг харуулах"</string>
+ <string name="app_name" msgid="6320102637491234792">"Толь бичгээр хангагч"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Толь бичгээг хангагч"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Толь бичгийн үйлчилгээ"</string>
+ <string name="download_description" msgid="6014835283119198591">"Толь бичгийн шинэчлэлтийн мэдээлэл"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Нэмэлт толь бичгүүд"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Толь бичиг байна"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Толь бичгийн тохиргоо"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"Хэрэглэгчийн толь бичиг"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"Хэрэглэгчийн толь"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Толь бичиг байна"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Одоо татаж байна"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Суулгасан"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Суулгасан, идэвхгүйжүүлсэн"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Толь бичгийн үйлчилгээнд холбогдоход алдаа гарлаа"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Толь бичиг байхгүй"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Дахин шинэчлэх"</string>
+ <string name="last_update" msgid="730467549913588780">"Сүүлд шинэчлэгдсэн"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Шинэчлэлтийг шалгаж байна"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Ачаалж байна..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Үндсэн толь бичиг"</string>
+ <string name="cancel" msgid="6830980399865683324">"Цуцлах"</string>
+ <string name="install_dict" msgid="180852772562189365">"Суулгах"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Цуцлах"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Устгах"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Таны мобайль төхөөрөмж дээр сонгосон хэлэнд толь бичиг байна.&lt;br/&gt; Тус  <xliff:g id="LANGUAGE">%1$s</xliff:g> толь бичгийг &lt;b&gt;татаж аван&lt;/b&gt; зөв бичилтээ сайжруулахыг бид зөвлөж байна.&lt;br/&gt; &lt;br/&gt; Татаж авахад 3G сүлжээгээр нэг хоёр минут болно. Танд &lt;b&gt;хязгааргүй дата эрх&lt;/b&gt; байхгүй бол нэмэлт төлбөр гарч болно.&lt;br/&gt; Та дата эрхийнхээ талаар сайн мэдэхгүй байгаа бол Wi-Fi холболттой газар очин автоматаар татаж авахыг зөвлөж байна.&lt;br/&gt; &lt;br/&gt; Зөвлөмж: Та өөрийн мобайль төхөөрөмжийн &lt;b&gt;Тохиргоо&lt;/b&gt; цэсний &lt;b&gt;Хэл &amp; оруулах&lt;/b&gt; руу очиж толь бичиг татаж авах буюу устгаж болно."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Одоо татах (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Wi-Fi-р татаж авах"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"<xliff:g id="LANGUAGE">%1$s</xliff:g> хэлний толь бичигтэй"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Шалгах болон татаж авахын тулд дарна уу"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Татаж байна: <xliff:g id="LANGUAGE">%1$s</xliff:g> хэлний санал болгох үгс удахгүй бэлэн болно."</string>
+ <string name="version_text" msgid="2715354215568469385">"Хувилбар <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Нэмэх"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Толь бичигт нэмэх"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Хэллэг"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Нэмэлт сонголтууд"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Цөөн сонголт"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"Тийм"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Үг:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Товчилбор:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Хэл:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Үг оруулна уу"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Зайлшгүй биш товчилбор"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Үг засах"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Засах"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Устгах"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"Таны хэрэглэгчийн толинд ямар ч үг алга байна. Нэмэх (+) товчинд хүрэн үг нэмнэ үү."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Бүх хэлэнд"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Өөр хэлүүд…"</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Устгах"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-mn/strings.xml b/java/res/values-mn/strings.xml
index 12a3b47f1..4a612040e 100644
--- a/java/res/values-mn/strings.xml
+++ b/java/res/values-mn/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Хоосон зай болон цэг таслал нь буруу бичсэн үгсийг автоматаар залруулна"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Идэвхгүй"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Хүлээцтэй"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Хүчтэй"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Маш хүчтэй"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Хүчтэй"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Маш хүчтэй"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Дараагийн-үг санал болгох"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Өмнөх үгийг үг санал болгоход ашиглах"</string>
<string name="gesture_input" msgid="826951152254563827">"Зангаагаар бичихийг идэвхжүүлэх"</string>
@@ -143,13 +143,13 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Англи (ИБ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Англи (АНУ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Испани (АНУ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Хэл байхгүй"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Хэл байхгүй (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Хэл байхгүй (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Хэл байхгүй (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Хэл байхгүй (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Хэл байхгүй (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Хэл байхгүй (PC)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Хэл байхгүй (Цагаан толгой)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Цагаан толгой (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Цагаан толгой (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Цагаан толгой (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Цагаан толгой (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Цагаан толгой (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Цагаан толгой (PC)"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Өөрийн оруулах загвар"</string>
<string name="add_style" msgid="6163126614514489951">"Загвар нэмэх"</string>
<string name="add" msgid="8299699805688017798">"Нэмэх"</string>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
new file mode 100644
index 000000000..49efdf18f
--- /dev/null
+++ b/java/res/values-ms-rMY/strings.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="english_ime_input_options" msgid="3909945612939668554">"Pilihan input"</string>
+ <string name="english_ime_research_log" msgid="8492602295696577851">"Arahan Log Penyelidikan"</string>
+ <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cari nama kenalan"</string>
+ <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Penyemak ejaan menggunakan entri dari senarai kenalan anda"</string>
+ <string name="vibrate_on_keypress" msgid="5258079494276955460">"Getar pada tekanan kekunci"</string>
+ <string name="sound_on_keypress" msgid="6093592297198243644">"Bunyi pada tekanan kekunci"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"Pop timbul pada tekanan kunci"</string>
+ <string name="general_category" msgid="1859088467017573195">"Umum"</string>
+ <string name="correction_category" msgid="2236750915056607613">"Pembetulan teks"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"Taipan gerak isyarat"</string>
+ <string name="misc_category" msgid="6894192814868233453">"Pilihan lain"</string>
+ <string name="advanced_settings" msgid="362895144495591463">"Tetapan lanjutan"</string>
+ <string name="advanced_settings_summary" msgid="4487980456152830271">"Pilihan untuk pakar"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Tukar ke kaedah input lain"</string>
+ <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Kunci pertukaran bahasa meliputi kaedah masukan lain juga"</string>
+ <string name="show_language_switch_key" msgid="5915478828318774384">"Kekunci tukar bahasa"</string>
+ <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Tunjukkan apabila berbilang bahasa input didayakan"</string>
+ <string name="sliding_key_input_preview" msgid="6604262359510068370">"Tunjukkan penunjuk slaid"</string>
+ <string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Paparkan petunjuk visual semasa meluncur daripada kekunci Shift atau Simbol"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Pop tmbl knci ketpkn lengah"</string>
+ <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Tiada kelewatan"</string>
+ <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Lalai"</string>
+ <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string>
+ <string name="settings_system_default" msgid="6268225104743331821">"Tetapan asal sistem"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"Cadangkan nama Kenalan"</string>
+ <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama daripada Kenalan untuk cadangan dan pembetulan"</string>
+ <string name="use_double_space_period" msgid="8781529969425082860">"Titik ruang berganda"</string>
+ <string name="use_double_space_period_summary" msgid="6532892187247952799">"Mengetik 2X pada bar ruang memasukkan titik diikuti dengan ruang"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Autopenghurufbesaran"</string>
+ <string name="auto_cap_summary" msgid="7934452761022946874">"Besarkan perkataan pertama setiap ayat"</string>
+ <string name="edit_personal_dictionary" msgid="3996910038952940420">"Kamus peribadi"</string>
+ <string name="configure_dictionaries_title" msgid="4238652338556902049">"Kamus tambahan"</string>
+ <string name="main_dictionary" msgid="4798763781818361168">"Kamus utama"</string>
+ <string name="prefs_show_suggestions" msgid="8026799663445531637">"Tunjukkan cadangan pembetulan"</string>
+ <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Paparkan cadangan perkataan semasa menaip"</string>
+ <string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Sentiasa tunjukkan"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Tunjukkan dalam mod potret"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Sentiasa sembunyikan"</string>
+ <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Sekat perkataan yg menyinggung"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Jangan cadangkan perkataan yang boleh menyinggung"</string>
+ <string name="auto_correction" msgid="7630720885194996950">"Auto pembetulan"</string>
+ <string name="auto_correction_summary" msgid="5625751551134658006">"Bar ruang dan tanda baca secara automatik membetulkan perkataan yang ditaip salah"</string>
+ <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Dimati"</string>
+ <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresif"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Sangat agresif"</string>
+ <string name="bigram_prediction" msgid="1084449187723948550">"Cadangan perkataan seterusnya"</string>
+ <string name="bigram_prediction_summary" msgid="3896362682751109677">"Gunakan perkataan sebelumnya dalam membuat cadangan"</string>
+ <string name="gesture_input" msgid="826951152254563827">"Dayakan taipan gerak isyarat"</string>
+ <string name="gesture_input_summary" msgid="9180350639305731231">"Input perkataan dengan meluncur melalui huruf"</string>
+ <string name="gesture_preview_trail" msgid="3802333369335722221">"Tunjukkan jejak gerak isyarat"</string>
+ <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Pratonton terapung dinamik"</string>
+ <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Lihat perkataan yang dicadangkan semasa membuat gerak isyarat"</string>
+ <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Disimpan"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Pergi"</string>
+ <string name="label_next_key" msgid="362972844525672568">"Seterusnya"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"Sblm"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"Selesai"</string>
+ <string name="label_send_key" msgid="2815056534433717444">"Hantar"</string>
+ <string name="label_pause_key" msgid="181098308428035340">"Jeda"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"Tunggu"</string>
+ <string name="spoken_use_headphones" msgid="896961781287283493">"Pasangkan set kepala untuk mendengar kekunci kata laluan disebut dengan kuat."</string>
+ <string name="spoken_current_text_is" msgid="2485723011272583845">"Teks semasa adalah %s"</string>
+ <string name="spoken_no_text_entered" msgid="7479685225597344496">"Tiada teks dimasukkan"</string>
+ <string name="spoken_description_unknown" msgid="3197434010402179157">"Kod kunci %d"</string>
+ <string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
+ <string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Kunci anjak dihidupkan (ketik untuk melumpuhkan)"</string>
+ <string name="spoken_description_caps_lock" msgid="3276478269526304432">"Kunci huruf besar dihidupkan (ketik untuk melumpuhkan)"</string>
+ <string name="spoken_description_delete" msgid="8740376944276199801">"Padam"</string>
+ <string name="spoken_description_to_symbol" msgid="5486340107500448969">"Simbol"</string>
+ <string name="spoken_description_to_alpha" msgid="23129338819771807">"Huruf"</string>
+ <string name="spoken_description_to_numeric" msgid="591752092685161732">"Numbers"</string>
+ <string name="spoken_description_settings" msgid="4627462689603838099">"Tetapan"</string>
+ <string name="spoken_description_tab" msgid="2667716002663482248">"Tab"</string>
+ <string name="spoken_description_space" msgid="2582521050049860859">"Ruang"</string>
+ <string name="spoken_description_mic" msgid="615536748882611950">"Input suara"</string>
+ <string name="spoken_description_smiley" msgid="2256309826200113918">"Muka senyum"</string>
+ <string name="spoken_description_return" msgid="8178083177238315647">"Kembali"</string>
+ <string name="spoken_description_search" msgid="1247236163755920808">"Cari"</string>
+ <string name="spoken_description_dot" msgid="40711082435231673">"Titik"</string>
+ <string name="spoken_description_language_switch" msgid="5507091328222331316">"Tukar bahasa"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"Seterusnya"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"Sebelumnya"</string>
+ <string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift didayakan"</string>
+ <string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"Kunci huruf besar didayakan"</string>
+ <string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Kunci anjak dilumpuhkan"</string>
+ <string name="spoken_description_mode_symbol" msgid="7183343879909747642">"Mod simbol"</string>
+ <string name="spoken_description_mode_alpha" msgid="3528307674390156956">"Mod huruf"</string>
+ <string name="spoken_description_mode_phone" msgid="6520207943132026264">"Mod telefon"</string>
+ <string name="spoken_description_mode_phone_shift" msgid="5499629753962641227">"Mod simbol telefon"</string>
+ <string name="announce_keyboard_hidden" msgid="8718927835531429807">"Papan kekunci tersembunyi"</string>
+ <string name="announce_keyboard_mode" msgid="4729081055438508321">"Menunjukkan <xliff:g id="MODE">%s</xliff:g> papan kekunci"</string>
+ <string name="keyboard_mode_date" msgid="3137520166817128102">"tarikh"</string>
+ <string name="keyboard_mode_date_time" msgid="339593358488851072">"tarikh dan masa"</string>
+ <string name="keyboard_mode_email" msgid="6216248078128294262">"e-mel"</string>
+ <string name="keyboard_mode_im" msgid="1137405089766557048">"pemesejan"</string>
+ <string name="keyboard_mode_number" msgid="7991623440699957069">"nombor"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"telefon"</string>
+ <string name="keyboard_mode_text" msgid="6479436687899701619">"teks"</string>
+ <string name="keyboard_mode_time" msgid="4381856885582143277">"masa"</string>
+ <string name="keyboard_mode_url" msgid="1519819835514911218">"URL"</string>
+ <string name="voice_input" msgid="3583258583521397548">"Kunci input suara"</string>
+ <string name="voice_input_modes_main_keyboard" msgid="3360660341121083174">"Pada papan kekunci utama"</string>
+ <string name="voice_input_modes_symbols_keyboard" msgid="7203213240786084067">"Pada papan kekunci simbol"</string>
+ <string name="voice_input_modes_off" msgid="3745699748218082014">"Dimati"</string>
+ <string name="voice_input_modes_summary_main_keyboard" msgid="6586544292900314339">"Mikrofon pada papan kekunci utama"</string>
+ <string name="voice_input_modes_summary_symbols_keyboard" msgid="5233725927281932391">"Mikrofon pada papan kekunci simbol"</string>
+ <string name="voice_input_modes_summary_off" msgid="63875609591897607">"Input suara dilmphkn"</string>
+ <string name="configure_input_method" msgid="373356270290742459">"Konfigurasikan kaedah input"</string>
+ <string name="language_selection_title" msgid="1651299598555326750">"Bahasa input"</string>
+ <string name="send_feedback" msgid="1780431884109392046">"Hantar maklum balas"</string>
+ <string name="select_language" msgid="3693815588777926848">"Bahasa input"</string>
+ <string name="hint_add_to_dictionary" msgid="573678656946085380">"Sentuh lagi untuk menyimpan"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"Kamus tersedia"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Dayakan maklum balas pengguna"</string>
+ <string name="prefs_description_log" msgid="7525225584555429211">"Bantu memperbaik editor kaedah input ini dengan menghantar statistik penggunaan dan laporan ranap secara automatik"</string>
+ <string name="keyboard_layout" msgid="8451164783510487501">"Tema papan kekunci"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"Bahasa Inggeris (UK)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"Bahasa Inggeris (Australia)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"Bahasa Sepanyol (AS)"</string>
+ <string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Bahasa Inggeris (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Bahasa Inggeris (AS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Bahasa Sepanyol (AS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Tradisional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Tiada bahasa (Abjad)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Abjad (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Abjad (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Abjad (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Abjad (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
+ <string name="custom_input_styles_title" msgid="8429952441821251512">"Gaya input peribadi"</string>
+ <string name="add_style" msgid="6163126614514489951">"Tambah gaya"</string>
+ <string name="add" msgid="8299699805688017798">"Tambah"</string>
+ <string name="remove" msgid="4486081658752944606">"Alih Keluar"</string>
+ <string name="save" msgid="7646738597196767214">"Simpan"</string>
+ <string name="subtype_locale" msgid="8576443440738143764">"Bahasa"</string>
+ <string name="keyboard_layout_set" msgid="4309233698194565609">"Reka letak"</string>
+ <string name="custom_input_style_note_message" msgid="8826731320846363423">"Gaya input tersuai anda perlu didayakan sebelum anda mula menggunakannya. Adakah anda ingin mendayakannya sekarang?"</string>
+ <string name="enable" msgid="5031294444630523247">"Dayakan"</string>
+ <string name="not_now" msgid="6172462888202790482">"Bukan sekarang"</string>
+ <string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
+ <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mod kajian kebolehgunaan"</string>
+ <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Kelewatan tekan lama kekunci"</string>
+ <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Tempoh getaran tekan kekunci"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Kelantangan bunyi tekan kekunci"</string>
+ <string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Baca fail kamus luaran"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Tiada fail kamus dalam folder Muat Turun"</string>
+ <string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Pilih fail kamus untuk dipasang"</string>
+ <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"Betul-betul pasang fail ini untuk <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
+ <string name="error" msgid="8940763624668513648">"Berlaku ralat"</string>
+ <string name="button_default" msgid="3988017840431881491">"Lalai"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"Selamat datang ke <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_welcome_additional_description" msgid="8150252008545768953">"dengan Taipan Gerak Isyarat"</string>
+ <string name="setup_start_action" msgid="8936036460897347708">"Bermula"</string>
+ <string name="setup_next_action" msgid="371821437915144603">"Langkah seterusnya"</string>
+ <string name="setup_steps_title" msgid="6400373034871816182">"Menyediakan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_title" msgid="3147967630253462315">"Dayakan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step1_instruction" msgid="2578631936624637241">"Sila semak \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" dlm ttpn Bhs &amp; input. Ini mbnarkn apl djlnkn pd pranti anda."</string>
+ <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> sudah didayakan dalam tetapan Bahasa &amp; input anda, jadi langkah ini telah selesai. Beralih ke langkah seterusnya!"</string>
+ <string name="setup_step1_action" msgid="4366513534999901728">"Dayakan dalam Tetapan"</string>
+ <string name="setup_step2_title" msgid="6860725447906690594">"Beralih ke <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="setup_step2_instruction" msgid="9141481964870023336">"Seterusnya, pilih \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" sebagai kaedah input teks aktif anda."</string>
+ <string name="setup_step2_action" msgid="1660330307159824337">"Tukar kaedah input"</string>
+ <string name="setup_step3_title" msgid="3154757183631490281">"Tahniah, anda sudah sedia!"</string>
+ <string name="setup_step3_instruction" msgid="8025981829605426000">"Kini anda boleh menaip dalam semua apl kegemaran anda dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
+ <string name="setup_step3_action" msgid="600879797256942259">"Konfigurasikan bahasa tambahan"</string>
+ <string name="setup_finish_action" msgid="276559243409465389">"Selesai"</string>
+ <string name="show_setup_wizard_icon" msgid="5008028590593710830">"Tunjukkan ikon apl"</string>
+ <string name="show_setup_wizard_icon_summary" msgid="4119998322536880213">"Paparkan ikon apl dalam pelancar"</string>
+ <string name="app_name" msgid="6320102637491234792">"Pembekal Kamus"</string>
+ <string name="dictionary_provider_name" msgid="3027315045397363079">"Pembekal Kamus"</string>
+ <string name="dictionary_service_name" msgid="6237472350693511448">"Perkhidmatan Kamus"</string>
+ <string name="download_description" msgid="6014835283119198591">"Maklumat kemas kini kamus"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"Kamus tambahan"</string>
+ <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Kamus tersedia"</string>
+ <string name="dictionary_settings_summary" msgid="5305694987799824349">"Tetapan untuk kamus"</string>
+ <string name="user_dictionaries" msgid="3582332055892252845">"Kamus pengguna"</string>
+ <string name="default_user_dict_pref_name" msgid="1625055720489280530">"Kamus pengguna"</string>
+ <string name="dictionary_available" msgid="4728975345815214218">"Kamus tersedia"</string>
+ <string name="dictionary_downloading" msgid="2982650524622620983">"Sedang memuat turun"</string>
+ <string name="dictionary_installed" msgid="8081558343559342962">"Dipasang"</string>
+ <string name="dictionary_disabled" msgid="8950383219564621762">"Dipasang, dilumpuhkan"</string>
+ <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Masalah menyambung kepada perkhidmatan kamus"</string>
+ <string name="no_dictionaries_available" msgid="8039920716566132611">"Tiada kamus tersedia"</string>
+ <string name="check_for_updates_now" msgid="8087688440916388581">"Muatkan semula"</string>
+ <string name="last_update" msgid="730467549913588780">"Kali terakhir dikemas kini"</string>
+ <string name="message_updating" msgid="4457761393932375219">"Menyemak kemas kini"</string>
+ <string name="message_loading" msgid="8689096636874758814">"Memuatkan..."</string>
+ <string name="main_dict_description" msgid="3072821352793492143">"Kamus utama"</string>
+ <string name="cancel" msgid="6830980399865683324">"Batal"</string>
+ <string name="install_dict" msgid="180852772562189365">"Pasang"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"Batal"</string>
+ <string name="delete_dict" msgid="756853268088330054">"Padam"</string>
+ <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"Bahasa pilihan pada peranti mudah alih anda mempunyai kamus tersedia.&lt;br/&gt; Kami mengesyorkan &lt;b&gt;memuat turun&lt;/b&gt; kamus <xliff:g id="LANGUAGE">%1$s</xliff:g> untuk memperbaik pengalaman menaip anda.&lt;br/&gt; &lt;br/&gt; Muat turun boleh mengambil masa seminit atau dua melalui 3G. Caj mungkin dikenakan jika anda tidak mempunyai &lt;b&gt;pelan data tanpa had&lt;/b&gt;.&lt;br/&gt; Jika anda tidak pasti jenis pelan data yang anda miliki, kami mengesyorkan agar anda mencari sambungan Wi-Fi untuk mula memuat turun secara automatik.&lt;br/&gt; &lt;br/&gt; Petua: Anda boleh memuat turun dan mengalih keluar kamus dengan pergi ke menu &lt;b&gt;Bahasa &amp; input&lt;/b&gt; dalam &lt;b&gt;Tetapan&lt;/b&gt; peranti mudah alih anda."</string>
+ <string name="download_over_metered" msgid="1643065851159409546">"Muat turun sekarang (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string>
+ <string name="do_not_download_over_metered" msgid="2176209579313941583">"Muat turun melalui Wi-Fi"</string>
+ <string name="dict_available_notification_title" msgid="6514288591959117288">"Kamus tersedia untuk <xliff:g id="LANGUAGE">%1$s</xliff:g>"</string>
+ <string name="dict_available_notification_description" msgid="1075194169443163487">"Tekan untuk mengulas dan memuat turun"</string>
+ <string name="toast_downloading_suggestions" msgid="1313027353588566660">"Memuat turun: cadangan untuk <xliff:g id="LANGUAGE">%1$s</xliff:g> akan sedia tidak lama lagi."</string>
+ <string name="version_text" msgid="2715354215568469385">"Versi <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string>
+ <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"tambah"</string>
+ <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Tambah ke kamus"</string>
+ <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Frasa"</string>
+ <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"Lagi pilihan"</string>
+ <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Kurang pilihan"</string>
+ <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string>
+ <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Perkataan:"</string>
+ <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Pintasan:"</string>
+ <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Bahasa:"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Taip perkataan"</string>
+ <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Pintasan pilihan"</string>
+ <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Edit perkataan"</string>
+ <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Edit"</string>
+ <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Padam"</string>
+ <string name="user_dict_settings_empty_text" msgid="558499587532668203">"Anda tidak mempunyai sebarang perkataan dalam kamus pengguna. Tambahkan perkataan dengan menyentuh butang Tambah (+)."</string>
+ <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"Untuk semua bahasa"</string>
+ <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"Lebih banyak bahasa..."</string>
+ <string name="user_dict_settings_delete" msgid="110413335187193859">"Padam"</string>
+ <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+</resources>
diff --git a/java/res/values-ms/strings.xml b/java/res/values-ms/strings.xml
index 968243bb3..df30627aa 100644
--- a/java/res/values-ms/strings.xml
+++ b/java/res/values-ms/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Bar ruang dan tanda baca secara automatik membetulkan perkataan yang ditaip salah"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Matikan"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Sederhana"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Agresif"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Sangat agresif"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresif"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Sangat agresif"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Cadangan perkataan seterusnya"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Gunakan perkataan sebelumnya dalam membuat cadangan"</string>
<string name="gesture_input" msgid="826951152254563827">"Dayakan taipan gerak isyarat"</string>
@@ -143,13 +143,13 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Bahasa Inggeris (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Bahasa Inggeris (AS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Bahasa Sepanyol (AS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Tiada bahasa"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Tiada bahasa (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Tiada bahasa (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Tiada bahasa (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Tiada bahasa (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Tiada bahasa (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Tiada bahasa (PC)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Tiada bahasa (Abjad)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Abjad (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Abjad (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Abjad (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Abjad (PC)"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Gaya input peribadi"</string>
<string name="add_style" msgid="6163126614514489951">"Tambah gaya"</string>
<string name="add" msgid="8299699805688017798">"Tambah"</string>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 33da13eaf..9b30ea329 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Mellomromstast og skilletegn retter automat. feilstavede ord"</string>
<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_aggressive" msgid="3524029103734923819">"Omfattende"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Veldig aggressiv"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Omfattende"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Veldig omfattende"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Forslag til neste ord"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Bruk forrige ord til å lage forslag"</string>
<string name="gesture_input" msgid="826951152254563827">"Aktiver ordføring"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Engelsk (Storbritannia) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Engelsk (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spansk (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Ingen språk"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Ingen språk (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Ingen språk (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Ingen språk (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Ingen språk (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Ingen språk (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Ingen språk (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradisjonell)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Ingen språk (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Egendefinerte inndata"</string>
<string name="add_style" msgid="6163126614514489951">"Legg til stil"</string>
<string name="add" msgid="8299699805688017798">"Legg til"</string>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 5224f813f..c61b090b6 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Met spatiebalk en interpunctie worden verkeerd gespelde woorden automatisch gecorrigeerd"</string>
<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_aggressive" msgid="3524029103734923819">"Agressief"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Zeer agressief"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agressief"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Zeer agressief"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Suggesties voor volgend woord"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Het vorige woord gebruiken bij het doen van suggesties"</string>
<string name="gesture_input" msgid="826951152254563827">"Typen via tekenen inschakelen"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Engels (VK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Engels (VS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spaans (VS) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Geen taal"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Geen taal (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Geen taal (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Geen taal (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Geen taal (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Geen taal (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Geen taal (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditioneel)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Geen taal (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (pc)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Aangep. invoerstijlen"</string>
<string name="add_style" msgid="6163126614514489951">"Stijl toev."</string>
<string name="add" msgid="8299699805688017798">"Toevoegen"</string>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index e128c0e33..31eace5cb 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Spacja i znaki przestankowe poprawiają błędnie wpisane słowa"</string>
<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_aggressive" msgid="3524029103734923819">"Agresywna"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Bardzo agresywna"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresywna"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Bardzo agresywna"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Podpowiadanie kolejnego słowa"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Pokazuj podpowiedzi na podstawie poprzedniego słowa"</string>
<string name="gesture_input" msgid="826951152254563827">"Włącz pisanie gestami"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"angielski (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"angielski (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"hiszpański (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Brak języka"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Brak języka (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Brak języka (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Brak języka (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Brak języka (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Brak języka (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Brak języka (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradycyjny)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Bez języka (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emotikony"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Style niestandardowe"</string>
<string name="add_style" msgid="6163126614514489951">"Dodaj styl"</string>
<string name="add" msgid="8299699805688017798">"Dodaj"</string>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index fb06f9291..cd89a7765 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Correcção automática de palavras mal escritas c/ barra de espaços e pontuação"</string>
<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_aggressive" msgid="3524029103734923819">"Agressiva"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Muito agressivo"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agressiva"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Muito agressiva"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Sugestões da palavra seguinte"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Utilizar palavra anterior para fazer sugestões"</string>
<string name="gesture_input" msgid="826951152254563827">"Ativar escrita por toque"</string>
@@ -134,7 +134,7 @@
<string name="select_language" msgid="3693815588777926848">"Idiomas de introdução"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para guardar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Activar comentários do utilizador"</string>
+ <string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentários do utilizador"</string>
<string name="prefs_description_log" msgid="7525225584555429211">"Envie automaticamente estatísticas de utilização e relatórios de falhas e ajude-nos a melhorar este editor do método de introdução."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglês (RU)"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglês (RU) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglês (EUA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Espanhol (EUA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Nenhum idioma"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nenhum idioma (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nenhum idioma (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nenhum idioma (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nenhum idioma (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nenh. idioma (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nenhum idioma (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Tradicional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Sem idioma (alfabeto)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabeto (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabeto (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabeto (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabeto (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Estilos entrada pers."</string>
<string name="add_style" msgid="6163126614514489951">"Adic. estilo"</string>
<string name="add" msgid="8299699805688017798">"Adicionar"</string>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index 8cbc41e3a..820f577ad 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -56,7 +56,7 @@
<string name="prefs_show_suggestions" msgid="8026799663445531637">"Exibir sugestões de correção"</string>
<string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Exibir sugestões de palavras durante a digitação"</string>
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"Mostrar sempre"</string>
- <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Mostrar em modo de retrato"</string>
+ <string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"Mostrar em modo retrato"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"Sempre ocultar"</string>
<string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Bloquear palavras ofensivas"</string>
<string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Não sugerir palavras potencialmente ofensivas"</string>
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"A barra de espaço e a pontuação corrigem automaticamente palavras com erro de digitação"</string>
<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_aggressive" msgid="3524029103734923819">"Agressivo"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Muito agressivo"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agressivo"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Muito agressivo"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Sugestões para a palavra seguinte"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Usar a palavra anterior ao fazer sugestões"</string>
<string name="gesture_input" msgid="826951152254563827">"Ativar a escrita com gestos"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Inglês (Reino Unido) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Inglês (EUA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"espanhol (EUA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Sem idioma"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"nenhum idioma (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nenhum idioma (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nenhum idioma (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nenhum idioma (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nenhum idioma (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nenhum idioma (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Nenhum idioma (alfabeto)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabeto (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabeto (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabeto (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabeto (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Estilos personalizados"</string>
<string name="add_style" msgid="6163126614514489951">"Adic. estilo"</string>
<string name="add" msgid="8299699805688017798">"Adicionar"</string>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 71c9deb0c..1c509ad73 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -104,9 +104,9 @@
<skip />
<!-- no translation found for auto_correction_threshold_mode_modest (8788366690620799097) -->
<skip />
- <!-- no translation found for auto_correction_threshold_mode_aggressive (3524029103734923819) -->
+ <!-- no translation found for auto_correction_threshold_mode_aggressive (7319007299148899623) -->
<skip />
- <!-- no translation found for auto_correction_threshold_mode_very_aggressive (3386782235540547678) -->
+ <!-- no translation found for auto_correction_threshold_mode_very_aggressive (1853309024129480416) -->
<skip />
<!-- no translation found for bigram_prediction (1084449187723948550) -->
<skip />
@@ -254,19 +254,23 @@
<skip />
<!-- no translation found for subtype_with_layout_es_US (6261791057007890189) -->
<skip />
- <!-- no translation found for subtype_no_language (141420857808801746) -->
+ <!-- no translation found for subtype_nepali_traditional (9032247506728040447) -->
<skip />
- <!-- no translation found for subtype_no_language_qwerty (2956121451616633133) -->
+ <!-- no translation found for subtype_no_language (7137390094240139495) -->
<skip />
- <!-- no translation found for subtype_no_language_qwertz (1177848172397202890) -->
+ <!-- no translation found for subtype_no_language_qwerty (244337630616742604) -->
<skip />
- <!-- no translation found for subtype_no_language_azerty (8721460968141187394) -->
+ <!-- no translation found for subtype_no_language_qwertz (443066912507547976) -->
<skip />
- <!-- no translation found for subtype_no_language_dvorak (3122976737669823935) -->
+ <!-- no translation found for subtype_no_language_azerty (8144348527575640087) -->
<skip />
- <!-- no translation found for subtype_no_language_colemak (4205992994906097244) -->
+ <!-- no translation found for subtype_no_language_dvorak (1564494667584718094) -->
<skip />
- <!-- no translation found for subtype_no_language_pcqwerty (8840928374394180189) -->
+ <!-- no translation found for subtype_no_language_colemak (5837418400010302623) -->
+ <skip />
+ <!-- no translation found for subtype_no_language_pcqwerty (5354918232046200018) -->
+ <skip />
+ <!-- no translation found for subtype_emoji (7483586578074549196) -->
<skip />
<!-- no translation found for custom_input_styles_title (8429952441821251512) -->
<skip />
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index cbba8a375..3caff1337 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -39,7 +39,7 @@
<string name="show_language_switch_key_summary" msgid="7343403647474265713">"Afişaţi când sunt activate mai multe limbi de intrare"</string>
<string name="sliding_key_input_preview" msgid="6604262359510068370">"Afișați indicator glisare"</string>
<string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"Afișați un indicator în timpul glisării de la Shift sau tasta de simboluri"</string>
- <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Înt. înch. pop-up esenţ."</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Închidere pop-up taste"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"Fără întârziere"</string>
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Prestabilit"</string>
<string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> msec."</string>
@@ -48,7 +48,7 @@
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizaţi numele din Agendă pentru sugestii şi corecţii"</string>
<string name="use_double_space_period" msgid="8781529969425082860">"Inserează punct spațiu"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubla atingere a barei de spațiu inserează punct urmat de spațiu"</string>
- <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalizare"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"Scriere automată cu majuscule"</string>
<string name="auto_cap_summary" msgid="7934452761022946874">"Scrie cu majusculă primul cuvânt din fiecare propoziţie"</string>
<string name="edit_personal_dictionary" msgid="3996910038952940420">"Dicționar personal"</string>
<string name="configure_dictionaries_title" msgid="4238652338556902049">"Dicţionare suplimentare"</string>
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Corectare automată cuvinte prin bară spaţiu/semne punctuaţie"</string>
<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_aggressive" msgid="3524029103734923819">"Agresivă"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Foarte exigentă"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Exigentă"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Foarte agresivă"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Sugestii pentru cuvântul următor"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Utilizează cuvântul anterior pentru sugestii"</string>
<string name="gesture_input" msgid="826951152254563827">"Activați tastarea gestuală"</string>
@@ -131,25 +131,27 @@
<string name="configure_input_method" msgid="373356270290742459">"Configuraţi metodele de intrare"</string>
<string name="language_selection_title" msgid="1651299598555326750">"Selectaţi limba"</string>
<string name="send_feedback" msgid="1780431884109392046">"Trimiteți feedback"</string>
- <string name="select_language" msgid="3693815588777926848">"Limbi de intrare"</string>
+ <string name="select_language" msgid="3693815588777926848">"Limbi de introducere de text"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Atingeţi din nou pentru a salva"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicţionar disponibil"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"Activaţi feedback de la utilizatori"</string>
<string name="prefs_description_log" msgid="7525225584555429211">"Ajutați la îmbunătățirea acestui instrument de editare a metodelor de introducere a textului trimițând în mod automat statistici de utilizare și rapoarte de blocare."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Temă pentru tastatură"</string>
- <string name="subtype_en_GB" msgid="88170601942311355">"Engleză (Marea Britanie)"</string>
- <string name="subtype_en_US" msgid="6160452336634534239">"Engleză (S.U.A.)"</string>
- <string name="subtype_es_US" msgid="5583145191430180200">"Spaniolă (S.U.A.)"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"engleză (Regatul Unit)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"engleză (S.U.A.)"</string>
+ <string name="subtype_es_US" msgid="5583145191430180200">"spaniolă (S.U.A.)"</string>
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Engleză (Regatul Unit) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Engleză (S.U.A.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spaniolă (S.U.A.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Nicio limbă"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Nicio limbă (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Nicio limbă (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Nicio limbă (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Nicio limbă (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Nicio limbă (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Nicio limbă (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradițional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Nicio limbă (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Stiluri personalizate"</string>
<string name="add_style" msgid="6163126614514489951">"Stil"</string>
<string name="add" msgid="8299699805688017798">"Adăugaţi"</string>
@@ -164,7 +166,7 @@
<string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modul Studiu privind utilizarea"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Timpul apăsării lungi a tastei"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrare după apăsarea tastei"</string>
- <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volum prin apăsarea tastei"</string>
+ <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Sunet la apăsarea tastelor"</string>
<string name="prefs_read_external_dictionary" msgid="2588931418575013067">"Citiți fișierul de dicționar extern"</string>
<string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"Nu există fișiere dicționar în dosarul Descărcări"</string>
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selectați un fișier dicționar de instalat"</string>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index 13f34ee3e..affe88fbe 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Автоматическое исправление опечаток при вводе знака препинания или пробела"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Откл."</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умеренное"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Активное"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Очень активно"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Активно"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Очень активно"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Подсказывать слова"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Предлагать подсказки на основе предыдущего слова"</string>
<string name="gesture_input" msgid="826951152254563827">"Включить функцию"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Английская (Великобр.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Английская (США) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Испанский (США): <xliff:g id="LAYOUT">%s</xliff:g>"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Язык не указан"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"QWERTY-клавиатура"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Язык не задан (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Язык не задан (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Язык не задан (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Яз. не задан (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Язык не задан (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (традиционный)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Язык не определен (латиница)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиница (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиница (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Латиница (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Латиница (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Латиница (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Латиница (ПК)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Эмодзи"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Персонализированные стили"</string>
<string name="add_style" msgid="6163126614514489951">"Добавить стиль"</string>
<string name="add" msgid="8299699805688017798">"Добавить"</string>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 9d315a8f5..85d64c6c0 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Stlačením medzerníka a interpunkcie sa aut. opravia chybné slová"</string>
<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_aggressive" msgid="3524029103734923819">"Agresívne"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Veľmi agresívne"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresívne"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Veľmi agresívne"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Návrhy ďalšieho slova"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Návrhy podľa predchádzajúceho slova"</string>
<string name="gesture_input" msgid="826951152254563827">"Povoliť písanie gestami"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"angličtina (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"angličtina (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"španielčina (USA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Žiadny jazyk"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Žiadny jazyk (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Žiadny jazyk (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Žiadny jazyk (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Žiadny jazyk (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Žiadny jazyk (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Žiadny jazyk (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradičná)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Žiadny jazyk (latinka)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinka (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinka (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Latinka (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Latinka (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Latinka (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Latinka (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Vlastné štýly vstupu"</string>
<string name="add_style" msgid="6163126614514489951">"Pridať štýl"</string>
<string name="add" msgid="8299699805688017798">"Pridať"</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 760cbde82..7648d73b2 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Preslednica in ločila samodejno popravijo napačno vtipkane besede"</string>
<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_aggressive" msgid="3524029103734923819">"Strogo"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Zelo strogo"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresivno"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Zelo agresivno"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Predlogi za naslednjo besedo"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Pri predlogu upoštevaj prejšnjo besedo"</string>
<string name="gesture_input" msgid="826951152254563827">"Omogoči vnos besedila s potezo"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Angleška (Zdr. kralj.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Angleška (ZDA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"španščina (ZDA) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Ni jezika"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Ni jezika (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Ni jezika (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Ni jezika (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Ni jezika (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Ni jezika (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Ni jezika (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (tradicionalna)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Brez jezika (latinice)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinica (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinica (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Latinica (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Latinica (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Latinica (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Latinica (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Znaki »emoji«"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Slogi vnosa po meri"</string>
<string name="add_style" msgid="6163126614514489951">"Dodaj slog"</string>
<string name="add" msgid="8299699805688017798">"Dodaj"</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 6bddc5c98..db06bce7e 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Размак и интерпункција аутоматски исправљају грешке у куцању"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Искључи"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Умерено"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Агресивно"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Веома агресивно"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Агресивно"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Веома агресивно"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Предлози за следећу реч"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Користи претходну реч при давању предлога"</string>
<string name="gesture_input" msgid="826951152254563827">"Омогући унос покретом"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"енглески (УК) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"енглески (САД) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"шпански (САД) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Без језика"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Нема језика (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Без језика (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Без језика (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Без језика (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Без језика (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Без језика (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (традиционални)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Нема језика (абецеда)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Абецеда (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Абецеда (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Абецеда (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Абецеда (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Абецеда (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Абецеда (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Емотикони"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Прилаг. стилови уноса"</string>
<string name="add_style" msgid="6163126614514489951">"Додав. стила"</string>
<string name="add" msgid="8299699805688017798">"Додај"</string>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index d1567c3ba..c6635165c 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Blanksteg/skiljetecken rättar felstavning"</string>
<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_aggressive" msgid="3524029103734923819">"Aggressiv"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Mycket aggressivt"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressivt"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Mycket aggressivt"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Föreslå nästa ord"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Ge förslag utifrån föregående ord"</string>
<string name="gesture_input" msgid="826951152254563827">"Aktivera svepskrivning"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Engelskt (brittiskt) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Engelskt (amerikanskt) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"spanska (USA (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Inget språk"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Inget språk (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Inget språk (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Inget språk (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Inget språk (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Inget språk (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Inget språk (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (traditionell)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Inget språk (alfabet)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabet (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabet (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabet (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabet (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Humörsymbol"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Anpassade indatastilar"</string>
<string name="add_style" msgid="6163126614514489951">"Ny stil"</string>
<string name="add" msgid="8299699805688017798">"Lägg till"</string>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 3891cf284..188bbca9c 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Kiaamba na kiakifishi hurekebisha maneno ambayo yamechapishwa vibaya"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Zima"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Ya wastani"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Ya hima"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Changamfu zaidi"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Linalokaribia"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Linalokaribia sana"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Mapendekezo ya neno lifuatalo"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Tumia nelo la awali katika kufanya mapendekezo"</string>
<string name="gesture_input" msgid="826951152254563827">"Washa kuandika kwa ishara"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Kiingereza (Uingereza) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Kiingereza (Marekani) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Kihispania (Marekani) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Hakuna lugha"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Hakuna lugha (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Hakuna lugha (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Hakuna lugha (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Hakuna lugha (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Hakuna lugha (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Hakuna lugha (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Asili)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Hakuna lugha (Alfabeti)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeti (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeti (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabeti (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabeti (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabeti (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabeti (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Mitindo maalum ya ingizo"</string>
<string name="add_style" msgid="6163126614514489951">"Ongeza mtindo"</string>
<string name="add" msgid="8299699805688017798">"Ongeza"</string>
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 51c710fa4..730b7d813 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -24,20 +24,15 @@
<dimen name="keyboardHeight">283.5dp</dimen>
<fraction name="minKeyboardHeight">45%p</fraction>
- <fraction name="keyboard_top_padding">2.444%p</fraction>
- <fraction name="keyboard_bottom_padding">0.0%p</fraction>
- <fraction name="key_bottom_gap">4.911%p</fraction>
- <fraction name="key_horizontal_gap">1.284%p</fraction>
-
- <fraction name="key_bottom_gap_stone">4.355%p</fraction>
- <fraction name="key_horizontal_gap_stone">1.505%p</fraction>
-
+ <fraction name="keyboard_top_padding_gb">2.444%p</fraction>
+ <fraction name="keyboard_bottom_padding_gb">0.0%p</fraction>
<fraction name="key_bottom_gap_gb">5.200%p</fraction>
<fraction name="key_horizontal_gap_gb">1.447%p</fraction>
+ <fraction name="keyboard_top_padding_ics">2.727%p</fraction>
+ <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
<fraction name="key_bottom_gap_ics">4.5%p</fraction>
<fraction name="key_horizontal_gap_ics">0.9%p</fraction>
- <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
<dimen name="popup_key_height">81.9dp</dimen>
@@ -67,4 +62,11 @@
<dimen name="gesture_floating_preview_text_offset">76dp</dimen>
<dimen name="gesture_floating_preview_horizontal_padding">26dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">17dp</dimen>
+
+ <!-- Emoji keyboard -->
+ <fraction name="emoji_keyboard_key_width">10%p</fraction>
+ <fraction name="emoji_keyboard_row_height">33%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">95%p</fraction>
+ <integer name="emoji_keyboard_max_key_count">30</integer>
+
</resources>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index 826565168..93862a767 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -28,8 +28,6 @@
<bool name="config_auto_correction_spacebar_led_enabled">false</bool>
<!-- The language is never displayed if == 0, always displayed if < 0 -->
<integer name="config_delay_before_fadeout_language_on_spacebar">1200</integer>
- <!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
- <string name="config_default_keyboard_theme_index" translatable="false">5</string>
<integer name="config_max_more_keys_column">5</integer>
<!--
Configuration for MainKeyboardView
diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml
index 75b476c64..2bcf2fa84 100644
--- a/java/res/values-sw600dp/dimens.xml
+++ b/java/res/values-sw600dp/dimens.xml
@@ -27,27 +27,22 @@
<dimen name="popup_key_height">63.0dp</dimen>
- <fraction name="keyboard_top_padding">2.291%p</fraction>
- <fraction name="keyboard_bottom_padding">0.0%p</fraction>
- <fraction name="key_bottom_gap">3.750%p</fraction>
- <fraction name="key_horizontal_gap">1.857%p</fraction>
-
- <fraction name="key_bottom_gap_stone">3.75%p</fraction>
- <fraction name="key_horizontal_gap_stone">1.602%p</fraction>
-
+ <fraction name="keyboard_top_padding_gb">2.291%p</fraction>
+ <fraction name="keyboard_bottom_padding_gb">0.0%p</fraction>
<fraction name="key_bottom_gap_gb">4.625%p</fraction>
<fraction name="key_horizontal_gap_gb">2.113%p</fraction>
+ <fraction name="keyboard_top_padding_ics">2.335%p</fraction>
+ <fraction name="keyboard_bottom_padding_ics">4.0%p</fraction>
<fraction name="key_bottom_gap_ics">4.5%p</fraction>
<fraction name="key_horizontal_gap_ics">1.565%p</fraction>
- <fraction name="keyboard_bottom_padding_ics">4.0%p</fraction>
<dimen name="more_keys_keyboard_key_horizontal_padding">6dp</dimen>
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
<!-- popup_key_height x 1.2 -->
<dimen name="more_keys_keyboard_slide_allowance">98.3dp</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="more_keys_keyboard_vertical_correction">-81.9dp</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction_gb">-81.9dp</dimen>
<!-- left or right padding of label alignment -->
<dimen name="key_label_horizontal_padding">6dp</dimen>
@@ -64,7 +59,7 @@
<fraction name="key_preview_text_ratio">50%</fraction>
<fraction name="spacebar_text_ratio">28.0%</fraction>
<dimen name="key_preview_height">94.5dp</dimen>
- <dimen name="key_preview_offset">16.0dp</dimen>
+ <dimen name="key_preview_offset_gb">16.0dp</dimen>
<!-- For 5-row keyboard -->
<fraction name="key_bottom_gap_5row">3.20%p</fraction>
@@ -93,4 +88,11 @@
<dimen name="gesture_floating_preview_horizontal_padding">28dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">19dp</dimen>
<dimen name="gesture_floating_preview_round_radius">3dp</dimen>
+
+ <!-- Emoji keyboard -->
+ <fraction name="emoji_keyboard_key_width">12.5%p</fraction>
+ <fraction name="emoji_keyboard_row_height">33%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">85%p</fraction>
+ <integer name="emoji_keyboard_max_key_count">24</integer>
+
</resources>
diff --git a/java/res/values-sw600dp/touch-position-correction.xml b/java/res/values-sw600dp/touch-position-correction.xml
index f77d3ae83..df07c1295 100644
--- a/java/res/values-sw600dp/touch-position-correction.xml
+++ b/java/res/values-sw600dp/touch-position-correction.xml
@@ -37,7 +37,7 @@
</string-array>
<string-array
- name="touch_position_correction_data_gingerbread"
+ name="touch_position_correction_data_gb"
translatable="false"
>
<!-- The default touch position data (See com.android.inputmethod.keyboard.ProximityInfo)
@@ -48,7 +48,7 @@
</string-array>
<string-array
- name="touch_position_correction_data_ice_cream_sandwich"
+ name="touch_position_correction_data_ics"
translatable="false"
>
<!-- The default touch position data (See com.android.inputmethod.keyboard.ProximityInfo)
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index f4a57ffb0..1e2e1c651 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -24,15 +24,8 @@
<dimen name="keyboardHeight">365.4dp</dimen>
<fraction name="minKeyboardHeight">45%p</fraction>
- <fraction name="keyboard_top_padding">1.896%p</fraction>
- <fraction name="keyboard_bottom_padding">0.0%p</fraction>
-
- <fraction name="key_bottom_gap">4.103%p</fraction>
- <fraction name="key_horizontal_gap">1.034%p</fraction>
-
- <fraction name="key_bottom_gap_stone">3.379%p</fraction>
- <fraction name="key_horizontal_gap_stone">1.062%p</fraction>
-
+ <fraction name="keyboard_top_padding_gb">1.896%p</fraction>
+ <fraction name="keyboard_bottom_padding_gb">0.0%p</fraction>
<fraction name="key_bottom_gap_gb">3.896%p</fraction>
<fraction name="key_horizontal_gap_gb">1.195%p</fraction>
@@ -70,4 +63,11 @@
<dimen name="gesture_floating_preview_text_offset">100dp</dimen>
<dimen name="gesture_floating_preview_horizontal_padding">32dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">21dp</dimen>
+
+ <!-- Emoji keyboard -->
+ <fraction name="emoji_keyboard_key_width">7.69%p</fraction>
+ <fraction name="emoji_keyboard_row_height">33%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">75%p</fraction>
+ <integer name="emoji_keyboard_max_key_count">39</integer>
+
</resources>
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index 97f11cb04..e1c07d6f8 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -26,8 +26,6 @@
<bool name="config_default_key_preview_popup">false</bool>
<bool name="config_default_sound_enabled">true</bool>
<bool name="config_auto_correction_spacebar_led_enabled">false</bool>
- <!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
- <string name="config_default_keyboard_theme_index" translatable="false">5</string>
<integer name="config_max_more_keys_column">5</integer>
<!--
Configuration for MainKeyboardView
diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml
index 91251f5a4..f62a536d7 100644
--- a/java/res/values-sw768dp/dimens.xml
+++ b/java/res/values-sw768dp/dimens.xml
@@ -25,18 +25,12 @@
<fraction name="maxKeyboardHeight">46%p</fraction>
<fraction name="minKeyboardHeight">-35.0%p</fraction>
- <fraction name="keyboard_top_padding">2.291%p</fraction>
- <fraction name="keyboard_bottom_padding">0.0%p</fraction>
-
- <fraction name="key_bottom_gap">4.270%p</fraction>
- <fraction name="key_horizontal_gap">1.551%p</fraction>
-
- <fraction name="key_bottom_gap_stone">3.75%p</fraction>
- <fraction name="key_horizontal_gap_stone">1.059%p</fraction>
-
+ <fraction name="keyboard_top_padding_gb">2.291%p</fraction>
+ <fraction name="keyboard_bottom_padding_gb">0.0%p</fraction>
<fraction name="key_bottom_gap_gb">4.687%p</fraction>
<fraction name="key_horizontal_gap_gb">1.272%p</fraction>
+ <fraction name="keyboard_top_padding_ics">2.335%p</fraction>
<fraction name="keyboard_bottom_padding_ics">0.0%p</fraction>
<fraction name="key_bottom_gap_ics">3.312%p</fraction>
<fraction name="key_horizontal_gap_ics">1.066%p</fraction>
@@ -48,7 +42,7 @@
<!-- popup_key_height x 1.2 -->
<dimen name="more_keys_keyboard_slide_allowance">98.3dp</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="more_keys_keyboard_vertical_correction">-81.9dp</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction_gb">-81.9dp</dimen>
<!-- left or right padding of label alignment -->
<dimen name="key_label_horizontal_padding">6dp</dimen>
@@ -65,7 +59,7 @@
<fraction name="key_preview_text_ratio">50%</fraction>
<fraction name="spacebar_text_ratio">29.03%</fraction>
<dimen name="key_preview_height">94.5dp</dimen>
- <dimen name="key_preview_offset">16.0dp</dimen>
+ <dimen name="key_preview_offset_gb">16.0dp</dimen>
<!-- For 5-row keyboard -->
<fraction name="key_bottom_gap_5row">2.95%p</fraction>
@@ -94,4 +88,11 @@
<dimen name="gesture_floating_preview_horizontal_padding">26dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">17dp</dimen>
<dimen name="gesture_floating_preview_round_radius">3dp</dimen>
+
+ <!-- Emoji keyboard -->
+ <fraction name="emoji_keyboard_key_width">10%p</fraction>
+ <fraction name="emoji_keyboard_row_height">33%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">85%p</fraction>
+ <integer name="emoji_keyboard_max_key_count">30</integer>
+
</resources>
diff --git a/java/res/values-th/donottranslate.xml b/java/res/values-th/donottranslate.xml
new file mode 100644
index 000000000..a9893feec
--- /dev/null
+++ b/java/res/values-th/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Whether this language uses spaces between words -->
+ <bool name="current_language_has_spaces">false</bool>
+</resources>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index 9d407dda7..632f39a74 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"กดเว้นวรรคและเครื่องหมายจะแก้คำผิดอัตโนมัติ"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"ปิด"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"ปานกลาง"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"เข้มงวด"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"เข้มงวดมาก"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"เข้มงวด"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"เข้มงวดมาก"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"คำแนะนำสำหรับคำถัดไป"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"ใช้คำก่อนหน้าในการสร้างข้อเสนอแนะ"</string>
<string name="gesture_input" msgid="826951152254563827">"เปิดการพิมพ์ด้วยท่าทางสัมผัส"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"อังกฤษ (สหราชอาณาจักร) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"อังกฤษ (สหรัฐอเมริกา) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"สเปน (สหรัฐอเมริกา) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"ไม่มีภาษา"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"ไม่มีภาษา (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"ไม่มีภาษา (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"ไม่มีภาษา (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"ไม่มีภาษา (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"ไม่มีภาษา (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"ไม่มีภาษา (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (ดั้งเดิม)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"ไม่มีภาษา (ตัวอักษรละติน)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"ตัวอักษร (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"ตัวอักษร (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"ตัวอักษร (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"ตัวอักษร (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"ตัวอักษร (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"ตัวอักษร (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"อีโมจิ"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"รูปแบบอินพุตกำหนดเอง"</string>
<string name="add_style" msgid="6163126614514489951">"เพิ่มสไตล์"</string>
<string name="add" msgid="8299699805688017798">"เพิ่ม"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index ee5d88657..3ec962b01 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Awto tinatama ng spacebar at bantas ang maling na-type"</string>
<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_aggressive" msgid="3524029103734923819">"Agresibo"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Napaka-agresibo"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Agresibo"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Napaka-agresibo"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Mga suhestiyon sa susunod na salita"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Gamitin ang nakaraang salita sa paggawa ng mga suhestiyon"</string>
<string name="gesture_input" msgid="826951152254563827">"Paganahin ang gesture na pag-type"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Ingles (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Ingles (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Spanish (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Walang wika"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Walang wika (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Walang wika (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Walang wika (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Walang wika (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Walang wika (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Walang wika (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Traditional)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Walang wika (Alpabeto)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alpabeto (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alpabeto (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alpabeto (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alpabeto (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alpabeto (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alpabeto (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Custom style ng input"</string>
<string name="add_style" msgid="6163126614514489951">"Dagdag style"</string>
<string name="add" msgid="8299699805688017798">"Idagdag"</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 2e7fa4353..4d0a6174c 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Boşluk tuşu ve noktalama işaretleri yanlış yazılan kelimeleri otomatikman düzeltir"</string>
<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_aggressive" msgid="3524029103734923819">"Agresif"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Çok geniş ölçekte"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Geniş ölçekte"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Çok geniş ölçekte"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Sonraki kelime önerileri"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Önerilerde bulunurken önceki kelimeyi kullan"</string>
<string name="gesture_input" msgid="826951152254563827">"Hareketle yazmayı etkinleştir"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"İngilizce (İngiltere) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"İngilizce (ABD) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"İspanyolca (ABD) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Dil yok"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Dil yok (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Dil yok (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Dil yok (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Dil yok (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Dil yok (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Dil yok (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Geleneksel)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Dil yok (Alfabe)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabe (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabe (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabe (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabe (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabe (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabe (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Özel giriş stilleri"</string>
<string name="add_style" msgid="6163126614514489951">"Stil ekle"</string>
<string name="add" msgid="8299699805688017798">"Ekle"</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index fdc7cb922..df62f3286 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Пробіл і пунктуація автоматично виправляють слова з помилками"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Вимк."</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Помірне"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Активне"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Дуже активне"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Активне"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Дуже активне"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Пропозиції наступного слова"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Використовувати попереднє слово, щоб надавати пропозиції"</string>
<string name="gesture_input" msgid="826951152254563827">"Увімкнути ввід жестами"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Англійська (Великобр.) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Англійська (США) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"іспанська (США) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Мову не вибрано"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"QWERTY-клавіатура"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Без мови (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Без мови (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Без мови (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Без мови (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Без мови (ПК)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (традиційна)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Стандартна (латиниця)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиниця (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиниця (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Латиниця (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Латиниця (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Латиниця (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Латиниця (ПК)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Cмайли Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Персональні стилі введення"</string>
<string name="add_style" msgid="6163126614514489951">"Додати стиль"</string>
<string name="add" msgid="8299699805688017798">"Додати"</string>
diff --git a/java/res/values-v18/emoji-categories.xml b/java/res/values-v18/emoji-categories.xml
new file mode 100644
index 000000000..2ea08159b
--- /dev/null
+++ b/java/res/values-v18/emoji-categories.xml
@@ -0,0 +1,909 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Note: This emoji code point list is valid on JB-MR2 (API == 18).
+ There is another emoji code point list for KLP and later under res/xml/values-v19. -->
+<resources>
+ <array
+ name="emoji_nature"
+ format="string"
+ >
+ <!-- <item>1f415</item> -->
+ <item>1f436</item>
+ <item>1f429</item>
+ <!-- <item>1f408</item> -->
+ <item>1f431</item>
+ <!-- <item>1f400</item> -->
+ <!-- <item>1f401</item> -->
+ <item>1f42d</item>
+ <item>1f439</item>
+ <item>1f422</item>
+ <!-- <item>1f407</item> -->
+ <item>1f430</item>
+ <!-- <item>1f413</item> -->
+ <item>1f414</item>
+ <item>1f423</item>
+ <item>1f424</item>
+ <item>1f425</item>
+ <item>1f426</item>
+ <!-- <item>1f40f</item> -->
+ <item>1f411</item>
+ <!-- <item>1f410</item> -->
+ <item>1f43a</item>
+ <!-- <item>1f403</item> -->
+ <!-- <item>1f402</item> -->
+ <!-- <item>1f404</item> -->
+ <item>1f42e</item>
+ <item>1f434</item>
+ <item>1f417</item>
+ <!-- <item>1f416</item> -->
+ <item>1f437</item>
+ <item>1f43d</item>
+ <item>1f438</item>
+ <item>1f40d</item>
+ <item>1f43c</item>
+ <item>1f427</item>
+ <item>1f418</item>
+ <item>1f428</item>
+ <item>1f412</item>
+ <item>1f435</item>
+ <!-- <item>1f406</item> -->
+ <item>1f42f</item>
+ <item>1f43b</item>
+ <item>1f42b</item>
+ <!-- <item>1f42a</item> -->
+ <!-- <item>1f40a</item> -->
+ <item>1f433</item>
+ <!-- <item>1f40b</item> -->
+ <item>1f41f</item>
+ <item>1f420</item>
+ <item>1f421</item>
+ <item>1f419</item>
+ <item>1f41a</item>
+ <item>1f42c</item>
+ <item>1f40c</item>
+ <item>1f41b</item>
+ <item>1f41c</item>
+ <item>1f41d</item>
+ <item>1f41e</item>
+ <item>1f432</item>
+ <!-- <item>1f409</item> -->
+ <item>1f43e</item>
+ <item>1f378</item>
+ <item>1f37a</item>
+ <item>1f37b</item>
+ <item>1f377</item>
+ <item>1f379</item>
+ <item>1f376</item>
+ <!-- <item>2615</item> -->
+ <item>1f375</item>
+ <!-- <item>1f37c</item> -->
+ <item>1f374</item>
+ <item>1f368</item>
+ <item>1f367</item>
+ <item>1f366</item>
+ <item>1f369</item>
+ <item>1f370</item>
+ <item>1f36a</item>
+ <item>1f36b</item>
+ <item>1f36c</item>
+ <item>1f36d</item>
+ <item>1f36e</item>
+ <item>1f36f</item>
+ <item>1f373</item>
+ <item>1f354</item>
+ <item>1f35f</item>
+ <item>1f35d</item>
+ <item>1f355</item>
+ <item>1f356</item>
+ <item>1f357</item>
+ <item>1f364</item>
+ <item>1f363</item>
+ <item>1f371</item>
+ <item>1f35e</item>
+ <item>1f35c</item>
+ <item>1f359</item>
+ <item>1f35a</item>
+ <item>1f35b</item>
+ <item>1f372</item>
+ <item>1f365</item>
+ <item>1f362</item>
+ <item>1f361</item>
+ <item>1f358</item>
+ <item>1f360</item>
+ <item>1f34c</item>
+ <item>1f34e</item>
+ <item>1f34f</item>
+ <item>1f34a</item>
+ <!-- <item>1f34b</item> -->
+ <item>1f344</item>
+ <item>1f345</item>
+ <item>1f346</item>
+ <item>1f347</item>
+ <item>1f348</item>
+ <item>1f349</item>
+ <!-- <item>1f350</item> -->
+ <item>1f351</item>
+ <item>1f352</item>
+ <item>1f353</item>
+ <item>1f34d</item>
+ <item>1f330</item>
+ <item>1f331</item>
+ <!-- <item>1f332</item> -->
+ <!-- <item>1f333</item> -->
+ <item>1f334</item>
+ <item>1f335</item>
+ <item>1f337</item>
+ <item>1f338</item>
+ <item>1f339</item>
+ <item>1f340</item>
+ <item>1f341</item>
+ <item>1f342</item>
+ <item>1f343</item>
+ <item>1f33a</item>
+ <item>1f33b</item>
+ <item>1f33c</item>
+ <item>1f33d</item>
+ <item>1f33e</item>
+ <item>1f33f</item>
+ <item>2600</item>
+ <item>1f308</item>
+ <item>26c5</item>
+ <item>2601</item>
+ <item>1f301</item>
+ <item>1f302</item>
+ <!-- <item>2614</item> -->
+ <item>1f4a7</item>
+ <item>26a1</item>
+ <item>1f300</item>
+ <item>2744</item>
+ <item>26c4</item>
+ <item>1f319</item>
+ <!-- <item>1f31e</item> -->
+ <!-- <item>1f31d</item> -->
+ <!-- <item>1f31a</item> -->
+ <item>1f31b</item>
+ <!-- <item>1f31c</item> -->
+ <item>1f311</item>
+ <!-- <item>1f312</item> -->
+ <item>1f313</item>
+ <item>1f314</item>
+ <item>1f315</item>
+ <!-- <item>1f316</item> -->
+ <!-- <item>1f317</item> -->
+ <!-- <item>1f318</item> -->
+ <item>1f391</item>
+ <item>1f304</item>
+ <item>1f305</item>
+ <item>1f307</item>
+ <item>1f306</item>
+ <item>1f303</item>
+ <item>1f30c</item>
+ <item>1f309</item>
+ <item>1f30a</item>
+ <item>1f30b</item>
+ <!-- <item>1f30e</item> -->
+ <item>1f30f</item>
+ <!-- <item>1f30d</item> -->
+ <!-- <item>1f310</item> -->
+ </array>
+ <array
+ name="emoji_symbols"
+ format="string"
+ >
+ <!-- <item>fe82e|0031,20e3</item> -->
+ <!-- <item>fe82f|0032,20e3</item> -->
+ <!-- <item>fe830|0033,20e3</item> -->
+ <!-- <item>fe831|0034,20e3</item> -->
+ <!-- <item>fe832|0035,20e3</item> -->
+ <!-- <item>fe833|0036,20e3</item> -->
+ <!-- <item>fe834|0037,20e3</item> -->
+ <!-- <item>fe835|0038,20e3</item> -->
+ <!-- <item>fe836|0039,20e3</item> -->
+ <!-- <item>fe837|0030,20e3</item> -->
+ <!-- <item>1f51f</item> -->
+ <!-- <item>fe82c|0023,20e3</item> -->
+ <item>1f51d</item>
+ <item>1f519</item>
+ <item>1f51b</item>
+ <item>1f51c</item>
+ <item>1f51a</item>
+ <item>23f3</item>
+ <item>231b</item>
+ <item>23f0</item>
+ <item>2648</item>
+ <item>2649</item>
+ <item>264a</item>
+ <item>264b</item>
+ <item>264c</item>
+ <item>264d</item>
+ <item>264e</item>
+ <item>264f</item>
+ <item>2650</item>
+ <item>2651</item>
+ <item>2652</item>
+ <item>2653</item>
+ <item>26ce</item>
+ <item>1f531</item>
+ <item>1f52f</item>
+ <item>1f6bb</item>
+ <!-- <item>1f6ae</item> -->
+ <!-- <item>1f6af</item> -->
+ <!-- <item>1f6b0</item> -->
+ <!-- <item>1f6b1</item> -->
+ <item>1f170</item>
+ <item>1f171</item>
+ <item>1f18e</item>
+ <item>1f17e</item>
+ <item>1f4ae</item>
+ <item>1f4af</item>
+ <item>1f520</item>
+ <item>1f521</item>
+ <item>1f522</item>
+ <item>1f523</item>
+ <item>1f524</item>
+ <item>27bf</item>
+ <item>1f4f6</item>
+ <item>1f4f3</item>
+ <item>1f4f4</item>
+ <!-- <item>1f4f5</item> -->
+ <item>1f6b9</item>
+ <item>1f6ba</item>
+ <item>1f6bc</item>
+ <item>267f</item>
+ <item>267b</item>
+ <item>1f6ad</item>
+ <item>1f6a9</item>
+ <item>26a0</item>
+ <item>1f201</item>
+ <item>1f51e</item>
+ <item>26d4</item>
+ <item>1f192</item>
+ <item>1f197</item>
+ <item>1f195</item>
+ <item>1f198</item>
+ <item>1f199</item>
+ <item>1f193</item>
+ <item>1f196</item>
+ <item>1f19a</item>
+ <item>1f232</item>
+ <item>1f233</item>
+ <item>1f234</item>
+ <item>1f235</item>
+ <item>1f236</item>
+ <item>1f237</item>
+ <item>1f238</item>
+ <item>1f239</item>
+ <item>1f202</item>
+ <item>1f23a</item>
+ <item>1f250</item>
+ <item>1f251</item>
+ <item>3299</item>
+ <item>00ae</item>
+ <item>00a9</item>
+ <item>2122</item>
+ <item>1f21a</item>
+ <item>1f22f</item>
+ <item>3297</item>
+ <item>2b55</item>
+ <item>274c</item>
+ <item>274e</item>
+ <item>2139</item>
+ <item>1f6ab</item>
+ <item>2705</item>
+ <item>2714</item>
+ <item>1f517</item>
+ <item>2734</item>
+ <item>2733</item>
+ <item>2795</item>
+ <item>2796</item>
+ <item>2716</item>
+ <item>2797</item>
+ <item>1f4a0</item>
+ <item>1f4a1</item>
+ <item>1f4a4</item>
+ <item>1f4a2</item>
+ <item>1f525</item>
+ <item>1f4a5</item>
+ <item>1f4a8</item>
+ <item>1f4a6</item>
+ <item>1f4ab</item>
+ <item>1f55b</item>
+ <!-- <item>1f567</item> -->
+ <item>1f550</item>
+ <!-- <item>1f55c</item> -->
+ <item>1f551</item>
+ <!-- <item>1f55d</item> -->
+ <item>1f552</item>
+ <!-- <item>1f55e</item> -->
+ <item>1f553</item>
+ <!-- <item>1f55f</item> -->
+ <item>1f554</item>
+ <!-- <item>1f560</item> -->
+ <item>1f555</item>
+ <!-- <item>1f561</item> -->
+ <item>1f556</item>
+ <!-- <item>1f562</item> -->
+ <item>1f557</item>
+ <!-- <item>1f563</item> -->
+ <item>1f558</item>
+ <!-- <item>1f564</item> -->
+ <item>1f559</item>
+ <!-- <item>1f565</item> -->
+ <item>1f55a</item>
+ <!-- <item>1f566</item> -->
+ <item>2195</item>
+ <item>2b06</item>
+ <item>2197</item>
+ <item>27a1</item>
+ <item>2198</item>
+ <item>2b07</item>
+ <item>2199</item>
+ <item>2b05</item>
+ <item>2196</item>
+ <item>2194</item>
+ <item>2934</item>
+ <item>2935</item>
+ <item>23ea</item>
+ <item>23eb</item>
+ <item>23ec</item>
+ <item>23e9</item>
+ <item>25c0</item>
+ <item>25b6</item>
+ <item>1f53d</item>
+ <item>1f53c</item>
+ <item>2747</item>
+ <item>2728</item>
+ <item>1f534</item>
+ <item>1f535</item>
+ <item>26aa</item>
+ <item>26ab</item>
+ <item>1f533</item>
+ <item>1f532</item>
+ <item>2b50</item>
+ <item>1f31f</item>
+ <item>1f320</item>
+ <item>25ab</item>
+ <item>25aa</item>
+ <item>25fd</item>
+ <item>25fe</item>
+ <item>25fb</item>
+ <item>25fc</item>
+ <item>2b1c</item>
+ <item>2b1b</item>
+ <item>1f538</item>
+ <item>1f539</item>
+ <item>1f536</item>
+ <item>1f537</item>
+ <item>1f53a</item>
+ <item>1f53b</item>
+ <item>2754</item>
+ <item>2753</item>
+ <item>2755</item>
+ <item>2757</item>
+ <item>203c</item>
+ <item>2049</item>
+ <item>3030</item>
+ <item>27b0</item>
+ <item>2660</item>
+ <item>2665</item>
+ <item>2663</item>
+ <item>2666</item>
+ <item>1f194</item>
+ <item>1f511</item>
+ <item>21a9</item>
+ <item>1f191</item>
+ <item>1f50d</item>
+ <item>1f512</item>
+ <item>1f513</item>
+ <item>21aa</item>
+ <item>1f510</item>
+ <!-- <item>2611</item> -->
+ <item>1f518</item>
+ <item>1f50e</item>
+ <item>1f516</item>
+ <item>1f50f</item>
+ <item>1f503</item>
+ <!-- <item>1f500</item> -->
+ <!-- <item>1f501</item> -->
+ <!-- <item>1f502</item> -->
+ <!-- <item>1f504</item> -->
+ <item>1f4e7</item>
+ <!-- <item>1f505</item> -->
+ <!-- <item>1f506</item> -->
+ <!-- <item>1f507</item> -->
+ <!-- <item>1f508</item> -->
+ <!-- <item>1f509</item> -->
+ <item>1f50a</item>
+ </array>
+ <array
+ name="emoji_faces"
+ format="string"
+ >
+ <item>263a</item>
+ <item>1f60a</item>
+ <!-- <item>1f600</item> -->
+ <item>1f601</item>
+ <item>1f602</item>
+ <item>1f603</item>
+ <item>1f604</item>
+ <item>1f605</item>
+ <item>1f606</item>
+ <!-- <item>1f607</item> -->
+ <!-- <item>1f608</item> -->
+ <item>1f609</item>
+ <!-- <item>1f62f</item> -->
+ <!-- <item>1f610</item> -->
+ <!-- <item>1f611</item> -->
+ <!-- <item>1f615</item> -->
+ <item>1f620</item>
+ <!-- <item>1f62c</item> -->
+ <item>1f621</item>
+ <item>1f622</item>
+ <!-- <item>1f634</item> -->
+ <!-- <item>1f62e</item> -->
+ <item>1f623</item>
+ <item>1f624</item>
+ <item>1f625</item>
+ <!-- <item>1f626</item> -->
+ <!-- <item>1f627</item> -->
+ <item>1f628</item>
+ <item>1f629</item>
+ <item>1f630</item>
+ <!-- <item>1f61f</item> -->
+ <item>1f631</item>
+ <item>1f632</item>
+ <item>1f633</item>
+ <item>1f635</item>
+ <!-- <item>1f636</item> -->
+ <item>1f637</item>
+ <item>1f61e</item>
+ <item>1f612</item>
+ <item>1f60d</item>
+ <!-- <item>1f61b</item> -->
+ <item>1f61c</item>
+ <item>1f61d</item>
+ <item>1f60b</item>
+ <!-- <item>1f617</item> -->
+ <!-- <item>1f619</item> -->
+ <item>1f618</item>
+ <item>1f61a</item>
+ <!-- <item>1f60e</item> -->
+ <item>1f62d</item>
+ <item>1f60c</item>
+ <item>1f616</item>
+ <item>1f614</item>
+ <item>1f62a</item>
+ <item>1f60f</item>
+ <item>1f613</item>
+ <item>1f62b</item>
+ <item>1f64b</item>
+ <item>1f64c</item>
+ <item>1f64d</item>
+ <item>1f645</item>
+ <item>1f646</item>
+ <item>1f647</item>
+ <item>1f64e</item>
+ <item>1f64f</item>
+ <item>1f63a</item>
+ <item>1f63c</item>
+ <item>1f638</item>
+ <item>1f639</item>
+ <item>1f63b</item>
+ <item>1f63d</item>
+ <item>1f63f</item>
+ <item>1f63e</item>
+ <item>1f640</item>
+ <item>1f648</item>
+ <item>1f649</item>
+ <item>1f64a</item>
+ <item>1f4a9</item>
+ <item>1f476</item>
+ <item>1f466</item>
+ <item>1f467</item>
+ <item>1f468</item>
+ <item>1f469</item>
+ <item>1f474</item>
+ <item>1f475</item>
+ <item>1f48f</item>
+ <item>1f491</item>
+ <item>1f46a</item>
+ <item>1f46b</item>
+ <!-- <item>1f46c</item> -->
+ <!-- <item>1f46d</item> -->
+ <item>1f464</item>
+ <!-- <item>1f465</item> -->
+ <item>1f46e</item>
+ <item>1f477</item>
+ <item>1f481</item>
+ <item>1f482</item>
+ <item>1f46f</item>
+ <item>1f470</item>
+ <item>1f478</item>
+ <item>1f385</item>
+ <item>1f47c</item>
+ <!-- <item>1f471</item> -->
+ <!-- <item>1f472</item> -->
+ <!-- <item>1f473</item> -->
+ <item>1f483</item>
+ <item>1f486</item>
+ <item>1f487</item>
+ <item>1f485</item>
+ <item>1f47b</item>
+ <item>1f479</item>
+ <item>1f47a</item>
+ <item>1f47d</item>
+ <item>1f47e</item>
+ <item>1f47f</item>
+ <item>1f480</item>
+ <item>1f4aa</item>
+ <item>1f440</item>
+ <item>1f442</item>
+ <item>1f443</item>
+ <item>1f463</item>
+ <item>1f444</item>
+ <item>1f445</item>
+ <item>1f48b</item>
+ <item>2764</item>
+ <item>1f499</item>
+ <item>1f49a</item>
+ <item>1f49b</item>
+ <item>1f49c</item>
+ <item>1f493</item>
+ <item>1f494</item>
+ <item>1f495</item>
+ <item>1f496</item>
+ <item>1f497</item>
+ <item>1f498</item>
+ <item>1f49d</item>
+ <item>1f49e</item>
+ <item>1f49f</item>
+ <item>1f44d</item>
+ <item>1f44e</item>
+ <item>1f44c</item>
+ <item>270a</item>
+ <item>270c</item>
+ <item>270b</item>
+ <item>1f44a</item>
+ <!-- <item>261d</item> -->
+ <item>1f446</item>
+ <item>1f447</item>
+ <item>1f448</item>
+ <item>1f449</item>
+ <item>1f44b</item>
+ <item>1f44f</item>
+ <!-- <item>1f450</item> -->
+ </array>
+ <array
+ name="emoji_objects"
+ format="string"
+ >
+ <item>1f530</item>
+ <item>1f484</item>
+ <item>1f45e</item>
+ <item>1f45f</item>
+ <item>1f451</item>
+ <item>1f452</item>
+ <item>1f3a9</item>
+ <item>1f393</item>
+ <item>1f453</item>
+ <item>231a</item>
+ <item>1f454</item>
+ <item>1f455</item>
+ <item>1f456</item>
+ <item>1f457</item>
+ <item>1f458</item>
+ <item>1f459</item>
+ <item>1f460</item>
+ <item>1f461</item>
+ <item>1f462</item>
+ <item>1f45a</item>
+ <item>1f45c</item>
+ <item>1f4bc</item>
+ <item>1f392</item>
+ <item>1f45d</item>
+ <item>1f45b</item>
+ <item>1f4b0</item>
+ <item>1f4b3</item>
+ <item>1f4b2</item>
+ <item>1f4b5</item>
+ <item>1f4b4</item>
+ <!-- <item>1f4b6</item> -->
+ <!-- <item>1f4b7</item> -->
+ <item>1f4b8</item>
+ <item>1f4b1</item>
+ <item>1f4b9</item>
+ <item>1f52b</item>
+ <item>1f52a</item>
+ <item>1f4a3</item>
+ <item>1f489</item>
+ <item>1f48a</item>
+ <item>1f6ac</item>
+ <item>1f514</item>
+ <!-- <item>1f515</item> -->
+ <item>1f6aa</item>
+ <!-- <item>1f52c</item> -->
+ <!-- <item>1f52d</item> -->
+ <item>1f52e</item>
+ <item>1f526</item>
+ <item>1f50b</item>
+ <item>1f50c</item>
+ <item>1f4dc</item>
+ <item>1f4d7</item>
+ <item>1f4d8</item>
+ <item>1f4d9</item>
+ <item>1f4da</item>
+ <item>1f4d4</item>
+ <item>1f4d2</item>
+ <item>1f4d1</item>
+ <item>1f4d3</item>
+ <item>1f4d5</item>
+ <item>1f4d6</item>
+ <item>1f4f0</item>
+ <item>1f4db</item>
+ <item>1f383</item>
+ <item>1f384</item>
+ <item>1f380</item>
+ <item>1f381</item>
+ <item>1f382</item>
+ <item>1f388</item>
+ <item>1f386</item>
+ <item>1f387</item>
+ <item>1f389</item>
+ <item>1f38a</item>
+ <item>1f38d</item>
+ <item>1f38f</item>
+ <item>1f38c</item>
+ <item>1f390</item>
+ <item>1f38b</item>
+ <item>1f38e</item>
+ <item>1f4f1</item>
+ <item>1f4f2</item>
+ <item>1f4df</item>
+ <item>260e</item>
+ <item>1f4de</item>
+ <item>1f4e0</item>
+ <item>1f4e6</item>
+ <item>2709</item>
+ <item>1f4e8</item>
+ <item>1f4e9</item>
+ <item>1f4ea</item>
+ <item>1f4eb</item>
+ <!-- <item>1f4ed</item> -->
+ <!-- <item>1f4ec</item> -->
+ <item>1f4ee</item>
+ <item>1f4e4</item>
+ <item>1f4e5</item>
+ <!-- <item>1f4ef</item> -->
+ <item>1f4e2</item>
+ <item>1f4e3</item>
+ <item>1f4e1</item>
+ <item>1f4ac</item>
+ <!-- <item>1f4ad</item> -->
+ <item>2712</item>
+ <item>270f</item>
+ <item>1f4dd</item>
+ <item>1f4cf</item>
+ <item>1f4d0</item>
+ <item>1f4cd</item>
+ <item>1f4cc</item>
+ <item>1f4ce</item>
+ <item>2702</item>
+ <item>1f4ba</item>
+ <item>1f4bb</item>
+ <item>1f4bd</item>
+ <item>1f4be</item>
+ <item>1f4bf</item>
+ <item>1f4c6</item>
+ <item>1f4c5</item>
+ <item>1f4c7</item>
+ <item>1f4cb</item>
+ <item>1f4c1</item>
+ <item>1f4c2</item>
+ <item>1f4c3</item>
+ <item>1f4c4</item>
+ <item>1f4ca</item>
+ <item>1f4c8</item>
+ <item>1f4c9</item>
+ <item>26fa</item>
+ <item>1f3a1</item>
+ <item>1f3a2</item>
+ <item>1f3a0</item>
+ <item>1f3aa</item>
+ <item>1f3a8</item>
+ <item>1f3ac</item>
+ <item>1f3a5</item>
+ <item>1f4f7</item>
+ <item>1f4f9</item>
+ <item>1f3a6</item>
+ <item>1f3ad</item>
+ <item>1f3ab</item>
+ <item>1f3ae</item>
+ <item>1f3b2</item>
+ <item>1f3b0</item>
+ <item>1f0cf</item>
+ <item>1f3b4</item>
+ <item>1f004</item>
+ <item>1f3af</item>
+ <item>1f4fa</item>
+ <item>1f4fb</item>
+ <item>1f4c0</item>
+ <item>1f4fc</item>
+ <item>1f3a7</item>
+ <item>1f3a4</item>
+ <item>1f3b5</item>
+ <item>1f3b6</item>
+ <item>1f3bc</item>
+ <item>1f3bb</item>
+ <item>1f3b9</item>
+ <item>1f3b7</item>
+ <item>1f3ba</item>
+ <item>1f3b8</item>
+ <item>303d</item>
+ </array>
+ <array
+ name="emoji_places"
+ format="string"
+ >
+ <item>1f3e0</item>
+ <item>1f3e1</item>
+ <item>1f3e2</item>
+ <item>1f3e3</item>
+ <!-- <item>1f3e4</item> -->
+ <item>1f3e5</item>
+ <item>1f3e6</item>
+ <item>1f3e7</item>
+ <item>1f3e8</item>
+ <item>1f3e9</item>
+ <item>1f3ea</item>
+ <item>1f3eb</item>
+ <item>26ea</item>
+ <item>26f2</item>
+ <item>1f3ec</item>
+ <item>1f3ef</item>
+ <item>1f3f0</item>
+ <item>1f3ed</item>
+ <item>1f5fb</item>
+ <item>1f5fc</item>
+ <item>1f5fd</item>
+ <item>1f5fe</item>
+ <item>1f5ff</item>
+ <item>2693</item>
+ <item>1f3ee</item>
+ <item>1f488</item>
+ <item>1f527</item>
+ <item>1f528</item>
+ <item>1f529</item>
+ <!-- <item>1f6bf</item> -->
+ <!-- <item>1f6c1</item> -->
+ <item>1f6c0</item>
+ <item>1f6bd</item>
+ <item>1f6be</item>
+ <item>1f3bd</item>
+ <item>1f3a3</item>
+ <item>1f3b1</item>
+ <item>1f3b3</item>
+ <item>26be</item>
+ <item>26f3</item>
+ <item>1f3be</item>
+ <item>26bd</item>
+ <item>1f3bf</item>
+ <item>1f3c0</item>
+ <item>1f3c1</item>
+ <item>1f3c2</item>
+ <item>1f3c3</item>
+ <item>1f3c4</item>
+ <item>1f3c6</item>
+ <!-- <item>1f3c7</item> -->
+ <item>1f40e</item>
+ <item>1f3c8</item>
+ <!-- <item>1f3c9</item> -->
+ <item>1f3ca</item>
+ <!-- <item>1f682</item> -->
+ <item>1f683</item>
+ <item>1f684</item>
+ <item>1f685</item>
+ <!-- <item>1f686</item> -->
+ <item>1f687</item>
+ <item>24c2</item>
+ <!-- <item>1f688</item> -->
+ <!-- <item>1f68a</item> -->
+ <!-- <item>1f68b</item> -->
+ <item>1f68c</item>
+ <!-- <item>1f68d</item> -->
+ <!-- <item>1f68e</item> -->
+ <item>1f68f</item>
+ <!-- <item>1f690</item> -->
+ <item>1f691</item>
+ <item>1f692</item>
+ <item>1f693</item>
+ <!-- <item>1f694</item> -->
+ <item>1f695</item>
+ <!-- <item>1f696</item> -->
+ <item>1f697</item>
+ <!-- <item>1f698</item> -->
+ <item>1f699</item>
+ <!-- <item>1f69a</item> -->
+ <!-- <item>1f69b</item> -->
+ <!-- <item>1f69c</item> -->
+ <!-- <item>1f69d</item> -->
+ <!-- <item>1f69e</item> -->
+ <!-- <item>1f69f</item> -->
+ <!-- <item>1f6a0</item> -->
+ <!-- <item>1f6a1</item> -->
+ <item>1f6a2</item>
+ <!-- <item>1f6a3</item> -->
+ <!-- <item>1f681</item> -->
+ <item>2708</item>
+ <!-- <item>1f6c2</item> -->
+ <!-- <item>1f6c3</item> -->
+ <!-- <item>1f6c4</item> -->
+ <!-- <item>1f6c5</item> -->
+ <item>26f5</item>
+ <item>1f6b2</item>
+ <!-- <item>1f6b3</item> -->
+ <!-- <item>1f6b4</item> -->
+ <!-- <item>1f6b5</item> -->
+ <!-- <item>1f6b7</item> -->
+ <!-- <item>1f6b8</item> -->
+ <item>1f689</item>
+ <item>1f680</item>
+ <item>1f6a4</item>
+ <item>1f6b6</item>
+ <item>26fd</item>
+ <item>1f17f</item>
+ <item>1f6a5</item>
+ <!-- <item>1f6a6</item> -->
+ <item>1f6a7</item>
+ <item>1f6a8</item>
+ <item>2668</item>
+ <item>1f48c</item>
+ <item>1f48d</item>
+ <item>1f48e</item>
+ <item>1f490</item>
+ <item>1f492</item>
+ <item>fe4e5|1f1ef,1f1f5</item>
+ <item>fe4e6|1f1fa,1f1f8</item>
+ <item>fe4e7|1f1eb,1f1f7</item>
+ <item>fe4e8|1f1e9,1f1ea</item>
+ <item>fe4e9|1f1ee,1f1f9</item>
+ <item>fe4ea|1f1ec,1f1e7</item>
+ <item>fe4eb|1f1ea,1f1f8</item>
+ <item>fe4ec|1f1f7,1f1fa</item>
+ <item>fe4ed|1f1e8,1f1f3</item>
+ <item>fe4ee|1f1f0,1f1f7</item>
+ </array>
+ <array
+ name="emoji_emoticons"
+ format="string"
+ >
+ <item>=-O</item>
+ <item>:-P</item>
+ <item>;-)</item>
+ <item>:-(</item>
+ <item>:-)</item>
+ <item>:-!</item>
+ <item>:-$</item>
+ <item>B-)</item>
+ <item>:O</item>
+ <item>:-*</item>
+ <item>:-D</item>
+ <item>:\'(</item>
+ <item>:-\\</item>
+ <item>O:-)</item>
+ <item>:-[</item>
+ </array>
+</resources>
diff --git a/java/res/values-v19/emoji-categories.xml b/java/res/values-v19/emoji-categories.xml
new file mode 100644
index 000000000..658bbfa83
--- /dev/null
+++ b/java/res/values-v19/emoji-categories.xml
@@ -0,0 +1,909 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Note: This emoji code point list is valid on KLP and later (API >= 19).
+ There is another emoji code point list for JB-MR2 under res/xml/values and values-v18.-->
+<resources>
+ <array
+ name="emoji_nature"
+ format="string"
+ >
+ <item>1f415</item>
+ <item>1f436</item>
+ <item>1f429</item>
+ <item>1f408</item>
+ <item>1f431</item>
+ <item>1f400</item>
+ <item>1f401</item>
+ <item>1f42d</item>
+ <item>1f439</item>
+ <item>1f422</item>
+ <item>1f407</item>
+ <item>1f430</item>
+ <item>1f413</item>
+ <item>1f414</item>
+ <item>1f423</item>
+ <item>1f424</item>
+ <item>1f425</item>
+ <item>1f426</item>
+ <item>1f40f</item>
+ <item>1f411</item>
+ <item>1f410</item>
+ <item>1f43a</item>
+ <item>1f403</item>
+ <item>1f402</item>
+ <item>1f404</item>
+ <item>1f42e</item>
+ <item>1f434</item>
+ <item>1f417</item>
+ <item>1f416</item>
+ <item>1f437</item>
+ <item>1f43d</item>
+ <item>1f438</item>
+ <item>1f40d</item>
+ <item>1f43c</item>
+ <item>1f427</item>
+ <item>1f418</item>
+ <item>1f428</item>
+ <item>1f412</item>
+ <item>1f435</item>
+ <item>1f406</item>
+ <item>1f42f</item>
+ <item>1f43b</item>
+ <item>1f42b</item>
+ <item>1f42a</item>
+ <item>1f40a</item>
+ <item>1f433</item>
+ <item>1f40b</item>
+ <item>1f41f</item>
+ <item>1f420</item>
+ <item>1f421</item>
+ <item>1f419</item>
+ <item>1f41a</item>
+ <item>1f42c</item>
+ <item>1f40c</item>
+ <item>1f41b</item>
+ <item>1f41c</item>
+ <item>1f41d</item>
+ <item>1f41e</item>
+ <item>1f432</item>
+ <item>1f409</item>
+ <item>1f43e</item>
+ <item>1f378</item>
+ <item>1f37a</item>
+ <item>1f37b</item>
+ <item>1f377</item>
+ <item>1f379</item>
+ <item>1f376</item>
+ <item>2615</item>
+ <item>1f375</item>
+ <item>1f37c</item>
+ <item>1f374</item>
+ <item>1f368</item>
+ <item>1f367</item>
+ <item>1f366</item>
+ <item>1f369</item>
+ <item>1f370</item>
+ <item>1f36a</item>
+ <item>1f36b</item>
+ <item>1f36c</item>
+ <item>1f36d</item>
+ <item>1f36e</item>
+ <item>1f36f</item>
+ <item>1f373</item>
+ <item>1f354</item>
+ <item>1f35f</item>
+ <item>1f35d</item>
+ <item>1f355</item>
+ <item>1f356</item>
+ <item>1f357</item>
+ <item>1f364</item>
+ <item>1f363</item>
+ <item>1f371</item>
+ <item>1f35e</item>
+ <item>1f35c</item>
+ <item>1f359</item>
+ <item>1f35a</item>
+ <item>1f35b</item>
+ <item>1f372</item>
+ <item>1f365</item>
+ <item>1f362</item>
+ <item>1f361</item>
+ <item>1f358</item>
+ <item>1f360</item>
+ <item>1f34c</item>
+ <item>1f34e</item>
+ <item>1f34f</item>
+ <item>1f34a</item>
+ <item>1f34b</item>
+ <item>1f344</item>
+ <item>1f345</item>
+ <item>1f346</item>
+ <item>1f347</item>
+ <item>1f348</item>
+ <item>1f349</item>
+ <item>1f350</item>
+ <item>1f351</item>
+ <item>1f352</item>
+ <item>1f353</item>
+ <item>1f34d</item>
+ <item>1f330</item>
+ <item>1f331</item>
+ <item>1f332</item>
+ <item>1f333</item>
+ <item>1f334</item>
+ <item>1f335</item>
+ <item>1f337</item>
+ <item>1f338</item>
+ <item>1f339</item>
+ <item>1f340</item>
+ <item>1f341</item>
+ <item>1f342</item>
+ <item>1f343</item>
+ <item>1f33a</item>
+ <item>1f33b</item>
+ <item>1f33c</item>
+ <item>1f33d</item>
+ <item>1f33e</item>
+ <item>1f33f</item>
+ <item>2600</item>
+ <item>1f308</item>
+ <item>26c5</item>
+ <item>2601</item>
+ <item>1f301</item>
+ <item>1f302</item>
+ <item>2614</item>
+ <item>1f4a7</item>
+ <item>26a1</item>
+ <item>1f300</item>
+ <item>2744</item>
+ <item>26c4</item>
+ <item>1f319</item>
+ <item>1f31e</item>
+ <item>1f31d</item>
+ <item>1f31a</item>
+ <item>1f31b</item>
+ <item>1f31c</item>
+ <item>1f311</item>
+ <item>1f312</item>
+ <item>1f313</item>
+ <item>1f314</item>
+ <item>1f315</item>
+ <item>1f316</item>
+ <item>1f317</item>
+ <item>1f318</item>
+ <item>1f391</item>
+ <item>1f304</item>
+ <item>1f305</item>
+ <item>1f307</item>
+ <item>1f306</item>
+ <item>1f303</item>
+ <item>1f30c</item>
+ <item>1f309</item>
+ <item>1f30a</item>
+ <item>1f30b</item>
+ <item>1f30e</item>
+ <item>1f30f</item>
+ <item>1f30d</item>
+ <item>1f310</item>
+ </array>
+ <array
+ name="emoji_symbols"
+ format="string"
+ >
+ <item>fe82e|0031,20e3</item>
+ <item>fe82f|0032,20e3</item>
+ <item>fe830|0033,20e3</item>
+ <item>fe831|0034,20e3</item>
+ <item>fe832|0035,20e3</item>
+ <item>fe833|0036,20e3</item>
+ <item>fe834|0037,20e3</item>
+ <item>fe835|0038,20e3</item>
+ <item>fe836|0039,20e3</item>
+ <item>fe837|0030,20e3</item>
+ <item>1f51f</item>
+ <item>fe82c|0023,20e3</item>
+ <item>1f51d</item>
+ <item>1f519</item>
+ <item>1f51b</item>
+ <item>1f51c</item>
+ <item>1f51a</item>
+ <item>23f3</item>
+ <item>231b</item>
+ <item>23f0</item>
+ <item>2648</item>
+ <item>2649</item>
+ <item>264a</item>
+ <item>264b</item>
+ <item>264c</item>
+ <item>264d</item>
+ <item>264e</item>
+ <item>264f</item>
+ <item>2650</item>
+ <item>2651</item>
+ <item>2652</item>
+ <item>2653</item>
+ <item>26ce</item>
+ <item>1f531</item>
+ <item>1f52f</item>
+ <item>1f6bb</item>
+ <item>1f6ae</item>
+ <item>1f6af</item>
+ <item>1f6b0</item>
+ <item>1f6b1</item>
+ <item>1f170</item>
+ <item>1f171</item>
+ <item>1f18e</item>
+ <item>1f17e</item>
+ <item>1f4ae</item>
+ <item>1f4af</item>
+ <item>1f520</item>
+ <item>1f521</item>
+ <item>1f522</item>
+ <item>1f523</item>
+ <item>1f524</item>
+ <item>27bf</item>
+ <item>1f4f6</item>
+ <item>1f4f3</item>
+ <item>1f4f4</item>
+ <item>1f4f5</item>
+ <item>1f6b9</item>
+ <item>1f6ba</item>
+ <item>1f6bc</item>
+ <item>267f</item>
+ <item>267b</item>
+ <item>1f6ad</item>
+ <item>1f6a9</item>
+ <item>26a0</item>
+ <item>1f201</item>
+ <item>1f51e</item>
+ <item>26d4</item>
+ <item>1f192</item>
+ <item>1f197</item>
+ <item>1f195</item>
+ <item>1f198</item>
+ <item>1f199</item>
+ <item>1f193</item>
+ <item>1f196</item>
+ <item>1f19a</item>
+ <item>1f232</item>
+ <item>1f233</item>
+ <item>1f234</item>
+ <item>1f235</item>
+ <item>1f236</item>
+ <item>1f237</item>
+ <item>1f238</item>
+ <item>1f239</item>
+ <item>1f202</item>
+ <item>1f23a</item>
+ <item>1f250</item>
+ <item>1f251</item>
+ <item>3299</item>
+ <item>00ae</item>
+ <item>00a9</item>
+ <item>2122</item>
+ <item>1f21a</item>
+ <item>1f22f</item>
+ <item>3297</item>
+ <item>2b55</item>
+ <item>274c</item>
+ <item>274e</item>
+ <item>2139</item>
+ <item>1f6ab</item>
+ <item>2705</item>
+ <item>2714</item>
+ <item>1f517</item>
+ <item>2734</item>
+ <item>2733</item>
+ <item>2795</item>
+ <item>2796</item>
+ <item>2716</item>
+ <item>2797</item>
+ <item>1f4a0</item>
+ <item>1f4a1</item>
+ <item>1f4a4</item>
+ <item>1f4a2</item>
+ <item>1f525</item>
+ <item>1f4a5</item>
+ <item>1f4a8</item>
+ <item>1f4a6</item>
+ <item>1f4ab</item>
+ <item>1f55b</item>
+ <item>1f567</item>
+ <item>1f550</item>
+ <item>1f55c</item>
+ <item>1f551</item>
+ <item>1f55d</item>
+ <item>1f552</item>
+ <item>1f55e</item>
+ <item>1f553</item>
+ <item>1f55f</item>
+ <item>1f554</item>
+ <item>1f560</item>
+ <item>1f555</item>
+ <item>1f561</item>
+ <item>1f556</item>
+ <item>1f562</item>
+ <item>1f557</item>
+ <item>1f563</item>
+ <item>1f558</item>
+ <item>1f564</item>
+ <item>1f559</item>
+ <item>1f565</item>
+ <item>1f55a</item>
+ <item>1f566</item>
+ <item>2195</item>
+ <item>2b06</item>
+ <item>2197</item>
+ <item>27a1</item>
+ <item>2198</item>
+ <item>2b07</item>
+ <item>2199</item>
+ <item>2b05</item>
+ <item>2196</item>
+ <item>2194</item>
+ <item>2934</item>
+ <item>2935</item>
+ <item>23ea</item>
+ <item>23eb</item>
+ <item>23ec</item>
+ <item>23e9</item>
+ <item>25c0</item>
+ <item>25b6</item>
+ <item>1f53d</item>
+ <item>1f53c</item>
+ <item>2747</item>
+ <item>2728</item>
+ <item>1f534</item>
+ <item>1f535</item>
+ <item>26aa</item>
+ <item>26ab</item>
+ <item>1f533</item>
+ <item>1f532</item>
+ <item>2b50</item>
+ <item>1f31f</item>
+ <item>1f320</item>
+ <item>25ab</item>
+ <item>25aa</item>
+ <item>25fd</item>
+ <item>25fe</item>
+ <item>25fb</item>
+ <item>25fc</item>
+ <item>2b1c</item>
+ <item>2b1b</item>
+ <item>1f538</item>
+ <item>1f539</item>
+ <item>1f536</item>
+ <item>1f537</item>
+ <item>1f53a</item>
+ <item>1f53b</item>
+ <item>2754</item>
+ <item>2753</item>
+ <item>2755</item>
+ <item>2757</item>
+ <item>203c</item>
+ <item>2049</item>
+ <item>3030</item>
+ <item>27b0</item>
+ <item>2660</item>
+ <item>2665</item>
+ <item>2663</item>
+ <item>2666</item>
+ <item>1f194</item>
+ <item>1f511</item>
+ <item>21a9</item>
+ <item>1f191</item>
+ <item>1f50d</item>
+ <item>1f512</item>
+ <item>1f513</item>
+ <item>21aa</item>
+ <item>1f510</item>
+ <item>2611</item>
+ <item>1f518</item>
+ <item>1f50e</item>
+ <item>1f516</item>
+ <item>1f50f</item>
+ <item>1f503</item>
+ <item>1f500</item>
+ <item>1f501</item>
+ <item>1f502</item>
+ <item>1f504</item>
+ <item>1f4e7</item>
+ <item>1f505</item>
+ <item>1f506</item>
+ <item>1f507</item>
+ <item>1f508</item>
+ <item>1f509</item>
+ <item>1f50a</item>
+ </array>
+ <array
+ name="emoji_faces"
+ format="string"
+ >
+ <item>263a</item>
+ <item>1f60a</item>
+ <item>1f600</item>
+ <item>1f601</item>
+ <item>1f602</item>
+ <item>1f603</item>
+ <item>1f604</item>
+ <item>1f605</item>
+ <item>1f606</item>
+ <item>1f607</item>
+ <item>1f608</item>
+ <item>1f609</item>
+ <item>1f62f</item>
+ <item>1f610</item>
+ <item>1f611</item>
+ <item>1f615</item>
+ <item>1f620</item>
+ <item>1f62c</item>
+ <item>1f621</item>
+ <item>1f622</item>
+ <item>1f634</item>
+ <item>1f62e</item>
+ <item>1f623</item>
+ <item>1f624</item>
+ <item>1f625</item>
+ <item>1f626</item>
+ <item>1f627</item>
+ <item>1f628</item>
+ <item>1f629</item>
+ <item>1f630</item>
+ <item>1f61f</item>
+ <item>1f631</item>
+ <item>1f632</item>
+ <item>1f633</item>
+ <item>1f635</item>
+ <item>1f636</item>
+ <item>1f637</item>
+ <item>1f61e</item>
+ <item>1f612</item>
+ <item>1f60d</item>
+ <item>1f61b</item>
+ <item>1f61c</item>
+ <item>1f61d</item>
+ <item>1f60b</item>
+ <item>1f617</item>
+ <item>1f619</item>
+ <item>1f618</item>
+ <item>1f61a</item>
+ <item>1f60e</item>
+ <item>1f62d</item>
+ <item>1f60c</item>
+ <item>1f616</item>
+ <item>1f614</item>
+ <item>1f62a</item>
+ <item>1f60f</item>
+ <item>1f613</item>
+ <item>1f62b</item>
+ <item>1f64b</item>
+ <item>1f64c</item>
+ <item>1f64d</item>
+ <item>1f645</item>
+ <item>1f646</item>
+ <item>1f647</item>
+ <item>1f64e</item>
+ <item>1f64f</item>
+ <item>1f63a</item>
+ <item>1f63c</item>
+ <item>1f638</item>
+ <item>1f639</item>
+ <item>1f63b</item>
+ <item>1f63d</item>
+ <item>1f63f</item>
+ <item>1f63e</item>
+ <item>1f640</item>
+ <item>1f648</item>
+ <item>1f649</item>
+ <item>1f64a</item>
+ <item>1f4a9</item>
+ <item>1f476</item>
+ <item>1f466</item>
+ <item>1f467</item>
+ <item>1f468</item>
+ <item>1f469</item>
+ <item>1f474</item>
+ <item>1f475</item>
+ <item>1f48f</item>
+ <item>1f491</item>
+ <item>1f46a</item>
+ <item>1f46b</item>
+ <item>1f46c</item>
+ <item>1f46d</item>
+ <item>1f464</item>
+ <item>1f465</item>
+ <item>1f46e</item>
+ <item>1f477</item>
+ <item>1f481</item>
+ <item>1f482</item>
+ <item>1f46f</item>
+ <item>1f470</item>
+ <item>1f478</item>
+ <item>1f385</item>
+ <item>1f47c</item>
+ <item>1f471</item>
+ <item>1f472</item>
+ <item>1f473</item>
+ <item>1f483</item>
+ <item>1f486</item>
+ <item>1f487</item>
+ <item>1f485</item>
+ <item>1f47b</item>
+ <item>1f479</item>
+ <item>1f47a</item>
+ <item>1f47d</item>
+ <item>1f47e</item>
+ <item>1f47f</item>
+ <item>1f480</item>
+ <item>1f4aa</item>
+ <item>1f440</item>
+ <item>1f442</item>
+ <item>1f443</item>
+ <item>1f463</item>
+ <item>1f444</item>
+ <item>1f445</item>
+ <item>1f48b</item>
+ <item>2764</item>
+ <item>1f499</item>
+ <item>1f49a</item>
+ <item>1f49b</item>
+ <item>1f49c</item>
+ <item>1f493</item>
+ <item>1f494</item>
+ <item>1f495</item>
+ <item>1f496</item>
+ <item>1f497</item>
+ <item>1f498</item>
+ <item>1f49d</item>
+ <item>1f49e</item>
+ <item>1f49f</item>
+ <item>1f44d</item>
+ <item>1f44e</item>
+ <item>1f44c</item>
+ <item>270a</item>
+ <item>270c</item>
+ <item>270b</item>
+ <item>1f44a</item>
+ <item>261d</item>
+ <item>1f446</item>
+ <item>1f447</item>
+ <item>1f448</item>
+ <item>1f449</item>
+ <item>1f44b</item>
+ <item>1f44f</item>
+ <item>1f450</item>
+ </array>
+ <array
+ name="emoji_objects"
+ format="string"
+ >
+ <item>1f530</item>
+ <item>1f484</item>
+ <item>1f45e</item>
+ <item>1f45f</item>
+ <item>1f451</item>
+ <item>1f452</item>
+ <item>1f3a9</item>
+ <item>1f393</item>
+ <item>1f453</item>
+ <item>231a</item>
+ <item>1f454</item>
+ <item>1f455</item>
+ <item>1f456</item>
+ <item>1f457</item>
+ <item>1f458</item>
+ <item>1f459</item>
+ <item>1f460</item>
+ <item>1f461</item>
+ <item>1f462</item>
+ <item>1f45a</item>
+ <item>1f45c</item>
+ <item>1f4bc</item>
+ <item>1f392</item>
+ <item>1f45d</item>
+ <item>1f45b</item>
+ <item>1f4b0</item>
+ <item>1f4b3</item>
+ <item>1f4b2</item>
+ <item>1f4b5</item>
+ <item>1f4b4</item>
+ <item>1f4b6</item>
+ <item>1f4b7</item>
+ <item>1f4b8</item>
+ <item>1f4b1</item>
+ <item>1f4b9</item>
+ <item>1f52b</item>
+ <item>1f52a</item>
+ <item>1f4a3</item>
+ <item>1f489</item>
+ <item>1f48a</item>
+ <item>1f6ac</item>
+ <item>1f514</item>
+ <item>1f515</item>
+ <item>1f6aa</item>
+ <item>1f52c</item>
+ <item>1f52d</item>
+ <item>1f52e</item>
+ <item>1f526</item>
+ <item>1f50b</item>
+ <item>1f50c</item>
+ <item>1f4dc</item>
+ <item>1f4d7</item>
+ <item>1f4d8</item>
+ <item>1f4d9</item>
+ <item>1f4da</item>
+ <item>1f4d4</item>
+ <item>1f4d2</item>
+ <item>1f4d1</item>
+ <item>1f4d3</item>
+ <item>1f4d5</item>
+ <item>1f4d6</item>
+ <item>1f4f0</item>
+ <item>1f4db</item>
+ <item>1f383</item>
+ <item>1f384</item>
+ <item>1f380</item>
+ <item>1f381</item>
+ <item>1f382</item>
+ <item>1f388</item>
+ <item>1f386</item>
+ <item>1f387</item>
+ <item>1f389</item>
+ <item>1f38a</item>
+ <item>1f38d</item>
+ <item>1f38f</item>
+ <item>1f38c</item>
+ <item>1f390</item>
+ <item>1f38b</item>
+ <item>1f38e</item>
+ <item>1f4f1</item>
+ <item>1f4f2</item>
+ <item>1f4df</item>
+ <item>260e</item>
+ <item>1f4de</item>
+ <item>1f4e0</item>
+ <item>1f4e6</item>
+ <item>2709</item>
+ <item>1f4e8</item>
+ <item>1f4e9</item>
+ <item>1f4ea</item>
+ <item>1f4eb</item>
+ <item>1f4ed</item>
+ <item>1f4ec</item>
+ <item>1f4ee</item>
+ <item>1f4e4</item>
+ <item>1f4e5</item>
+ <item>1f4ef</item>
+ <item>1f4e2</item>
+ <item>1f4e3</item>
+ <item>1f4e1</item>
+ <item>1f4ac</item>
+ <item>1f4ad</item>
+ <item>2712</item>
+ <item>270f</item>
+ <item>1f4dd</item>
+ <item>1f4cf</item>
+ <item>1f4d0</item>
+ <item>1f4cd</item>
+ <item>1f4cc</item>
+ <item>1f4ce</item>
+ <item>2702</item>
+ <item>1f4ba</item>
+ <item>1f4bb</item>
+ <item>1f4bd</item>
+ <item>1f4be</item>
+ <item>1f4bf</item>
+ <item>1f4c6</item>
+ <item>1f4c5</item>
+ <item>1f4c7</item>
+ <item>1f4cb</item>
+ <item>1f4c1</item>
+ <item>1f4c2</item>
+ <item>1f4c3</item>
+ <item>1f4c4</item>
+ <item>1f4ca</item>
+ <item>1f4c8</item>
+ <item>1f4c9</item>
+ <item>26fa</item>
+ <item>1f3a1</item>
+ <item>1f3a2</item>
+ <item>1f3a0</item>
+ <item>1f3aa</item>
+ <item>1f3a8</item>
+ <item>1f3ac</item>
+ <item>1f3a5</item>
+ <item>1f4f7</item>
+ <item>1f4f9</item>
+ <item>1f3a6</item>
+ <item>1f3ad</item>
+ <item>1f3ab</item>
+ <item>1f3ae</item>
+ <item>1f3b2</item>
+ <item>1f3b0</item>
+ <item>1f0cf</item>
+ <item>1f3b4</item>
+ <item>1f004</item>
+ <item>1f3af</item>
+ <item>1f4fa</item>
+ <item>1f4fb</item>
+ <item>1f4c0</item>
+ <item>1f4fc</item>
+ <item>1f3a7</item>
+ <item>1f3a4</item>
+ <item>1f3b5</item>
+ <item>1f3b6</item>
+ <item>1f3bc</item>
+ <item>1f3bb</item>
+ <item>1f3b9</item>
+ <item>1f3b7</item>
+ <item>1f3ba</item>
+ <item>1f3b8</item>
+ <item>303d</item>
+ </array>
+ <array
+ name="emoji_places"
+ format="string"
+ >
+ <item>1f3e0</item>
+ <item>1f3e1</item>
+ <item>1f3e2</item>
+ <item>1f3e3</item>
+ <item>1f3e4</item>
+ <item>1f3e5</item>
+ <item>1f3e6</item>
+ <item>1f3e7</item>
+ <item>1f3e8</item>
+ <item>1f3e9</item>
+ <item>1f3ea</item>
+ <item>1f3eb</item>
+ <item>26ea</item>
+ <item>26f2</item>
+ <item>1f3ec</item>
+ <item>1f3ef</item>
+ <item>1f3f0</item>
+ <item>1f3ed</item>
+ <item>1f5fb</item>
+ <item>1f5fc</item>
+ <item>1f5fd</item>
+ <item>1f5fe</item>
+ <item>1f5ff</item>
+ <item>2693</item>
+ <item>1f3ee</item>
+ <item>1f488</item>
+ <item>1f527</item>
+ <item>1f528</item>
+ <item>1f529</item>
+ <item>1f6bf</item>
+ <item>1f6c1</item>
+ <item>1f6c0</item>
+ <item>1f6bd</item>
+ <item>1f6be</item>
+ <item>1f3bd</item>
+ <item>1f3a3</item>
+ <item>1f3b1</item>
+ <item>1f3b3</item>
+ <item>26be</item>
+ <item>26f3</item>
+ <item>1f3be</item>
+ <item>26bd</item>
+ <item>1f3bf</item>
+ <item>1f3c0</item>
+ <item>1f3c1</item>
+ <item>1f3c2</item>
+ <item>1f3c3</item>
+ <item>1f3c4</item>
+ <item>1f3c6</item>
+ <item>1f3c7</item>
+ <item>1f40e</item>
+ <item>1f3c8</item>
+ <item>1f3c9</item>
+ <item>1f3ca</item>
+ <item>1f682</item>
+ <item>1f683</item>
+ <item>1f684</item>
+ <item>1f685</item>
+ <item>1f686</item>
+ <item>1f687</item>
+ <item>24c2</item>
+ <item>1f688</item>
+ <item>1f68a</item>
+ <item>1f68b</item>
+ <item>1f68c</item>
+ <item>1f68d</item>
+ <item>1f68e</item>
+ <item>1f68f</item>
+ <item>1f690</item>
+ <item>1f691</item>
+ <item>1f692</item>
+ <item>1f693</item>
+ <item>1f694</item>
+ <item>1f695</item>
+ <item>1f696</item>
+ <item>1f697</item>
+ <item>1f698</item>
+ <item>1f699</item>
+ <item>1f69a</item>
+ <item>1f69b</item>
+ <item>1f69c</item>
+ <item>1f69d</item>
+ <item>1f69e</item>
+ <item>1f69f</item>
+ <item>1f6a0</item>
+ <item>1f6a1</item>
+ <item>1f6a2</item>
+ <item>1f6a3</item>
+ <item>1f681</item>
+ <item>2708</item>
+ <item>1f6c2</item>
+ <item>1f6c3</item>
+ <item>1f6c4</item>
+ <item>1f6c5</item>
+ <item>26f5</item>
+ <item>1f6b2</item>
+ <item>1f6b3</item>
+ <item>1f6b4</item>
+ <item>1f6b5</item>
+ <item>1f6b7</item>
+ <item>1f6b8</item>
+ <item>1f689</item>
+ <item>1f680</item>
+ <item>1f6a4</item>
+ <item>1f6b6</item>
+ <item>26fd</item>
+ <item>1f17f</item>
+ <item>1f6a5</item>
+ <item>1f6a6</item>
+ <item>1f6a7</item>
+ <item>1f6a8</item>
+ <item>2668</item>
+ <item>1f48c</item>
+ <item>1f48d</item>
+ <item>1f48e</item>
+ <item>1f490</item>
+ <item>1f492</item>
+ <item>fe4e5|1f1ef,1f1f5</item>
+ <item>fe4e6|1f1fa,1f1f8</item>
+ <item>fe4e7|1f1eb,1f1f7</item>
+ <item>fe4e8|1f1e9,1f1ea</item>
+ <item>fe4e9|1f1ee,1f1f9</item>
+ <item>fe4ea|1f1ec,1f1e7</item>
+ <item>fe4eb|1f1ea,1f1f8</item>
+ <item>fe4ec|1f1f7,1f1fa</item>
+ <item>fe4ed|1f1e8,1f1f3</item>
+ <item>fe4ee|1f1f0,1f1f7</item>
+ </array>
+ <array
+ name="emoji_emoticons"
+ format="string"
+ >
+ <item>=-O</item>
+ <item>:-P</item>
+ <item>;-)</item>
+ <item>:-(</item>
+ <item>:-)</item>
+ <item>:-!</item>
+ <item>:-$</item>
+ <item>B-)</item>
+ <item>:O</item>
+ <item>:-*</item>
+ <item>:-D</item>
+ <item>:\'(</item>
+ <item>:-\\</item>
+ <item>O:-)</item>
+ <item>:-[</item>
+ </array>
+</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index b489f5770..e08d1c6b9 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Phím cách và dấu câu tự động sửa từ nhập sai"</string>
<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_aggressive" msgid="3524029103734923819">"Linh hoạt"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Rất linh hoạt"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Linh hoạt"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Rất linh hoạt"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Đề xuất từ tiếp theo"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Sử dụng từ trước đó khi đưa ra đề xuất"</string>
<string name="gesture_input" msgid="826951152254563827">"Bật nhập bằng cử chỉ"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"Tiếng Anh (Anh) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"Tiếng Anh (Mỹ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"Tiếng Tây Ban Nha (Mỹ) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Không có ngôn ngữ nào"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Không có ngôn ngữ (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"0 ngôn ngữ (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"0 ngôn ngữ (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"0 ngôn ngữ (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"0 ngôn ngữ (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"0 ngôn ngữ (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Truyền thống)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Không ngôn ngữ nào (Bảng chữ cái)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Bảng chữ cái (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Bảng chữ cái (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Bảng chữ cái (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Bảng chữ cái (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Bảng chữ cái (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Bảng chữ cái (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"Biểu tượng cảm xúc"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Kiểu nhập tùy chỉnh"</string>
<string name="add_style" msgid="6163126614514489951">"Thêm kiểu"</string>
<string name="add" msgid="8299699805688017798">"Thêm"</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 1177c01c4..5980cbf13 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -26,7 +26,7 @@
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼写检查工具会使用您的联系人列表中的条目"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按键振动"</string>
<string name="sound_on_keypress" msgid="6093592297198243644">"按键音效"</string>
- <string name="popup_on_keypress" msgid="123894815723512944">"按键时显示所输字符"</string>
+ <string name="popup_on_keypress" msgid="123894815723512944">"按键时弹出显示字符"</string>
<string name="general_category" msgid="1859088467017573195">"常规"</string>
<string name="correction_category" msgid="2236750915056607613">"文本更正"</string>
<string name="gesture_typing_category" msgid="497263612130532630">"滑行输入"</string>
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"按空格键和标点可自动更正错别字"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"关闭"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"小改"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"大改"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"改动极大"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"大幅改动"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"极大幅度改动"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"后续字词建议"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"根据上一个字词提供建议"</string>
<string name="gesture_input" msgid="826951152254563827">"启用滑行输入"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"英语(英国)(<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"英语(美国)(<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"西班牙语(美国)(<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"无语言"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"无语言(QWERTY 键盘)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"无语言(QWERTZ 键盘)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"无语言(AZERTY 键盘)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"无语言(Dvorak 键盘)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"无语言(Colemak 键盘)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"无语言(PC 键盘)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g>(传统)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"无语言(字母)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"字母 (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"字母 (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"字母 (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"字母 (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"表情符号"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"自定义输入风格"</string>
<string name="add_style" msgid="6163126614514489951">"添加样式"</string>
<string name="add" msgid="8299699805688017798">"添加"</string>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 351907aaf..b14a01a0a 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -25,15 +25,15 @@
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查詢聯絡人姓名"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼字檢查程式使用您的聯絡人清單項目"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string>
- <string name="sound_on_keypress" msgid="6093592297198243644">"按鍵時播放音效"</string>
- <string name="popup_on_keypress" msgid="123894815723512944">"按鍵時顯示彈出式視窗"</string>
- <string name="general_category" msgid="1859088467017573195">"一般設定"</string>
+ <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="correction_category" msgid="2236750915056607613">"文字修正"</string>
<string name="gesture_typing_category" msgid="497263612130532630">"手勢輸入"</string>
<string name="misc_category" msgid="6894192814868233453">"其他選項"</string>
<string name="advanced_settings" msgid="362895144495591463">"進階設定"</string>
<string name="advanced_settings_summary" msgid="4487980456152830271">"進階選項"</string>
- <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"切換至其他輸入法"</string>
+ <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"切換到其他輸入法"</string>
<string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"使語言切換鍵包含其他輸入法"</string>
<string name="show_language_switch_key" msgid="5915478828318774384">"語言切換鍵"</string>
<string name="show_language_switch_key_summary" msgid="7343403647474265713">"有多種輸入語言可選用時顯示切換鍵"</string>
@@ -44,7 +44,7 @@
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"預設"</string>
<string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> 毫秒"</string>
<string name="settings_system_default" msgid="6268225104743331821">"系統預設"</string>
- <string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人名稱"</string>
+ <string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人姓名"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"根據「聯絡人」名稱提供建議與修正"</string>
<string name="use_double_space_period" msgid="8781529969425082860">"輕按兩下空格鍵即插入句號"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"輕按兩下空格鍵可插入句號另加一個空格"</string>
@@ -57,15 +57,15 @@
<string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"輸入時顯示建議字詞"</string>
<string name="prefs_suggestion_visibility_show_name" msgid="3219916594067551303">"一律顯示"</string>
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"在垂直模式中顯示"</string>
- <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"永遠隱藏"</string>
+ <string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"一律隱藏"</string>
<string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"封鎖令人反感的字詞"</string>
<string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"不建議可能令人反感的字詞"</string>
<string name="auto_correction" msgid="7630720885194996950">"自動修正"</string>
<string name="auto_correction_summary" msgid="5625751551134658006">"按空白鍵或標點符號時,自動修正前面的錯字"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"關閉"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"更正範圍小"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"更正範圍大"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"更正範圍極大"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"大幅更正"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"極大幅度更正"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"建議下一個字詞"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"根據前一個字詞提供建議"</string>
<string name="gesture_input" msgid="826951152254563827">"啟用手勢輸入"</string>
@@ -74,13 +74,13 @@
<string name="gesture_floating_preview_text" msgid="4443240334739381053">"動態浮動預覽"</string>
<string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"使用手勢輸入時顯示建議字詞"</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>
- <string name="label_previous_key" msgid="1211868118071386787">"上一步"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"前往"</string>
+ <string name="label_next_key" msgid="362972844525672568">"下一頁"</string>
+ <string name="label_previous_key" msgid="1211868118071386787">"上一頁"</string>
<string name="label_done_key" msgid="2441578748772529288">"完成"</string>
<string name="label_send_key" msgid="2815056534433717444">"傳送"</string>
<string name="label_pause_key" msgid="181098308428035340">"暫停"</string>
- <string name="label_wait_key" msgid="6402152600878093134">"等候"</string>
+ <string name="label_wait_key" msgid="6402152600878093134">"等待"</string>
<string name="spoken_use_headphones" msgid="896961781287283493">"連接耳機即可聽取系統朗讀密碼按鍵。"</string>
<string name="spoken_current_text_is" msgid="2485723011272583845">"目前文字為 %s"</string>
<string name="spoken_no_text_entered" msgid="7479685225597344496">"未輸入文字"</string>
@@ -101,8 +101,8 @@
<string name="spoken_description_search" msgid="1247236163755920808">"搜尋"</string>
<string name="spoken_description_dot" msgid="40711082435231673">"點"</string>
<string name="spoken_description_language_switch" msgid="5507091328222331316">"切換語言"</string>
- <string name="spoken_description_action_next" msgid="8636078276664150324">"下一步"</string>
- <string name="spoken_description_action_previous" msgid="800872415009336208">"上一步"</string>
+ <string name="spoken_description_action_next" msgid="8636078276664150324">"下一頁"</string>
+ <string name="spoken_description_action_previous" msgid="800872415009336208">"上一頁"</string>
<string name="spoken_description_shiftmode_on" msgid="5700440798609574589">"Shift 鍵已啟用"</string>
<string name="spoken_description_shiftmode_locked" msgid="593175803181701830">"大寫鎖定已啟用"</string>
<string name="spoken_description_shiftmode_off" msgid="657219998449174808">"Shift 鍵已停用"</string>
@@ -117,7 +117,7 @@
<string name="keyboard_mode_email" msgid="6216248078128294262">"電子郵件"</string>
<string name="keyboard_mode_im" msgid="1137405089766557048">"簡訊"</string>
<string name="keyboard_mode_number" msgid="7991623440699957069">"數字"</string>
- <string name="keyboard_mode_phone" msgid="6851627527401433229">"電話"</string>
+ <string name="keyboard_mode_phone" msgid="6851627527401433229">"電話號碼"</string>
<string name="keyboard_mode_text" msgid="6479436687899701619">"文字"</string>
<string name="keyboard_mode_time" msgid="4381856885582143277">"時間"</string>
<string name="keyboard_mode_url" msgid="1519819835514911218">"網址"</string>
@@ -133,23 +133,25 @@
<string name="send_feedback" msgid="1780431884109392046">"提供意見"</string>
<string name="select_language" msgid="3693815588777926848">"輸入語言"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"再次輕觸即可儲存"</string>
- <string name="has_dictionary" msgid="6071847973466625007">"可使用字典"</string>
+ <string name="has_dictionary" msgid="6071847973466625007">"可用的字典"</string>
<string name="prefs_enable_log" msgid="6620424505072963557">"啟用使用者意見回饋"</string>
<string name="prefs_description_log" msgid="7525225584555429211">"自動傳送使用統計資料和當機報告,協助改善此輸入法編輯器"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string>
- <string name="subtype_en_GB" msgid="88170601942311355">"英文 (英式)"</string>
- <string name="subtype_en_US" msgid="6160452336634534239">"英文 (美式)"</string>
+ <string name="subtype_en_GB" msgid="88170601942311355">"英文 (英國)"</string>
+ <string name="subtype_en_US" msgid="6160452336634534239">"英文 (美國)"</string>
<string name="subtype_es_US" msgid="5583145191430180200">"西班牙文 (美國)"</string>
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"英文 (英國) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"英文 (美國) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"西班牙文 (美國) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"無語言"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"無語言 (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"無語言 (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"無語言 (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"無語言 (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"無語言 (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"無語言 (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (傳統)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"無語言 (字母)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"字母 (AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"字母 (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"字母 (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"字母 (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"表情符號"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"自訂輸入樣式"</string>
<string name="add_style" msgid="6163126614514489951">"新增樣式"</string>
<string name="add" msgid="8299699805688017798">"新增"</string>
@@ -171,7 +173,7 @@
<string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"準備為<xliff:g id="LOCALE_NAME">%s</xliff:g>版本安裝這個檔案嗎?"</string>
<string name="error" msgid="8940763624668513648">"發生錯誤"</string>
<string name="button_default" msgid="3988017840431881491">"預設"</string>
- <string name="setup_welcome_title" msgid="6112821709832031715">"歡迎使用「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」"</string>
+ <string name="setup_welcome_title" msgid="6112821709832031715">"歡迎使用 <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"含手勢輸入功能"</string>
<string name="setup_start_action" msgid="8936036460897347708">"開始設定"</string>
<string name="setup_next_action" msgid="371821437915144603">"下一步"</string>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 9c44c6f1c..9ed88a00f 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -64,8 +64,8 @@
<string name="auto_correction_summary" msgid="5625751551134658006">"Ibha yesikhala nokubhala ngamagama amakhulu kulungisa amaphutha amagama athayiphwe kabi"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Valiwe"</string>
<string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Thobekile"</string>
- <string name="auto_correction_threshold_mode_aggressive" msgid="3524029103734923819">"Bukhali"</string>
- <string name="auto_correction_threshold_mode_very_aggressive" msgid="3386782235540547678">"Nobudlova kakhulu"</string>
+ <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Bukhali"</string>
+ <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Bukhali kakhulu"</string>
<string name="bigram_prediction" msgid="1084449187723948550">"Iziphakamiso zegama elilandelayo"</string>
<string name="bigram_prediction_summary" msgid="3896362682751109677">"Sebenzisa igama langaphambilini ekwenzeni iziphakamiso"</string>
<string name="gesture_input" msgid="826951152254563827">"Nika amandla okuthayipha ngokuthinta"</string>
@@ -143,13 +143,15 @@
<string name="subtype_with_layout_en_GB" msgid="2179097748724725906">"I-English (UK) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_en_US" msgid="1362581347576714579">"I-English (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_es_US" msgid="6261791057007890189">"I-Spanish (US) (<xliff:g id="LAYOUT">%s</xliff:g>)"</string>
- <string name="subtype_no_language" msgid="141420857808801746">"Akunalimi"</string>
- <string name="subtype_no_language_qwerty" msgid="2956121451616633133">"Akunalimi (QWERTY)"</string>
- <string name="subtype_no_language_qwertz" msgid="1177848172397202890">"Alukho ulimi (QWERTZ)"</string>
- <string name="subtype_no_language_azerty" msgid="8721460968141187394">"Alukho ulimi (AZERTY)"</string>
- <string name="subtype_no_language_dvorak" msgid="3122976737669823935">"Alukho ulimi (Dvorak)"</string>
- <string name="subtype_no_language_colemak" msgid="4205992994906097244">"Alukho ulimi (Colemak)"</string>
- <string name="subtype_no_language_pcqwerty" msgid="8840928374394180189">"Alukho ulimi (PC)"</string>
+ <string name="subtype_nepali_traditional" msgid="9032247506728040447">"<xliff:g id="LANGUAGE">%s</xliff:g> (Ezosiko)"</string>
+ <string name="subtype_no_language" msgid="7137390094240139495">"Alikho ulimi (Alfabhethi)"</string>
+ <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabhethi (QWERTY)"</string>
+ <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabhethi (QWERTZ)"</string>
+ <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alfabhethi (I-AZERTY)"</string>
+ <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alfabhethi (Dvorak)"</string>
+ <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alfabhethi (Colemak)"</string>
+ <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alfabhethi (PC)"</string>
+ <string name="subtype_emoji" msgid="7483586578074549196">"I-Emoji"</string>
<string name="custom_input_styles_title" msgid="8429952441821251512">"Izitayela zokufaka ngokwezifiso"</string>
<string name="add_style" msgid="6163126614514489951">"Engeza isitayela"</string>
<string name="add" msgid="8299699805688017798">"Engeza"</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index eef9116da..09782143f 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -1,17 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+<!--
+/*
+**
+** 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.
+*/
-->
<resources>
@@ -22,15 +26,18 @@
<attr name="keyboardViewStyle" format="reference" />
<!-- MainKeyboardView style -->
<attr name="mainKeyboardViewStyle" format="reference" />
+ <!-- EmojiKeyboardView style -->
+ <attr name="emojiKeyboardViewStyle" format="reference" />
<!-- MoreKeysKeyboard style -->
<attr name="moreKeysKeyboardStyle" format="reference" />
<!-- MoreKeysKeyboardView style -->
<attr name="moreKeysKeyboardViewStyle" format="reference" />
- <attr name="moreKeysKeyboardPanelStyle" format="reference" />
+ <!-- MoreKeysKeyboardView container style -->
+ <attr name="moreKeysKeyboardContainerStyle" format="reference" />
<!-- Suggestions strip style -->
<attr name="suggestionStripViewStyle" format="reference" />
- <attr name="moreSuggestionsViewStyle" format="reference" />
- <attr name="suggestionBackgroundStyle" format="reference" />
+ <!-- Suggestion word style -->
+ <attr name="suggestionWordStyle" format="reference" />
</declare-styleable>
<declare-styleable name="KeyboardView">
@@ -38,6 +45,8 @@
possible states: normal, pressed, checkable, checkable+pressed, checkable+checked,
checkable+checked+pressed. -->
<attr name="keyBackground" format="reference" />
+ <!-- Image for the functional key used in Emoji layout. -->
+ <attr name="keyBackgroundEmojiFunctional" format="reference" />
<!-- Horizontal padding of left/right aligned key label to the edge of the key. -->
<attr name="keyLabelHorizontalPadding" format="dimension" />
@@ -158,6 +167,10 @@
<attr name="suppressKeyPreviewAfterBatchInputDuration" format="integer" />
</declare-styleable>
+ <declare-styleable name="EmojiKeyboardView">
+ <attr name="emojiTabLabelColor" format="reference" />
+ </declare-styleable>
+
<declare-styleable name="SuggestionStripView">
<attr name="suggestionStripOption" format="integer">
<!-- This should be aligned with SuggestionStripLayoutHelper.AUTO_CORRECT_* and etc. -->
@@ -169,10 +182,6 @@
<attr name="colorTypedWord" format="color" />
<attr name="colorAutoCorrect" format="color" />
<attr name="colorSuggested" format="color" />
- <attr name="alphaValidTypedWord" format="fraction" />
- <attr name="alphaTypedWord" format="fraction" />
- <attr name="alphaAutoCorrect" format="fraction" />
- <attr name="alphaSuggested" format="fraction" />
<attr name="alphaObsoleted" format="fraction" />
<attr name="suggestionsCountInStrip" format="integer" />
<attr name="centerSuggestionPercentile" format="fraction" />
@@ -216,9 +225,15 @@
<attr name="iconLanguageSwitchKey" format="reference" />
<attr name="iconZwnjKey" format="reference" />
<attr name="iconZwjKey" format="reference" />
+ <attr name="iconImeKey" format="reference" />
<attr name="iconEmojiKey" format="reference" />
</declare-styleable>
+ <declare-styleable name="Keyboard_GridRows">
+ <attr name="codesArray" format="reference" />
+ <attr name="textsArray" format="reference" />
+ </declare-styleable>
+
<declare-styleable name="Keyboard_Key">
<!-- The unicode value that this key outputs.
Code value represented in hexadecimal prefixed with "0x" or code value reference using
@@ -240,11 +255,12 @@
<attr name="maxMoreKeysColumn" format="integer" />
<attr name="backgroundType" format="enum">
<!-- This should be aligned with Key.BACKGROUND_TYPE_* -->
- <enum name="normal" value="0" />
- <enum name="functional" value="1" />
- <enum name="action" value="2" />
- <enum name="stickyOff" value="3" />
- <enum name="stickyOn" value="4" />
+ <enum name="empty" value="0" />
+ <enum name="normal" value="1" />
+ <enum name="functional" value="2" />
+ <enum name="action" value="3" />
+ <enum name="stickyOff" value="4" />
+ <enum name="stickyOn" value="5" />
</attr>
<!-- The key action flags. -->
<attr name="keyActionFlags" format="integer">
@@ -365,6 +381,7 @@
</declare-styleable>
<declare-styleable name="Keyboard_Case">
+ <attr name="keyboardLayoutSet" format="string" />
<!-- This should be aligned with KeyboardLayoutSet_Element's elementName. -->
<attr name="keyboardLayoutSetElement" format="enum|string">
<enum name="alphabet" value="0" />
@@ -377,6 +394,13 @@
<enum name="phone" value="7" />
<enum name="phoneSymbols" value="8" />
<enum name="number" value="9" />
+ <enum name="emojiRecents" value="10" />
+ <enum name="emojiCategory1" value="11" />
+ <enum name="emojiCategory2" value="12" />
+ <enum name="emojiCategory3" value="13" />
+ <enum name="emojiCategory4" value="14" />
+ <enum name="emojiCategory5" value="15" />
+ <enum name="emojiCategory6" value="16" />
</attr>
<!-- This should be aligned with KeyboardId.MODE_* -->
<attr name="mode" format="enum|string">
@@ -432,6 +456,13 @@
<enum name="phone" value="7" />
<enum name="phoneSymbols" value="8" />
<enum name="number" value="9" />
+ <enum name="emojiRecents" value="10" />
+ <enum name="emojiCategory1" value="11" />
+ <enum name="emojiCategory2" value="12" />
+ <enum name="emojiCategory3" value="13" />
+ <enum name="emojiCategory4" value="14" />
+ <enum name="emojiCategory5" value="15" />
+ <enum name="emojiCategory6" value="16" />
</attr>
<attr name="elementKeyboard" format="reference"/>
<!-- Enable proximity characters correction. Disabled by default. -->
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index daa167c8a..3803cb776 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -1,47 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Color resources for default, and Gingerbread theme. -->
- <color name="highlight_color_default">#FFFCAE00</color>
- <color name="highlight_translucent_color_default">#99FCAE00</color>
- <color name="key_text_color_default">@android:color/white</color>
- <color name="key_text_shadow_color_default">#BB000000</color>
- <color name="key_text_inactivated_color_default">@android:color/white</color>
- <color name="key_hint_letter_color_default">#80000000</color>
- <color name="key_hint_label_color_default">#E0E0E4E5</color>
- <color name="key_shifted_letter_hint_inactivated_color_default">#66E0E4E5</color>
- <color name="key_shifted_letter_hint_activated_color_default">#CCE0E4E5</color>
- <color name="spacebar_text_color_default">#FFC0C0C0</color>
- <color name="spacebar_text_shadow_color_default">#80000000</color>
- <color name="typed_word_color_default">@android:color/white</color>
- <color name="gesture_floating_preview_color_default">#C0000000</color>
- <!-- Color resources for Stone theme. -->
- <color name="key_text_color_stone">@android:color/black</color>
- <color name="key_text_shadow_color_stone">@android:color/white</color>
- <color name="key_text_inactivated_color_stone">#FF808080</color>
- <color name="key_hint_letter_color_stone">#80000000</color>
- <color name="key_hint_label_color_stone">#E0000000</color>
- <color name="key_shifted_letter_hint_inactivated_color_stone">#66000000</color>
- <color name="key_shifted_letter_hint_activated_color_stone">#CC000000</color>
- <color name="spacebar_text_color_stone">@android:color/black</color>
- <color name="spacebar_text_shadow_color_stone">#D0FFFFFF</color>
- <!-- Color resources for IceCreamSandwich theme. -->
+ <!-- Color resources for Gingerbread theme. -->
+ <color name="highlight_color_gb">#FFFCAE00</color>
+ <color name="typed_word_color_gb">@android:color/white</color>
+ <color name="highlight_translucent_color_gb">#99FCAE00</color>
+ <color name="key_text_color_gb">@android:color/white</color>
+ <color name="key_text_shadow_color_gb">#BB000000</color>
+ <color name="key_text_inactivated_color_gb">#66E0E4E5</color>
+ <color name="key_hint_letter_color_gb">#80000000</color>
+ <color name="key_hint_label_color_gb">#E0E0E4E5</color>
+ <color name="key_shifted_letter_hint_inactivated_color_gb">#66E0E4E5</color>
+ <color name="key_shifted_letter_hint_activated_color_gb">#CCE0E4E5</color>
+ <color name="spacebar_text_color_gb">#FFC0C0C0</color>
+ <color name="spacebar_text_shadow_color_gb">#80000000</color>
+ <color name="gesture_floating_preview_color_gb">#C0000000</color>
+ <!-- Color resources for IceCreamSandwich theme. Base color = 33B5E5 -->
<!-- android:color/holo_blue_light value is #FF33B5E5 -->
- <color name="highlight_color_ics">@android:color/holo_blue_light</color>
+ <color name="highlight_color_ics">#FF33B5E5</color>
+ <color name="typed_word_color_ics">#D833B5E5</color>
+ <color name="suggested_word_color_ics">#B233B5E5</color>
<color name="highlight_translucent_color_ics">#9933B5E5</color>
<color name="key_text_color_ics">@android:color/white</color>
<color name="key_text_shadow_color_ics">@android:color/transparent</color>
@@ -52,11 +48,22 @@
<color name="key_shifted_letter_hint_activated_color_ics">@android:color/white</color>
<color name="spacebar_text_color_ics">#FFC0C0C0</color>
<color name="spacebar_text_shadow_color_ics">#80000000</color>
- <color name="typed_word_color_ics">@color/highlight_color_ics</color>
+ <color name="gesture_floating_preview_color_ics">#C0000000</color>
+ <!-- Color resources for KLP theme. Base color = F0F0F0 -->
+ <color name="highlight_color_holo">#FFF0F0F0</color>
+ <color name="typed_word_color_holo">#D8F0F0F0</color>
+ <color name="suggested_word_color_holo">#B2F0F0F0</color>
+ <color name="highlight_translucent_color_holo">#99E0E0E0</color>
<!-- Color resources for setup wizard and tutorial -->
<color name="setup_background">#FFEBEBEB</color>
<color name="setup_text_dark">#FF707070</color>
<color name="setup_text_action">@android:color/holo_blue_light</color>
<color name="setup_step_background">@android:color/background_light</color>
<color name="setup_welcome_video_margin_color">#FFCCCCCC</color>
+ <color name="emoji_category_page_id_view_background">#FF000000</color>
+ <color name="emoji_category_page_id_view_foreground">#80FFFFFF</color>
+
+ <!-- TODO: Color which should be included in the theme -->
+ <color name="emoji_key_background_color">#00000000</color>
+ <color name="emoji_key_pressed_background_color">#30FFFFFF</color>
</resources>
diff --git a/java/res/values/config-additional-features.xml b/java/res/values/config-additional-features.xml
new file mode 100644
index 000000000..47eb7724c
--- /dev/null
+++ b/java/res/values/config-additional-features.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+ <!-- Whether phrase gestures are enabled by default -->
+ <bool name="config_default_phrase_gesture_enabled">false</bool>
+</resources>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index d3a21f2aa..465d52cec 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -42,7 +42,7 @@
<integer name="config_keyboard_grid_height">16</integer>
<integer name="config_double_space_period_timeout">1100</integer>
<!-- This configuration is the index of the array {@link KeyboardSwitcher.KEYBOARD_THEMES}. -->
- <string name="config_default_keyboard_theme_index" translatable="false">5</string>
+ <string name="config_default_keyboard_theme_index" translatable="false">0</string>
<integer name="config_max_more_keys_column">5</integer>
<!--
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 98ae76cb1..4e3b2f567 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -29,18 +29,11 @@
<dimen name="more_keys_keyboard_key_horizontal_padding">8dp</dimen>
- <fraction name="keyboard_top_padding">1.556%p</fraction>
- <fraction name="keyboard_bottom_padding">4.669%p</fraction>
<fraction name="keyboard_left_padding">0%p</fraction>
<fraction name="keyboard_right_padding">0%p</fraction>
- <fraction name="key_bottom_gap">6.250%p</fraction>
- <fraction name="key_horizontal_gap">1.352%p</fraction>
-
- <fraction name="keyboard_top_padding_stone">1.556%p</fraction>
- <fraction name="keyboard_bottom_padding_stone">0.778%p</fraction>
- <fraction name="key_bottom_gap_stone">7.506%p</fraction>
- <fraction name="key_horizontal_gap_stone">1.739%p</fraction>
+ <fraction name="keyboard_top_padding_gb">1.556%p</fraction>
+ <fraction name="keyboard_bottom_padding_gb">4.669%p</fraction>
<fraction name="key_bottom_gap_gb">6.495%p</fraction>
<fraction name="key_horizontal_gap_gb">1.971%p</fraction>
@@ -48,13 +41,12 @@
<fraction name="keyboard_bottom_padding_ics">4.669%p</fraction>
<fraction name="key_bottom_gap_ics">6.127%p</fraction>
<fraction name="key_horizontal_gap_ics">1.739%p</fraction>
- <dimen name="more_keys_keyboard_horizontal_edges_padding_ics">4dp</dimen>
<!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. -->
<!-- popup_key_height x 1.2 -->
<dimen name="more_keys_keyboard_slide_allowance">63.36dp</dimen>
<!-- popup_key_height x -1.0 -->
- <dimen name="more_keys_keyboard_vertical_correction">-52.8dp</dimen>
+ <dimen name="more_keys_keyboard_vertical_correction_gb">-52.8dp</dimen>
<dimen name="keyboard_vertical_correction">0.0dp</dimen>
<fraction name="key_letter_ratio">55%</fraction>
@@ -67,7 +59,7 @@
<fraction name="key_preview_text_ratio">82%</fraction>
<fraction name="spacebar_text_ratio">33.735%</fraction>
<dimen name="key_preview_height">80dp</dimen>
- <dimen name="key_preview_offset">-8.0dp</dimen>
+ <dimen name="key_preview_offset_gb">-8.0dp</dimen>
<dimen name="key_label_horizontal_padding">4dp</dimen>
<dimen name="key_hint_letter_padding">1dp</dimen>
@@ -121,10 +113,20 @@
<dimen name="gesture_floating_preview_text_offset">73dp</dimen>
<dimen name="gesture_floating_preview_horizontal_padding">24dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">16dp</dimen>
- <dimen name="gesture_floating_preview_round_radius">3dp</dimen>
+ <dimen name="gesture_floating_preview_round_radius">2dp</dimen>
+
+ <!-- Emoji keyboard -->
+ <fraction name="emoji_keyboard_key_width">14.2857%p</fraction>
+ <fraction name="emoji_keyboard_row_height">33%p</fraction>
+ <fraction name="emoji_keyboard_key_letter_size">90%p</fraction>
+ <integer name="emoji_keyboard_max_key_count">21</integer>
+ <dimen name="emoji_category_page_id_height">3dp</dimen>
<!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. -->
<dimen name="accessibility_edge_slop">8dp</dimen>
<integer name="user_dictionary_max_word_length" translatable="false">48</integer>
+
+ <dimen name="language_on_spacebar_horizontal_margin">1dp</dimen>
+
</resources>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index e352f082b..42e692d2f 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -18,6 +18,8 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- TODO: these settings depend on the language. They should be put either in the dictionary
+ header, or in the subtype maybe? -->
<!-- Symbols that are suggested between words -->
<string name="suggested_punctuations">!,?,\\,,:,;,\",(,),\',-,/,@,_</string>
<!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
@@ -29,6 +31,8 @@
<string name="symbols_word_separators">"&#x0009;&#x0020;\n"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
<!-- Word connectors -->
<string name="symbols_word_connectors">\'-</string>
+ <!-- Whether this language uses spaces between words -->
+ <bool name="current_language_has_spaces">true</bool>
<!-- Always show the suggestion strip -->
<string name="prefs_suggestion_visibility_show_value">0</string>
@@ -94,29 +98,17 @@
<string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
<!-- Keyboard theme names -->
- <string name="layout_basic">Basic</string>
- <string name="layout_high_contrast">Basic (High Contrast)</string>
- <string name="layout_stone_bold">Stone (bold)</string>
- <string name="layout_stone_normal">Stone (normal)</string>
<string name="layout_gingerbread">Gingerbread</string>
<string name="layout_ics">IceCreamSandwich</string>
<!-- For keyboard theme switcher dialog -->
<string-array name="keyboard_layout_modes">
- <item>@string/layout_basic</item>
- <item>@string/layout_high_contrast</item>
- <item>@string/layout_stone_normal</item>
- <item>@string/layout_stone_bold</item>
- <item>@string/layout_gingerbread</item>
<item>@string/layout_ics</item>
+ <item>@string/layout_gingerbread</item>
</string-array>
<string-array name="keyboard_layout_modes_values">
<item>0</item>
<item>1</item>
- <item>2</item>
- <item>3</item>
- <item>4</item>
- <item>5</item>
</string-array>
<!-- Subtype locale display name exceptions.
@@ -166,47 +158,47 @@
<!-- Compatibility map from subtypeLocale:subtypeExtraValue to keyboardLayoutSet -->
<string-array name="locale_and_extra_value_to_keyboard_layout_set_map">
- <item>en_US:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>en_US:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>en_GB:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>en_GB:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>ar:SupportTouchPositionCorrection</item>
+ <item>ar:SupportTouchPositionCorrection,EmojiCapable</item>
<item>arabic</item>
- <item>cs:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>cs:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>da:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>da:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>de:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>de:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>es:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>es:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>spanish</item>
- <item>fi:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>fi:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>fr:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>fr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>azerty</item>
- <item>fr_CA:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>fr_CA:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>hr:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>hr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>hu:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>hu:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>it:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>it:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>iw:SupportTouchPositionCorrection</item>
+ <item>iw:SupportTouchPositionCorrection,EmojiCapable</item>
<item>hebrew</item>
- <item>nb:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>nb:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>nl:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>nl:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>pl:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>pl:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>ru:SupportTouchPositionCorrection</item>
+ <item>ru:SupportTouchPositionCorrection,EmojiCapable</item>
<item>east_slavic</item>
- <item>sr:SupportTouchPositionCorrection</item>
+ <item>sr:SupportTouchPositionCorrection,EmojiCapable</item>
<item>south_slavic</item>
- <item>sv:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>sv:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>tr:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>tr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
</string-array>
diff --git a/java/res/values/emoji-categories.xml b/java/res/values/emoji-categories.xml
new file mode 100644
index 000000000..ce82a8b40
--- /dev/null
+++ b/java/res/values/emoji-categories.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- Note: This emoji code point list is valid prior to JB-MR2 (API < 18).
+ There is another emoji code point list for JB-MR2 and KLP and later under
+ res/xml/values-v1[89].-->
+<resources>
+ <!-- Dummy codeArrays for recents emoji keyboard.
+ Do not remove these keys, because they are used as a template. -->
+ <array
+ name="emoji_recents"
+ format="string"
+ >
+ <!-- These code point should be aligned with {@link RecentsKeyboard#TEMPLATE_KEY_CODE_*. -->
+ <item>30</item>
+ <item>31</item>
+ </array>
+ <array
+ name="emoji_nature"
+ format="string"
+ >
+ <item>2744</item> <!-- SNOWFLAKE -->
+ </array>
+ <array
+ name="emoji_symbols"
+ format="string"
+ >
+ <item>2460</item> <!-- CIRCLED DIGIT ONE -->
+ <item>2461</item> <!-- CIRCLED DIGIT TWO -->
+ <item>2462</item> <!-- CIRCLED DIGIT THREE -->
+ <item>2463</item> <!-- CIRCLED DIGIT FOUR -->
+ <item>2464</item> <!-- CIRCLED DIGIT FIVE -->
+ <item>2465</item> <!-- CIRCLED DIGIT SIX -->
+ <item>2466</item> <!-- CIRCLED DIGIT SEVEN -->
+ <item>2467</item> <!-- CIRCLED DIGIT EIGHT -->
+ <item>2468</item> <!-- CIRCLED DIGIT NINE -->
+ <item>2469</item> <!-- CIRCLED DIGIT TEN -->
+ <item>00ae</item> <!-- REGISTERED SIGN -->
+ <item>00a9</item> <!-- COPYRIGHT SIGN -->
+ <item>2122</item> <!-- TRADE MARK SIGN -->
+ <item>2734</item> <!-- EIGHT POINTED BLACK STAR -->
+ <item>2733</item> <!-- EIGHT POINTED PINWHEEL STAR -->
+ <item>2716</item> <!-- HEAVY MULTIPLICATION MARK -->
+ <item>2195</item> <!-- UP DOWN ARROW -->
+ <item>2197</item> <!-- NORTH EAST ARROW -->
+ <item>27a1</item> <!-- BLACK RIGHTWARDS ARROW -->
+ <item>2198</item> <!-- SOUTH EAST ARROW -->
+ <item>2199</item> <!-- SOUTH WEST ARROW -->
+ <item>2196</item> <!-- NORTH EAST ARROW -->
+ <item>2194</item> <!-- LEFT RIGHT ARROW -->
+ <item>25c0</item> <!-- BLACK LEFT-POINTING TRIANGLE -->
+ <item>25b6</item> <!-- BLACK ROGHT-POINTING TRIANGLE -->
+ <item>2747</item> <!-- SPARKLE -->
+ <item>25aa</item> <!-- BLACK SMALL SQUARE -->
+ <item>203c</item> <!-- DOUBLE EXCLAMATION MARK -->
+ <item>2660</item> <!-- BLACK SPADE SUIT -->
+ <item>2665</item> <!-- BLACK HEART SUIT -->
+ <item>2663</item> <!-- BLACK CLUB SUIT -->
+ <item>2666</item> <!-- BLACK DIAMOND SUIT -->
+ <item>21a9</item> <!-- LEFTWARDS ARROW WITH HOOK -->
+ <item>21aa</item> <!-- RIGHTWARDS ARROW WITH HOOK -->
+ </array>
+ <array
+ name="emoji_faces"
+ format="string"
+ >
+ <item>270C</item> <!-- VICTORY HAND -->
+ <item>2764</item> <!-- HEAVY BLACK HEART -->
+ </array>
+ <array
+ name="emoji_objects"
+ format="string"
+ >
+ <item>260e</item> <!-- BLACK TELEPHONE -->
+ <item>2709</item> <!-- ENVELOPE -->
+ <item>2712</item> <!-- BLACK NIB -->
+ <item>270f</item> <!-- PENCIL -->
+ <item>2702</item> <!-- BLACK SCISSORS -->
+ <item>2669</item> <!-- QUARTER NOTE -->
+ <item>266a</item> <!-- EIGHTH NOTE -->
+ <item>266c</item> <!-- BEAMED SIXTEENTH NOTES -->
+ </array>
+ <array
+ name="emoji_places"
+ format="string"
+ >
+ <item>2708</item> <!-- AIRPLANE -->
+ <item>2668</item> <!-- HOT SPRINGS -->
+ </array>
+ <array
+ name="emoji_emoticons"
+ format="string"
+ >
+ <item>=-O</item>
+ <item>:-P</item>
+ <item>;-)</item>
+ <item>:-(</item>
+ <item>:-)</item>
+ <item>:-!</item>
+ <item>:-$</item>
+ <item>B-)</item>
+ <item>:O</item>
+ <item>:-*</item>
+ <item>:-D</item>
+ <item>:\'(</item>
+ <item>:-\\</item>
+ <item>O:-)</item>
+ <item>:-[</item>
+ </array>
+</resources>
diff --git a/java/res/values/keyboard-icons-black.xml b/java/res/values/keyboard-icons-black.xml
deleted file mode 100644
index c1b1b6573..000000000
--- a/java/res/values/keyboard-icons-black.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardIcons.Black">
- <!-- Keyboard icons -->
- <!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are too
- ambiguous.
- sym_bkeyboard_voice_off
- -->
- <item name="iconShiftKey">@drawable/sym_bkeyboard_shift</item>
- <item name="iconDeleteKey">@drawable/sym_bkeyboard_delete</item>
- <item name="iconSettingsKey">@drawable/sym_bkeyboard_settings</item>
- <item name="iconSpaceKey">@drawable/sym_bkeyboard_space</item>
- <item name="iconEnterKey">@drawable/sym_bkeyboard_return</item>
- <item name="iconSearchKey">@drawable/sym_bkeyboard_search</item>
- <item name="iconTabKey">@drawable/sym_bkeyboard_tab</item>
- <item name="iconShortcutKey">@drawable/sym_bkeyboard_mic</item>
- <item name="iconShortcutForLabel">@drawable/sym_bkeyboard_label_mic</item>
- <item name="iconSpaceKeyForNumberLayout">@drawable/sym_bkeyboard_space</item>
- <item name="iconShiftKeyShifted">@drawable/sym_bkeyboard_shift_locked</item>
- <item name="iconShortcutKeyDisabled">@drawable/sym_bkeyboard_voice_off</item>
- <item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
- <!-- TODO: Needs dedicated black theme globe icon -->
- <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
- <!-- TODO: Needs dedicated black theme ZWNJ and ZWJ icons -->
- <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item>
- <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item>
- <item name="iconEmojiKey">@drawable/ic_emoji_light</item>
- </style>
-</resources>
diff --git a/java/res/values/keyboard-icons-ics.xml b/java/res/values/keyboard-icons-ics.xml
deleted file mode 100644
index 5ada27ae8..000000000
--- a/java/res/values/keyboard-icons-ics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardIcons.IceCreamSandwich">
- <!-- Keyboard icons -->
- <!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are missing.
- sym_keyboard_123_mic_holo
- -->
- <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo</item>
- <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo</item>
- <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo</item>
- <item name="iconSpaceKey">@null</item>
- <item name="iconEnterKey">@drawable/sym_keyboard_return_holo</item>
- <item name="iconSearchKey">@drawable/sym_keyboard_search_holo</item>
- <item name="iconTabKey">@drawable/sym_keyboard_tab_holo</item>
- <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo</item>
- <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo</item>
- <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space_holo</item>
- <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo</item>
- <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo</item>
- <item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
- <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
- <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item>
- <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item>
- <item name="iconEmojiKey">@drawable/ic_emoji_light</item>
- </style>
-</resources>
diff --git a/java/res/values/keyboard-icons-white.xml b/java/res/values/keyboard-icons-white.xml
deleted file mode 100644
index 7c6de42fa..000000000
--- a/java/res/values/keyboard-icons-white.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardIcons">
- <!-- Keyboard icons -->
- <item name="iconShiftKey">@drawable/sym_keyboard_shift</item>
- <item name="iconDeleteKey">@drawable/sym_keyboard_delete</item>
- <item name="iconSettingsKey">@drawable/sym_keyboard_settings</item>
- <item name="iconSpaceKey">@drawable/sym_keyboard_space</item>
- <item name="iconEnterKey">@drawable/sym_keyboard_return</item>ZZ
- <item name="iconSearchKey">@drawable/sym_keyboard_search</item>
- <item name="iconTabKey">@drawable/sym_keyboard_tab</item>
- <item name="iconShortcutKey">@drawable/sym_keyboard_mic</item>
- <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic</item>
- <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space</item>
- <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked</item>
- <!-- TODO: Needs non-holo disabled shortcut icon drawable -->
- <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo</item>
- <item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
- <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
- <!-- TODO: Needs dedicated black theme ZWNJ and ZWJ icons -->
- <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item>
- <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item>
- <item name="iconEmojiKey">@drawable/ic_emoji_dark</item>
- </style>
-</resources>
diff --git a/java/res/values/keypress-vibration-durations.xml b/java/res/values/keypress-vibration-durations.xml
index 53448c3e1..ee0ac003c 100644
--- a/java/res/values/keypress-vibration-durations.xml
+++ b/java/res/values/keypress-vibration-durations.xml
@@ -55,8 +55,8 @@
<item>MODEL=HTL22:MANUFACTURER=HTC,15</item>
<!-- Motorola Razor M -->
<item>MODEL=XT907:MANUFACTURER=motorola,30</item>
- <!-- Sony Xperia Z -->
- <item>MODEL=C6603:MANUFACTURER=Sony,35</item>
+ <!-- Sony Xperia Z, Z Ultra -->
+ <item>MODEL=C6603|C6806:MANUFACTURER=Sony,35</item>
<!-- Default value for unknown device. The negative value means system default. -->
<item>,-1</item>
</string-array>
diff --git a/java/res/values/setup-styles.xml b/java/res/values/setup-styles.xml
index 1ffe8ca46..c968b2fc6 100644
--- a/java/res/values/setup-styles.xml
+++ b/java/res/values/setup-styles.xml
@@ -1,17 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index aae5b0b70..69da1e862 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -371,6 +371,8 @@
<!-- Description for Spanish (United States) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
This should be identical to subtype_es_US aside from the trailing (%s). -->
<string name="subtype_with_layout_es_US">Spanish (US) (<xliff:g id="layout">%s</xliff:g>)</string>
+ <!-- Description for Nepali (Traditional) keyboard subtype [CHAR LIMIT=25] -->
+ <string name="subtype_nepali_traditional"><xliff:g id="language">%s</xliff:g> (Traditional)</string>
<!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
Description for Serbian Cyrillic keyboard subtype [CHAR LIMIT=25]
<string name="subtype_serbian_cyrillic">Serbian (Cyrillic)</string>
@@ -457,6 +459,8 @@ language among those that use the Latin alphabet. This keyboard is laid out in t
disposition that offers additional keys, but smaller keys compared to other common dispositions for
mobile devices. [CHAR LIMIT=25] -->
<string name="subtype_no_language_pcqwerty">Alphabet (PC)</string>
+ <!-- Description for Emoji keyboard subtype [CHAR LIMIT=25] -->
+ <string name="subtype_emoji">Emoji</string>
<!-- Title of the preference settings for custom input styles (language and keyboard layout pairs) [CHAR LIMIT=35]-->
<string name="custom_input_styles_title">Custom input styles</string>
@@ -493,6 +497,8 @@ mobile devices. [CHAR LIMIT=25] -->
<string name="prefs_read_external_dictionary">Read external dictionary file</string>
<!-- Title of the settings for using only personalization dictionary -->
<string name="prefs_use_only_personalization_dictionary" translatable="false">Use only personalization dictionary</string>
+ <!-- Title of the settings for boosting personalization dictionary -->
+ <string name="prefs_boost_personalization_dictionary" translatable="false">Boost personalization dictionary</string>
<!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
<string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
<!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
deleted file mode 100644
index 37c6a9553..000000000
--- a/java/res/values/styles.xml
+++ /dev/null
@@ -1,415 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Theme "Basic" -->
- <style name="Keyboard">
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">0</item>
- <item name="touchPositionCorrectionData">@array/touch_position_correction_data_default</item>
- <item name="rowHeight">25%p</item>
- <item name="moreKeysTemplate">@xml/kbd_more_keys_keyboard_template</item>
- <item name="keyboardTopPadding">@fraction/keyboard_top_padding</item>
- <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding</item>
- <item name="keyboardLeftPadding">@fraction/keyboard_left_padding</item>
- <item name="keyboardRightPadding">@fraction/keyboard_right_padding</item>
- <item name="horizontalGap">@fraction/key_horizontal_gap</item>
- <item name="verticalGap">@fraction/key_bottom_gap</item>
- <item name="maxMoreKeysColumn">@integer/config_max_more_keys_column</item>
- </style>
- <style name="KeyboardView">
- <item name="android:background">@drawable/keyboard_background</item>
- <item name="keyBackground">@drawable/btn_keyboard_key</item>
- <item name="keyLetterSize">@fraction/key_letter_ratio</item>
- <item name="keyLargeLetterRatio">@fraction/key_large_letter_ratio</item>
- <item name="keyLabelSize">@fraction/key_label_ratio</item>
- <item name="keyLargeLabelRatio">@fraction/key_large_label_ratio</item>
- <item name="keyHintLetterRatio">@fraction/key_hint_letter_ratio</item>
- <item name="keyHintLabelRatio">@fraction/key_hint_label_ratio</item>
- <item name="keyShiftedLetterHintRatio">@fraction/key_uppercase_letter_ratio</item>
- <item name="keyTypeface">normal</item>
- <item name="keyTextColor">@color/key_text_color_default</item>
- <item name="keyTextInactivatedColor">@color/key_text_color_default</item>
- <item name="keyHintLetterColor">@color/key_hint_letter_color_default</item>
- <item name="keyHintLabelColor">@color/key_hint_label_color_default</item>
- <item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_default</item>
- <item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_default</item>
- <item name="keyLabelHorizontalPadding">@dimen/key_label_horizontal_padding</item>
- <item name="keyHintLetterPadding">@dimen/key_hint_letter_padding</item>
- <item name="keyPopupHintLetterPadding">@dimen/key_popup_hint_letter_padding</item>
- <item name="keyShiftedLetterHintPadding">@dimen/key_uppercase_letter_padding</item>
- <item name="keyPreviewTextColor">@color/key_text_color_default</item>
- <item name="keyPreviewTextRatio">@fraction/key_preview_text_ratio</item>
- <item name="verticalCorrection">@dimen/keyboard_vertical_correction</item>
- <item name="keyTextShadowColor">@color/key_text_shadow_color_default</item>
- <item name="keyTextShadowRadius">2.75</item>
- <item name="backgroundDimAlpha">128</item>
- <item name="gestureFloatingPreviewTextSize">@dimen/gesture_floating_preview_text_size</item>
- <item name="gestureFloatingPreviewTextColor">@color/highlight_color_default</item>
- <item name="gestureFloatingPreviewTextOffset">@dimen/gesture_floating_preview_text_offset</item>
- <item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_default</item>
- <item name="gestureFloatingPreviewHorizontalPadding">@dimen/gesture_floating_preview_horizontal_padding</item>
- <item name="gestureFloatingPreviewVerticalPadding">@dimen/gesture_floating_preview_vertical_padding</item>
- <item name="gestureFloatingPreviewRoundRadius">@dimen/gesture_floating_preview_round_radius</item>
- <item name="gestureTrailMinSamplingDistance">@dimen/gesture_trail_min_sampling_distance</item>
- <item name="gestureTrailMaxInterpolationAngularThreshold">@integer/gesture_trail_max_interpolation_angular_threshold</item>
- <item name="gestureTrailMaxInterpolationDistanceThreshold">@dimen/gesture_trail_max_interpolation_distance_threshold</item>
- <item name="gestureTrailMaxInterpolationSegments">@integer/gesture_trail_max_interpolation_segments</item>
- <item name="gestureTrailFadeoutStartDelay">@integer/config_gesture_trail_fadeout_start_delay</item>
- <item name="gestureTrailFadeoutDuration">@integer/config_gesture_trail_fadeout_duration</item>
- <item name="gestureTrailUpdateInterval">@integer/config_gesture_trail_update_interval</item>
- <item name="gestureTrailColor">@color/highlight_color_default</item>
- <item name="gestureTrailStartWidth">@dimen/gesture_trail_start_width</item>
- <item name="gestureTrailEndWidth">@dimen/gesture_trail_end_width</item>
- <item name="gestureTrailBodyRatio">@integer/gesture_trail_body_ratio</item>
- <item name="gestureTrailShadowRatio">@integer/gesture_trail_shadow_ratio</item>
- <!-- Common attributes of MainKeyboardView -->
- <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
- <item name="keyHysteresisDistanceForSlidingModifier">@dimen/config_key_hysteresis_distance_for_sliding_modifier</item>
- <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
- <item name="touchNoiseThresholdDistance">@dimen/config_touch_noise_threshold_distance</item>
- <item name="slidingKeyInputEnable">@bool/config_sliding_key_input_enabled</item>
- <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_default</item>
- <item name="slidingKeyInputPreviewWidth">@dimen/config_sliding_key_input_preview_width</item>
- <item name="slidingKeyInputPreviewBodyRatio">@integer/config_sliding_key_input_preview_body_ratio</item>
- <item name="slidingKeyInputPreviewShadowRatio">@integer/config_sliding_key_input_preview_shadow_ratio</item>
- <item name="keyRepeatStartTimeout">@integer/config_key_repeat_start_timeout</item>
- <item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
- <item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
- <item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
- <item name="keyPreviewLayout">@layout/key_preview</item>
- <item name="keyPreviewOffset">@dimen/key_preview_offset</item>
- <item name="keyPreviewHeight">@dimen/key_preview_height</item>
- <item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
- <item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
- <item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
- <item name="languageOnSpacebarFinalAlpha">@integer/config_language_on_spacebar_final_alpha</item>
- <item name="languageOnSpacebarFadeoutAnimator">@anim/language_on_spacebar_fadeout</item>
- <!-- Remove animations for now because it could drain a non-negligible amount of battery while typing.
- <item name="altCodeKeyWhileTypingFadeoutAnimator">@anim/alt_code_key_while_typing_fadeout</item>
- <item name="altCodeKeyWhileTypingFadeinAnimator">@anim/alt_code_key_while_typing_fadein</item>
- -->
- <!-- Common attributes of MainKeyboardView for gesture typing detection and recognition -->
- <item name="gestureFloatingPreviewTextLingerTimeout">@integer/config_gesture_floating_preview_text_linger_timeout</item>
- <item name="gestureStaticTimeThresholdAfterFastTyping">@integer/config_gesture_static_time_threshold_after_fast_typing</item>
- <item name="gestureDetectFastMoveSpeedThreshold">@fraction/config_gesture_detect_fast_move_speed_threshold</item>
- <item name="gestureDynamicThresholdDecayDuration">@integer/config_gesture_dynamic_threshold_decay_duration</item>
- <item name="gestureDynamicTimeThresholdFrom">@integer/config_gesture_dynamic_time_threshold_from</item>
- <item name="gestureDynamicTimeThresholdTo">@integer/config_gesture_dynamic_time_threshold_to</item>
- <item name="gestureDynamicDistanceThresholdFrom">@fraction/config_gesture_dynamic_distance_threshold_from</item>
- <item name="gestureDynamicDistanceThresholdTo">@fraction/config_gesture_dynamic_distance_threshold_to</item>
- <item name="gestureSamplingMinimumDistance">@fraction/config_gesture_sampling_minimum_distance</item>
- <item name="gestureRecognitionMinimumTime">@integer/config_gesture_recognition_minimum_time</item>
- <item name="gestureRecognitionUpdateTime">@integer/config_gesture_recognition_update_time</item>
- <item name="gestureRecognitionSpeedThreshold">@fraction/config_gesture_recognition_speed_threshold</item>
- <item name="suppressKeyPreviewAfterBatchInputDuration">@integer/config_suppress_key_preview_after_batch_input_duration</item>
- </style>
- <style
- name="MainKeyboardView"
- parent="KeyboardView">
- <item name="autoCorrectionSpacebarLedEnabled">true</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
- <item name="spacebarTextColor">@color/spacebar_text_color_default</item>
- <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_default</item>
- </style>
- <style
- name="MoreKeysKeyboard"
- parent="Keyboard"
- >
- <item name="keyboardTopPadding">0%p</item>
- <item name="keyboardBottomPadding">0%p</item>
- <item name="horizontalGap">0%p</item>
- <item name="touchPositionCorrectionData">@null</item>
- </style>
- <style
- name="MoreKeysKeyboardView"
- parent="KeyboardView"
- >
- <item name="keyBackground">@drawable/btn_keyboard_key_popup</item>
- <item name="verticalCorrection">@dimen/more_keys_keyboard_vertical_correction</item>
- </style>
- <style name="MoreKeysKeyboardPanelStyle">
- <item name="android:background">@drawable/keyboard_popup_panel_background</item>
- </style>
- <style
- name="SuggestionStripViewStyle"
- >
- <item name="android:background">@drawable/keyboard_suggest_strip</item>
- <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
- <item name="colorValidTypedWord">@color/highlight_color_default</item>
- <item name="colorTypedWord">@color/typed_word_color_default</item>
- <item name="colorAutoCorrect">@color/highlight_color_default</item>
- <item name="colorSuggested">@color/highlight_color_default</item>
- <item name="alphaObsoleted">50%</item>
- <item name="suggestionsCountInStrip">@integer/suggestions_count_in_strip</item>
- <item name="centerSuggestionPercentile">@fraction/center_suggestion_percentile</item>
- <item name="maxMoreSuggestionsRow">@integer/max_more_suggestions_row</item>
- <item name="minMoreSuggestionsWidth">@fraction/min_more_suggestions_width</item>
- </style>
- <style
- name="MoreSuggestionsViewStyle"
- parent="MoreKeysKeyboardView"
- >
- </style>
- <style name="SuggestionBackgroundStyle">
- <item name="android:background">@drawable/btn_suggestion</item>
- </style>
- <!-- Theme "Basic high contrast" -->
- <style
- name="Keyboard.HighContrast"
- parent="Keyboard"
- >
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">1</item>
- </style>
- <style
- name="KeyboardView.HighContrast"
- parent="KeyboardView"
- >
- <item name="android:background">@android:color/black</item>
- <item name="keyBackground">@drawable/btn_keyboard_key3</item>
- </style>
- <style
- name="MainKeyboardView.HighContrast"
- parent="KeyboardView.HighContrast"
- >
- <item name="autoCorrectionSpacebarLedEnabled">true</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
- <item name="spacebarTextColor">@color/spacebar_text_color_default</item>
- <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_default</item>
- </style>
- <!-- Theme "Stone" -->
- <style
- name="Keyboard.Stone"
- parent="Keyboard"
- >
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">6</item>
- <item name="keyboardTopPadding">@fraction/keyboard_top_padding_stone</item>
- <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_stone</item>
- <item name="horizontalGap">@fraction/key_horizontal_gap_stone</item>
- <item name="verticalGap">@fraction/key_bottom_gap_stone</item>
- </style>
- <style
- name="KeyboardView.Stone"
- parent="KeyboardView"
- >
- <item name="keyBackground">@drawable/btn_keyboard_key_stone</item>
- <item name="keyTextColor">@color/key_text_color_stone</item>
- <item name="keyTextInactivatedColor">@color/key_text_inactivated_color_stone</item>
- <item name="keyHintLetterColor">@color/key_hint_letter_color_stone</item>
- <item name="keyHintLabelColor">@color/key_hint_label_color_stone</item>
- <item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_stone</item>
- <item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_stone</item>
- <item name="keyTextShadowColor">@color/key_text_shadow_color_stone</item>
- </style>
- <style
- name="MainKeyboardView.Stone"
- parent="KeyboardView.Stone"
- >
- <item name="autoCorrectionSpacebarLedEnabled">true</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
- <item name="spacebarTextColor">@color/spacebar_text_color_stone</item>
- <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_stone</item>
- </style>
- <style
- name="MoreKeysKeyboard.Stone"
- parent="Keyboard.Stone"
- >
- <item name="keyboardTopPadding">0%p</item>
- <item name="keyboardBottomPadding">0%p</item>
- <item name="horizontalGap">0%p</item>
- <item name="touchPositionCorrectionData">@null</item>
- </style>
- <style
- name="MoreKeysKeyboardView.Stone"
- parent="MoreKeysKeyboardView"
- >
- <item name="keyBackground">@drawable/btn_keyboard_key_stone</item>
- <item name="keyTextColor">@color/key_text_color_stone</item>
- <item name="keyTextShadowColor">@color/key_text_shadow_color_stone</item>
- </style>
- <!-- Theme "Stone bold" -->
- <style
- name="Keyboard.Stone.Bold"
- parent="Keyboard.Stone"
- >
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">7</item>
- </style>
- <style
- name="KeyboardView.Stone.Bold"
- parent="KeyboardView.Stone"
- >
- <item name="keyTypeface">bold</item>
- </style>
- <style
- name="MainKeyboardView.Stone.Bold"
- parent="KeyboardView.Stone.Bold"
- >
- <item name="autoCorrectionSpacebarLedEnabled">true</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
- <item name="spacebarTextColor">@color/spacebar_text_color_stone</item>
- <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_stone</item>
- </style>
- <!-- Theme "Gingerbread" -->
- <style
- name="Keyboard.Gingerbread"
- parent="Keyboard"
- >
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">8</item>
- <item name="touchPositionCorrectionData">@array/touch_position_correction_data_gingerbread</item>
- <item name="horizontalGap">@fraction/key_horizontal_gap_gb</item>
- <item name="verticalGap">@fraction/key_bottom_gap_gb</item>
- </style>
- <style
- name="KeyboardView.Gingerbread"
- parent="KeyboardView"
- >
- <item name="android:background">@drawable/keyboard_dark_background</item>
- <item name="keyBackground">@drawable/btn_keyboard_key_gingerbread</item>
- <item name="keyTypeface">bold</item>
- </style>
- <style
- name="MainKeyboardView.Gingerbread"
- parent="KeyboardView.Gingerbread"
- >
- <item name="autoCorrectionSpacebarLedEnabled">true</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item>
- <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
- <item name="spacebarTextColor">@color/spacebar_text_color_default</item>
- <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_default</item>
- </style>
- <style
- name="MoreKeysKeyboard.Gingerbread"
- parent="Keyboard.Gingerbread"
- >
- <item name="keyboardTopPadding">0%p</item>
- <item name="keyboardBottomPadding">0%p</item>
- <item name="horizontalGap">0%p</item>
- <item name="touchPositionCorrectionData">@null</item>
- </style>
- <style
- name="MoreKeysKeyboardView.Gingerbread"
- parent="MoreKeysKeyboardView"
- >
- <item name="android:background">@null</item>
- </style>
- <!-- Theme "IceCreamSandwich" -->
- <style
- name="Keyboard.IceCreamSandwich"
- parent="Keyboard"
- >
- <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
- <item name="themeId">5</item>
- <item name="keyboardTopPadding">@fraction/keyboard_top_padding_ics</item>
- <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_ics</item>
- <item name="horizontalGap">@fraction/key_horizontal_gap_ics</item>
- <item name="verticalGap">@fraction/key_bottom_gap_ics</item>
- <item name="touchPositionCorrectionData">@array/touch_position_correction_data_ice_cream_sandwich</item>
- </style>
- <style
- name="KeyboardView.IceCreamSandwich"
- parent="KeyboardView"
- >
- <item name="android:background">@drawable/keyboard_background_holo</item>
- <item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
- <item name="keyTypeface">bold</item>
- <item name="keyTextInactivatedColor">@color/key_text_inactivated_color_ics</item>
- <item name="keyHintLetterColor">@color/key_hint_letter_color_ics</item>
- <item name="keyHintLabelColor">@color/key_hint_label_color_ics</item>
- <item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_ics</item>
- <item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_ics</item>
- <item name="keyPreviewLayout">@layout/key_preview_ics</item>
- <item name="keyPreviewTextColor">@color/key_text_color_ics</item>
- <item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
- <item name="keyTextShadowColor">@color/key_text_shadow_color_ics</item>
- <item name="keyTextShadowRadius">0.0</item>
- <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_ics</item>
- <item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
- <item name="gestureTrailColor">@color/highlight_color_ics</item>
- </style>
- <style
- name="MainKeyboardView.IceCreamSandwich"
- parent="KeyboardView.IceCreamSandwich"
- >
- <item name="autoCorrectionSpacebarLedEnabled">false</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
- <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
- <item name="spacebarTextColor">@color/spacebar_text_color_ics</item>
- <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_ics</item>
- </style>
- <style
- name="MoreKeysKeyboard.IceCreamSandwich"
- parent="Keyboard.IceCreamSandwich"
- >
- <item name="keyboardTopPadding">0%p</item>
- <item name="keyboardBottomPadding">0%p</item>
- <item name="horizontalGap">0%p</item>
- <item name="touchPositionCorrectionData">@null</item>
- </style>
- <style
- name="MoreKeysKeyboardView.IceCreamSandwich"
- parent="MoreKeysKeyboardView"
- >
- <item name="android:background">@null</item>
- <item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
- <item name="verticalCorrection">@dimen/more_keys_keyboard_vertical_correction_ics</item>
- </style>
- <style name="MoreKeysKeyboardPanelStyle.IceCreamSandwich">
- <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
- </style>
- <style
- name="SuggestionStripViewStyle.IceCreamSandwich"
- >
- <item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
- <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
- <item name="colorValidTypedWord">@color/highlight_color_ics</item>
- <item name="colorTypedWord">@color/highlight_color_ics</item>
- <item name="colorAutoCorrect">@color/highlight_color_ics</item>
- <item name="colorSuggested">@color/highlight_color_ics</item>
- <item name="alphaValidTypedWord">85%</item>
- <item name="alphaTypedWord">85%</item>
- <item name="alphaSuggested">70%</item>
- <item name="alphaObsoleted">70%</item>
- <item name="suggestionsCountInStrip">@integer/suggestions_count_in_strip</item>
- <item name="centerSuggestionPercentile">@fraction/center_suggestion_percentile</item>
- <item name="maxMoreSuggestionsRow">@integer/max_more_suggestions_row</item>
- <item name="minMoreSuggestionsWidth">@fraction/min_more_suggestions_width</item>
- </style>
- <style
- name="MoreSuggestionsViewStyle.IceCreamSandwich"
- parent="MoreKeysKeyboardView.IceCreamSandwich"
- >
- </style>
- <style name="SuggestionBackgroundStyle.IceCreamSandwich">
- <item name="android:background">@drawable/btn_suggestion_ics</item>
- </style>
- <style
- name="SuggestionPreviewBackgroundStyle.IceCreamSandwich"
- parent="MoreKeysKeyboardPanelStyle.IceCreamSandwich"
- >
- </style>
- <style name="MoreKeysKeyboardAnimation">
- <item name="android:windowEnterAnimation">@anim/more_keys_keyboard_fadein</item>
- <item name="android:windowExitAnimation">@anim/more_keys_keyboard_fadeout</item>
- </style>
-</resources>
diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml
deleted file mode 100644
index e81d47386..000000000
--- a/java/res/values/themes-basic-highcontrast.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardTheme.HighContrast" parent="KeyboardIcons">
- <item name="keyboardStyle">@style/Keyboard.HighContrast</item>
- <item name="keyboardViewStyle">@style/KeyboardView.HighContrast</item>
- <item name="mainKeyboardViewStyle">@style/MainKeyboardView.HighContrast</item>
- <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard</item>
- <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView</item>
- <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
- <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
- <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
- <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
- </style>
-</resources>
diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml
deleted file mode 100644
index c44f0f614..000000000
--- a/java/res/values/themes-basic.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardTheme" parent="KeyboardIcons">
- <item name="keyboardStyle">@style/Keyboard</item>
- <item name="keyboardViewStyle">@style/KeyboardView</item>
- <item name="mainKeyboardViewStyle">@style/MainKeyboardView</item>
- <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard</item>
- <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView</item>
- <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
- <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
- <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
- <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
- </style>
-</resources>
diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml
new file mode 100644
index 000000000..8e9cfc90b
--- /dev/null
+++ b/java/res/values/themes-common.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="KeyboardIcons" />
+ <!-- Default theme values -->
+ <style name="Keyboard">
+ <item name="touchPositionCorrectionData">@array/touch_position_correction_data_default</item>
+ <item name="rowHeight">25%p</item>
+ <item name="moreKeysTemplate">@xml/kbd_more_keys_keyboard_template</item>
+ <item name="keyboardLeftPadding">@fraction/keyboard_left_padding</item>
+ <item name="keyboardRightPadding">@fraction/keyboard_right_padding</item>
+ <item name="maxMoreKeysColumn">@integer/config_max_more_keys_column</item>
+ </style>
+ <style name="KeyboardView">
+ <item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
+ <item name="keyLetterSize">@fraction/key_letter_ratio</item>
+ <item name="keyLargeLetterRatio">@fraction/key_large_letter_ratio</item>
+ <item name="keyLabelSize">@fraction/key_label_ratio</item>
+ <item name="keyLargeLabelRatio">@fraction/key_large_label_ratio</item>
+ <item name="keyHintLetterRatio">@fraction/key_hint_letter_ratio</item>
+ <item name="keyHintLabelRatio">@fraction/key_hint_label_ratio</item>
+ <item name="keyShiftedLetterHintRatio">@fraction/key_uppercase_letter_ratio</item>
+ <item name="keyTypeface">normal</item>
+ <item name="keyLabelHorizontalPadding">@dimen/key_label_horizontal_padding</item>
+ <item name="keyHintLetterPadding">@dimen/key_hint_letter_padding</item>
+ <item name="keyPopupHintLetterPadding">@dimen/key_popup_hint_letter_padding</item>
+ <item name="keyShiftedLetterHintPadding">@dimen/key_uppercase_letter_padding</item>
+ <item name="keyPreviewTextRatio">@fraction/key_preview_text_ratio</item>
+ <item name="verticalCorrection">@dimen/keyboard_vertical_correction</item>
+ <item name="backgroundDimAlpha">128</item>
+ <item name="gestureFloatingPreviewTextSize">@dimen/gesture_floating_preview_text_size</item>
+ <item name="gestureFloatingPreviewTextOffset">@dimen/gesture_floating_preview_text_offset</item>
+ <item name="gestureFloatingPreviewHorizontalPadding">@dimen/gesture_floating_preview_horizontal_padding</item>
+ <item name="gestureFloatingPreviewVerticalPadding">@dimen/gesture_floating_preview_vertical_padding</item>
+ <item name="gestureFloatingPreviewRoundRadius">@dimen/gesture_floating_preview_round_radius</item>
+ <item name="gestureTrailMinSamplingDistance">@dimen/gesture_trail_min_sampling_distance</item>
+ <item name="gestureTrailMaxInterpolationAngularThreshold">@integer/gesture_trail_max_interpolation_angular_threshold</item>
+ <item name="gestureTrailMaxInterpolationDistanceThreshold">@dimen/gesture_trail_max_interpolation_distance_threshold</item>
+ <item name="gestureTrailMaxInterpolationSegments">@integer/gesture_trail_max_interpolation_segments</item>
+ <item name="gestureTrailFadeoutStartDelay">@integer/config_gesture_trail_fadeout_start_delay</item>
+ <item name="gestureTrailFadeoutDuration">@integer/config_gesture_trail_fadeout_duration</item>
+ <item name="gestureTrailUpdateInterval">@integer/config_gesture_trail_update_interval</item>
+ <item name="gestureTrailStartWidth">@dimen/gesture_trail_start_width</item>
+ <item name="gestureTrailEndWidth">@dimen/gesture_trail_end_width</item>
+ <item name="gestureTrailBodyRatio">@integer/gesture_trail_body_ratio</item>
+ <item name="gestureTrailShadowRatio">@integer/gesture_trail_shadow_ratio</item>
+ <!-- Common attributes of MainKeyboardView -->
+ <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
+ <item name="keyHysteresisDistanceForSlidingModifier">@dimen/config_key_hysteresis_distance_for_sliding_modifier</item>
+ <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
+ <item name="touchNoiseThresholdDistance">@dimen/config_touch_noise_threshold_distance</item>
+ <item name="slidingKeyInputEnable">@bool/config_sliding_key_input_enabled</item>
+ <item name="slidingKeyInputPreviewWidth">@dimen/config_sliding_key_input_preview_width</item>
+ <item name="slidingKeyInputPreviewBodyRatio">@integer/config_sliding_key_input_preview_body_ratio</item>
+ <item name="slidingKeyInputPreviewShadowRatio">@integer/config_sliding_key_input_preview_shadow_ratio</item>
+ <item name="keyRepeatStartTimeout">@integer/config_key_repeat_start_timeout</item>
+ <item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
+ <item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
+ <item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
+ <item name="keyPreviewHeight">@dimen/key_preview_height</item>
+ <item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
+ <item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
+ <item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
+ <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item>
+ <item name="languageOnSpacebarFinalAlpha">@integer/config_language_on_spacebar_final_alpha</item>
+ <item name="languageOnSpacebarFadeoutAnimator">@anim/language_on_spacebar_fadeout</item>
+ <!-- Remove animations for now because it could drain a non-negligible amount of battery while typing.
+ <item name="altCodeKeyWhileTypingFadeoutAnimator">@anim/alt_code_key_while_typing_fadeout</item>
+ <item name="altCodeKeyWhileTypingFadeinAnimator">@anim/alt_code_key_while_typing_fadein</item>
+ -->
+ <!-- Common attributes of MainKeyboardView for gesture typing detection and recognition -->
+ <item name="gestureFloatingPreviewTextLingerTimeout">@integer/config_gesture_floating_preview_text_linger_timeout</item>
+ <item name="gestureStaticTimeThresholdAfterFastTyping">@integer/config_gesture_static_time_threshold_after_fast_typing</item>
+ <item name="gestureDetectFastMoveSpeedThreshold">@fraction/config_gesture_detect_fast_move_speed_threshold</item>
+ <item name="gestureDynamicThresholdDecayDuration">@integer/config_gesture_dynamic_threshold_decay_duration</item>
+ <item name="gestureDynamicTimeThresholdFrom">@integer/config_gesture_dynamic_time_threshold_from</item>
+ <item name="gestureDynamicTimeThresholdTo">@integer/config_gesture_dynamic_time_threshold_to</item>
+ <item name="gestureDynamicDistanceThresholdFrom">@fraction/config_gesture_dynamic_distance_threshold_from</item>
+ <item name="gestureDynamicDistanceThresholdTo">@fraction/config_gesture_dynamic_distance_threshold_to</item>
+ <item name="gestureSamplingMinimumDistance">@fraction/config_gesture_sampling_minimum_distance</item>
+ <item name="gestureRecognitionMinimumTime">@integer/config_gesture_recognition_minimum_time</item>
+ <item name="gestureRecognitionUpdateTime">@integer/config_gesture_recognition_update_time</item>
+ <item name="gestureRecognitionSpeedThreshold">@fraction/config_gesture_recognition_speed_threshold</item>
+ <item name="suppressKeyPreviewAfterBatchInputDuration">@integer/config_suppress_key_preview_after_batch_input_duration</item>
+ </style>
+ <style
+ name="MainKeyboardView"
+ parent="KeyboardView" />
+ <!-- Though {@link EmojiKeyboardView} doesn't extend {@link KeyboardView}, some views inside it,
+ for instance delete button, need themed {@link KeyboardView} attributes. -->
+ <style
+ name="EmojiKeyboardView"
+ parent="KeyboardView"
+ >
+ <item name="emojiTabLabelColor">@color/emoji_tab_label_color_ics</item>
+ </style>
+ <style name="MoreKeysKeyboard" />
+ <style
+ name="MoreKeysKeyboardView"
+ parent="MainKeyboardView" />
+ <style name="MoreKeysKeyboardContainer" />
+ <style name="SuggestionStripView">
+ <item name="suggestionsCountInStrip">@integer/suggestions_count_in_strip</item>
+ <item name="centerSuggestionPercentile">@fraction/center_suggestion_percentile</item>
+ <item name="maxMoreSuggestionsRow">@integer/max_more_suggestions_row</item>
+ <item name="minMoreSuggestionsWidth">@fraction/min_more_suggestions_width</item>
+ </style>
+ <style name="SuggestionWord" />
+ <style name="MoreKeysKeyboardAnimation">
+ <item name="android:windowEnterAnimation">@anim/more_keys_keyboard_fadein</item>
+ <item name="android:windowExitAnimation">@anim/more_keys_keyboard_fadeout</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/java/res/values/themes-gb.xml b/java/res/values/themes-gb.xml
new file mode 100644
index 000000000..d9ac4acb2
--- /dev/null
+++ b/java/res/values/themes-gb.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+ <style name="KeyboardTheme.GB" parent="KeyboardIcons.GB">
+ <item name="keyboardStyle">@style/Keyboard.GB</item>
+ <item name="keyboardViewStyle">@style/KeyboardView.GB</item>
+ <item name="mainKeyboardViewStyle">@style/MainKeyboardView.GB</item>
+ <item name="emojiKeyboardViewStyle">@style/EmojiKeyboardView.GB</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.GB</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.GB</item>
+ <item name="moreKeysKeyboardContainerStyle">@style/MoreKeysKeyboardContainer.GB</item>
+ <item name="suggestionStripViewStyle">@style/SuggestionStripView.GB</item>
+ <item name="suggestionWordStyle">@style/SuggestionWord.GB</item>
+ </style>
+ <style name="KeyboardIcons.GB">
+ <!-- Keyboard icons -->
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo_dark</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo_dark</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo_dark</item>
+ <item name="iconSpaceKey">@drawable/sym_keyboard_space_holo_dark</item>
+ <item name="iconEnterKey">@drawable/sym_keyboard_return_holo_dark</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search_holo_dark</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab_holo_dark</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_mic_holo_dark</item>
+ <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo_dark</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo_dark</item>
+ <!-- TODO: Needs non-holo disabled shortcut icon drawable -->
+ <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo_dark</item>
+ <item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
+ <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch_dark</item>
+ <!-- TODO: Needs dedicated black theme ZWNJ and ZWJ icons -->
+ <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo_dark</item>
+ <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo_dark</item>
+ <item name="iconEmojiKey">@drawable/sym_keyboard_smiley_holo_dark</item>
+ </style>
+ <style
+ name="Keyboard.GB"
+ parent="Keyboard"
+ >
+ <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
+ <item name="themeId">1</item>
+ <item name="touchPositionCorrectionData">@array/touch_position_correction_data_gb</item>
+ <item name="keyboardTopPadding">@fraction/keyboard_top_padding_gb</item>
+ <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_gb</item>
+ <item name="horizontalGap">@fraction/key_horizontal_gap_gb</item>
+ <item name="verticalGap">@fraction/key_bottom_gap_gb</item>
+ </style>
+ <style
+ name="KeyboardView.GB"
+ parent="KeyboardView"
+ >
+ <item name="android:background">@drawable/keyboard_background_gb</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_gb</item>
+ <item name="keyTypeface">bold</item>
+ <item name="keyTextColor">@color/key_text_color_gb</item>
+ <item name="keyTextInactivatedColor">@color/key_text_inactivated_color_gb</item>
+ <item name="keyHintLetterColor">@color/key_hint_letter_color_gb</item>
+ <item name="keyHintLabelColor">@color/key_hint_label_color_gb</item>
+ <item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_gb</item>
+ <item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_gb</item>
+ <item name="keyPreviewTextColor">@color/key_text_color_gb</item>
+ <item name="keyTextShadowColor">@color/key_text_shadow_color_gb</item>
+ <item name="keyTextShadowRadius">2.75</item>
+ </style>
+ <style
+ name="MainKeyboardView.GB"
+ parent="KeyboardView.GB"
+ >
+ <item name="keyPreviewLayout">@layout/key_preview_gb</item>
+ <item name="keyPreviewOffset">@dimen/key_preview_offset_gb</item>
+ <item name="gestureFloatingPreviewTextColor">@color/highlight_color_gb</item>
+ <item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_gb</item>
+ <item name="gestureTrailColor">@color/highlight_color_gb</item>
+ <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_gb</item>
+ <item name="autoCorrectionSpacebarLedEnabled">true</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_gb</item>
+ <item name="spacebarTextColor">@color/spacebar_text_color_gb</item>
+ <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_gb</item>
+ </style>
+ <!-- Though {@link EmojiKeyboardView} doesn't extend {@link KeyboardView}, some views inside it,
+ for instance delete button, need themed {@link KeyboardView} attributes. -->
+ <style
+ name="EmojiKeyboardView.GB"
+ parent="KeyboardView.GB"
+ >
+ <item name="keyBackground">@drawable/btn_keyboard_key_functional_gb</item>
+ <item name="emojiTabLabelColor">@color/emoji_tab_label_color_gb</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard.GB"
+ parent="Keyboard.GB"
+ >
+ <item name="keyboardTopPadding">0%p</item>
+ <item name="keyboardBottomPadding">0%p</item>
+ <item name="horizontalGap">0%p</item>
+ <item name="touchPositionCorrectionData">@null</item>
+ </style>
+ <style
+ name="MoreKeysKeyboardView.GB"
+ parent="KeyboardView.GB"
+ >
+ <item name="android:background">@null</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_gb</item>
+ <item name="keyTypeface">normal</item>
+ <item name="verticalCorrection">@dimen/more_keys_keyboard_vertical_correction_gb</item>
+ </style>
+ <style
+ name="MoreKeysKeyboardContainer.GB"
+ >
+ <item name="android:background">@drawable/keyboard_popup_panel_background_gb</item>
+ </style>
+ <style
+ name="SuggestionStripView.GB"
+ parent="SuggestionStripView"
+ >
+ <item name="android:background">@drawable/keyboard_suggest_strip_gb</item>
+ <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
+ <item name="colorValidTypedWord">@color/highlight_color_gb</item>
+ <item name="colorTypedWord">@color/typed_word_color_gb</item>
+ <item name="colorAutoCorrect">@color/highlight_color_gb</item>
+ <item name="colorSuggested">@color/highlight_color_gb</item>
+ <item name="alphaObsoleted">50%</item>
+ </style>
+ <style name="SuggestionWord.GB">
+ <item name="android:background">@drawable/btn_suggestion_gb</item>
+ </style>
+</resources>
diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml
deleted file mode 100644
index 129afdf5b..000000000
--- a/java/res/values/themes-gingerbread.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardTheme.Gingerbread" parent="KeyboardIcons">
- <item name="keyboardStyle">@style/Keyboard.Gingerbread</item>
- <item name="keyboardViewStyle">@style/KeyboardView.Gingerbread</item>
- <item name="mainKeyboardViewStyle">@style/MainKeyboardView.Gingerbread</item>
- <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Gingerbread</item>
- <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Gingerbread</item>
- <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
- <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
- <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
- <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
- </style>
-</resources>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 1264831f3..33dd50c2c 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -1,29 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
-->
-<resources>
- <style name="KeyboardTheme.IceCreamSandwich" parent="KeyboardIcons.IceCreamSandwich">
- <item name="keyboardStyle">@style/Keyboard.IceCreamSandwich</item>
- <item name="keyboardViewStyle">@style/KeyboardView.IceCreamSandwich</item>
- <item name="mainKeyboardViewStyle">@style/MainKeyboardView.IceCreamSandwich</item>
- <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.IceCreamSandwich</item>
- <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.IceCreamSandwich</item>
- <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle.IceCreamSandwich</item>
- <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle.IceCreamSandwich</item>
- <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle.IceCreamSandwich</item>
- <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="KeyboardTheme.ICS" parent="KeyboardIcons.ICS">
+ <item name="keyboardStyle">@style/Keyboard.ICS</item>
+ <item name="keyboardViewStyle">@style/KeyboardView.ICS</item>
+ <item name="mainKeyboardViewStyle">@style/MainKeyboardView.ICS</item>
+ <item name="emojiKeyboardViewStyle">@style/EmojiKeyboardView.ICS</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.ICS</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.ICS</item>
+ <item name="moreKeysKeyboardContainerStyle">@style/MoreKeysKeyboardContainer.ICS</item>
+ <item name="suggestionStripViewStyle">@style/SuggestionStripView.ICS</item>
+ <item name="suggestionWordStyle">@style/SuggestionWord.ICS</item>
+ </style>
+ <style name="KeyboardIcons.ICS">
+ <!-- Keyboard icons -->
+ <!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are missing.
+ sym_keyboard_123_mic_holo
+ -->
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo_dark</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo_dark</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo_dark</item>
+ <item name="iconSpaceKey">@null</item>
+ <item name="iconEnterKey">@drawable/sym_keyboard_return_holo_dark</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search_holo_dark</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab_holo_dark</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo_dark</item>
+ <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo_dark</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space_holo_dark</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo_dark</item>
+ <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo_dark</item>
+ <item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
+ <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch_dark</item>
+ <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo_dark</item>
+ <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo_dark</item>
+ <item name="iconEmojiKey">@drawable/sym_keyboard_smiley_holo_dark</item>
+ </style>
+ <style
+ name="Keyboard.ICS"
+ parent="Keyboard"
+ >
+ <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
+ <item name="themeId">0</item>
+ <item name="keyboardTopPadding">@fraction/keyboard_top_padding_ics</item>
+ <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding_ics</item>
+ <item name="horizontalGap">@fraction/key_horizontal_gap_ics</item>
+ <item name="verticalGap">@fraction/key_bottom_gap_ics</item>
+ <item name="touchPositionCorrectionData">@array/touch_position_correction_data_ics</item>
+ </style>
+ <style
+ name="KeyboardView.ICS"
+ parent="KeyboardView"
+ >
+ <item name="android:background">@drawable/keyboard_background_holo</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
+ <item name="keyTypeface">bold</item>
+ <item name="keyTextColor">@color/key_text_color_ics</item>
+ <item name="keyTextInactivatedColor">@color/key_text_inactivated_color_ics</item>
+ <item name="keyHintLetterColor">@color/key_hint_letter_color_ics</item>
+ <item name="keyHintLabelColor">@color/key_hint_label_color_ics</item>
+ <item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_ics</item>
+ <item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_ics</item>
+ <item name="keyPreviewTextColor">@color/key_text_color_ics</item>
+ <item name="keyTextShadowColor">@color/key_text_shadow_color_ics</item>
+ <item name="keyTextShadowRadius">0.0</item>
+ </style>
+ <style
+ name="MainKeyboardView.ICS"
+ parent="KeyboardView.ICS"
+ >
+ <item name="keyPreviewLayout">@layout/key_preview_ics</item>
+ <item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
+ <item name="gestureFloatingPreviewTextColor">@color/highlight_color_holo</item>
+ <item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_ics</item>
+ <item name="gestureTrailColor">@color/highlight_color_holo</item>
+ <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_holo</item>
+ <item name="autoCorrectionSpacebarLedEnabled">false</item>
+ <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
+ <item name="spacebarTextColor">@color/spacebar_text_color_ics</item>
+ <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_ics</item>
+ </style>
+ <!-- Though {@link EmojiKeyboardView} doesn't extend {@link KeyboardView}, some views inside it,
+ for instance delete button, need themed {@link KeyboardView} attributes. -->
+ <style
+ name="EmojiKeyboardView.ICS"
+ parent="KeyboardView.ICS"
+ >
+ <item name="keyBackgroundEmojiFunctional">@drawable/btn_keyboard_key_functional_ics</item>
+ <item name="emojiTabLabelColor">@color/emoji_tab_label_color_ics</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard.ICS"
+ parent="Keyboard.ICS"
+ >
+ <item name="keyboardTopPadding">0%p</item>
+ <item name="keyboardBottomPadding">0%p</item>
+ <item name="horizontalGap">0%p</item>
+ <item name="touchPositionCorrectionData">@null</item>
+ </style>
+ <style
+ name="MoreKeysKeyboardView.ICS"
+ parent="KeyboardView.ICS"
+ >
+ <item name="android:background">@null</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_ics</item>
+ <item name="keyTypeface">normal</item>
+ <item name="verticalCorrection">@dimen/more_keys_keyboard_vertical_correction_ics</item>
+ </style>
+ <style
+ name="MoreKeysKeyboardContainer.ICS"
+ >
+ <item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
+ </style>
+ <style
+ name="SuggestionStripView.ICS"
+ parent="SuggestionStripView"
+ >
+ <item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
+ <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
+ <item name="colorValidTypedWord">@color/typed_word_color_holo</item>
+ <item name="colorTypedWord">@color/typed_word_color_holo</item>
+ <item name="colorAutoCorrect">@color/highlight_color_holo</item>
+ <item name="colorSuggested">@color/suggested_word_color_holo</item>
+ <item name="alphaObsoleted">70%</item>
+ </style>
+ <style name="SuggestionWord.ICS">
+ <item name="android:background">@drawable/btn_suggestion_ics</item>
</style>
</resources>
diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml
deleted file mode 100644
index 196f3ef9f..000000000
--- a/java/res/values/themes-stone-bold.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardTheme.Stone.Bold" parent="KeyboardIcons.Black">
- <item name="keyboardStyle">@style/Keyboard.Stone.Bold</item>
- <item name="keyboardViewStyle">@style/KeyboardView.Stone.Bold</item>
- <item name="mainKeyboardViewStyle">@style/MainKeyboardView.Stone.Bold</item>
- <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Stone</item>
- <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Stone</item>
- <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
- <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
- <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
- <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
- </style>
-</resources>
diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml
deleted file mode 100644
index d0d35c28d..000000000
--- a/java/res/values/themes-stone.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <style name="KeyboardTheme.Stone" parent="KeyboardIcons.Black">
- <item name="keyboardStyle">@style/Keyboard.Stone</item>
- <item name="keyboardViewStyle">@style/KeyboardView.Stone</item>
- <item name="mainKeyboardViewStyle">@style/MainKeyboardView.Stone</item>
- <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.Stone</item>
- <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.Stone</item>
- <item name="moreKeysKeyboardPanelStyle">@style/MoreKeysKeyboardPanelStyle</item>
- <item name="suggestionStripViewStyle">@style/SuggestionStripViewStyle</item>
- <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
- <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
- </style>
-</resources>
diff --git a/java/res/values/touch-position-correction.xml b/java/res/values/touch-position-correction.xml
index 7df86f467..9df517b32 100644
--- a/java/res/values/touch-position-correction.xml
+++ b/java/res/values/touch-position-correction.xml
@@ -37,7 +37,7 @@
</string-array>
<string-array
- name="touch_position_correction_data_gingerbread"
+ name="touch_position_correction_data_gb"
translatable="false"
>
<!-- First row -->
@@ -57,7 +57,7 @@
</string-array>
<string-array
- name="touch_position_correction_data_ice_cream_sandwich"
+ name="touch_position_correction_data_ics"
translatable="false"
>
<!-- First row -->
diff --git a/java/res/xml-sw600dp/key_apostrophe.xml b/java/res/xml-sw600dp/key_apostrophe.xml
deleted file mode 100644
index 2aec34729..000000000
--- a/java/res/xml-sw600dp/key_apostrophe.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:mode="email|url"
- >
- <Key
- latin:keyLabel="-" />
- </case>
- <case
- latin:languageCode="fa"
- >
- <Key
- latin:keyLabel="!text/keylabel_for_apostrophe"
- latin:keyHintLabel="!text/keyhintlabel_for_apostrophe"
- latin:keyLabelFlags="hasPopupHint"
- latin:moreKeys="!text/more_keys_for_apostrophe"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </case>
- <default>
- <Key
- latin:keyLabel="!text/keylabel_for_apostrophe"
- latin:keyHintLabel="!text/keyhintlabel_for_apostrophe"
- latin:moreKeys="!text/more_keys_for_apostrophe"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml-sw600dp/key_dash.xml b/java/res/xml-sw600dp/key_dash.xml
deleted file mode 100644
index b139c29c8..000000000
--- a/java/res/xml-sw600dp/key_dash.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:mode="email|url"
- >
- <Key
- latin:keyLabel="_" />
- </case>
- <case
- latin:languageCode="ar|fa"
- >
- <Key
- latin:keyLabel="."
- latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics"
- latin:keyLabelFlags="hasPopupHint"
- latin:moreKeys="!text/more_keys_for_arabic_diacritics"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </case>
- <default>
- <Key
- latin:keyLabel="-"
- latin:keyHintLabel="_"
- latin:moreKeys="_"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml-sw600dp/key_f1.xml b/java/res/xml-sw600dp/key_f1.xml
index 77afe4e64..ac0053236 100644
--- a/java/res/xml-sw600dp/key_f1.xml
+++ b/java/res/xml-sw600dp/key_f1.xml
@@ -53,10 +53,7 @@
</case>
<default>
<Key
- latin:keyLabel="/"
- latin:keyHintLabel="\@"
- latin:moreKeys="\@"
- latin:keyStyle="hasShiftedLetterHintStyle" />
+ latin:keyLabel="/" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw600dp/key_f2.xml b/java/res/xml-sw600dp/key_f2.xml
deleted file mode 100644
index ca3b30b54..000000000
--- a/java/res/xml-sw600dp/key_f2.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:mode="email|url"
- >
- <Key
- latin:keyStyle="comKeyStyle" />
- </case>
- <case
- latin:imeAction="actionSearch"
- >
- <Key
- latin:keyLabel=":"
- latin:keyHintLabel="+"
- latin:moreKeys="+"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </case>
- <default>
- <Key
- latin:keyStyle="smileyKeyStyle" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml-sw600dp/key_space.xml b/java/res/xml-sw600dp/key_space_5kw.xml
index 86af89f50..86af89f50 100644
--- a/java/res/xml-sw600dp/key_space.xml
+++ b/java/res/xml-sw600dp/key_space_5kw.xml
diff --git a/java/res/xml/kbd_10_10_7_symbols.xml b/java/res/xml-sw600dp/key_space_symbols.xml
index 4d9861b73..07aa7d179 100644
--- a/java/res/xml/kbd_10_10_7_symbols.xml
+++ b/java/res/xml-sw600dp/key_space_symbols.xml
@@ -18,10 +18,9 @@
*/
-->
-<Keyboard
+<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_symbols" />
-</Keyboard>
+ latin:keyboardLayout="@xml/key_space_5kw" />
+</merge>
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index f407ba346..d817add11 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -123,7 +123,8 @@
latin:styleName="emojiKeyStyle"
latin:code="!code/key_emoji"
latin:keyIcon="!icon/emoji_key"
- latin:keyActionFlags="noKeyPreview" />
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="functional" />
<key-style
latin:styleName="settingsKeyStyle"
latin:code="!code/key_settings"
diff --git a/java/res/xml-sw600dp/keys_comma_period.xml b/java/res/xml-sw600dp/keys_comma_period.xml
deleted file mode 100644
index 752f75b5f..000000000
--- a/java/res/xml-sw600dp/keys_comma_period.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:mode="email"
- >
- <Key
- latin:keyLabel="," />
- <Key
- latin:keyLabel="." />
- </case>
- <default>
- <Key
- latin:keyLabel="!text/keylabel_for_tablet_comma"
- latin:keyHintLabel="!text/keyhintlabel_for_tablet_comma"
- latin:moreKeys="!text/more_keys_for_tablet_comma"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="."
- latin:keyHintLabel="!text/keyhintlabel_for_tablet_period"
- latin:moreKeys="!text/more_keys_for_tablet_period"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml-sw600dp/keys_exclamation_question.xml b/java/res/xml-sw600dp/keys_exclamation_question.xml
new file mode 100644
index 000000000..983ef3897
--- /dev/null
+++ b/java/res/xml-sw600dp/keys_exclamation_question.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <Key
+ latin:keyLabel="\?" />
+ <Key
+ latin:keyLabel="!" />
+</merge>
diff --git a/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml b/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml
index 0a27ca70c..324e025ed 100644
--- a/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml
+++ b/java/res/xml-sw600dp/keys_pcqwerty2_right3.xml
@@ -23,36 +23,32 @@
>
<switch>
<case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
>
<Key
latin:keyLabel="["
- latin:moreKeys="{" />
- <Key
- latin:keyLabel="]"
- latin:moreKeys="}" />
- <!-- U+00A6: "¦" BROKEN BAR -->
- <Key
- latin:keyLabel="\\"
- latin:moreKeys="\\|,&#x00A6;" />
- </case>
- <default>
- <Key
- latin:keyLabel="["
latin:keyHintLabel="{"
- latin:moreKeys="{"
+ latin:additionalMoreKeys="{"
latin:keyStyle="hasShiftedLetterHintStyle" />
<Key
latin:keyLabel="]"
latin:keyHintLabel="}"
- latin:moreKeys="}"
+ latin:additionalMoreKeys="}"
latin:keyStyle="hasShiftedLetterHintStyle" />
- <!-- U+00A6: "¦" BROKEN BAR -->
<Key
latin:keyLabel="\\"
latin:keyHintLabel="|"
- latin:moreKeys="\\|,&#x00A6;"
+ latin:additionalMoreKeys="\\|"
latin:keyStyle="hasShiftedLetterHintStyle" />
+ </case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
+ <default>
+ <Key
+ latin:keyLabel="{" />
+ <Key
+ latin:keyLabel="}" />
+ <Key
+ latin:keyLabel="|" />
</default>
</switch>
-</merge>
+</merge> \ No newline at end of file
diff --git a/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml b/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml
index 0e3013afe..254b5e571 100644
--- a/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml
+++ b/java/res/xml-sw600dp/keys_pcqwerty3_right2.xml
@@ -23,26 +23,27 @@
>
<switch>
<case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
>
<Key
latin:keyLabel=";"
- latin:moreKeys=":" />
+ latin:keyHintLabel=":"
+ latin:additionalMoreKeys=":"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<Key
latin:keyLabel="\'"
- latin:moreKeys="!fixedColumnOrder!3,!text/double_quotes,!text/single_quotes" />
+ latin:keyHintLabel="&quot;"
+ latin:additionalMoreKeys="&quot;"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!fixedColumnOrder!4,!text/double_quotes,%,!text/single_quotes" />
</case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
<default>
<Key
- latin:keyLabel=";"
- latin:keyHintLabel=":"
- latin:moreKeys=":"
- latin:keyStyle="hasShiftedLetterHintStyle" />
+ latin:keyLabel=":" />
<Key
- latin:keyLabel="\'"
- latin:keyHintLabel="&quot;"
- latin:moreKeys="!fixedColumnOrder!4,!text/double_quotes,&quot;,!text/single_quotes"
- latin:keyStyle="hasShiftedLetterHintStyle" />
+ latin:keyLabel="&quot;"
+ latin:moreKeys="!fixedColumnOrder!3,!text/double_quotes,!text/single_quotes" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml b/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml
index ee5271abe..774ff8d05 100644
--- a/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml
+++ b/java/res/xml-sw600dp/keys_pcqwerty4_right3.xml
@@ -23,28 +23,26 @@
>
<switch>
<case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
>
- <!-- U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
- U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
- U+2264: "≤" LESS-THAN OR EQUAL TO
- U+2265: "≥" GREATER-THAN EQUAL TO
- U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
- U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -->
- <Key
+ <Key
latin:keyLabel=","
+ latin:keyHintLabel="&lt;"
latin:additionalMoreKeys="&lt;"
- latin:moreKeys="!fixedColumnOrder!4,&#x2039;,&#x2064;,&#x00AB;" />
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<Key
latin:keyLabel="."
+ latin:keyHintLabel="&gt;"
latin:additionalMoreKeys="&gt;"
- latin:moreKeys="!fixedColumnOrder!4,&#x203A;,&#x2065;,&#x00BB;" />
- <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<Key
latin:keyLabel="/"
+ latin:keyHintLabel="\?"
latin:additionalMoreKeys="\?"
- latin:moreKeys="&#x00BF;" />
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_question" />
</case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
<default>
<!-- U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
@@ -53,24 +51,14 @@
U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -->
<Key
- latin:keyLabel=","
- latin:keyHintLabel="&lt;"
- latin:additionalMoreKeys="&lt;"
- latin:moreKeys="!fixedColumnOrder!4,&#x2039;,&#x2264;,&#x00AB;"
- latin:keyStyle="hasShiftedLetterHintStyle" />
+ latin:keyLabel="&lt;"
+ latin:moreKeys="!fixedColumnOrder!3,&#x2039;,&#x2264;,&#x00AB;" />
<Key
- latin:keyLabel="."
- latin:keyHintLabel="&gt;"
- latin:additionalMoreKeys="&gt;"
- latin:moreKeys="!fixedColumnOrder!4,&#x203A;,&#x2265;,&#x00BB;"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
+ latin:keyLabel="&gt;"
+ latin:moreKeys="!fixedColumnOrder!3,&#x203A;,&#x2265;,&#x00BB;" />
<Key
- latin:keyLabel="/"
- latin:keyHintLabel="\?"
- latin:additionalMoreKeys="\?"
- latin:moreKeys="&#x00BF;"
- latin:keyStyle="hasShiftedLetterHintStyle" />
+ latin:keyLabel="\?"
+ latin:moreKeys="!text/more_keys_for_symbols_question" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw600dp/row_dvorak4.xml b/java/res/xml-sw600dp/row_dvorak4.xml
index 969cc145e..11b403452 100644
--- a/java/res/xml-sw600dp/row_dvorak4.xml
+++ b/java/res/xml-sw600dp/row_dvorak4.xml
@@ -34,12 +34,15 @@
latin:keyboardLayout="@xml/key_f1" />
<include
latin:keyXPos="28.0%p"
- latin:keyboardLayout="@xml/key_space"
+ latin:keyboardLayout="@xml/key_space_5kw"
latin:backgroundType="normal" />
<include
latin:keyboardLayout="@xml/key_question_exclamation" />
- <include
- latin:keyboardLayout="@xml/key_dash" />
+ <Key
+ latin:keyLabel="-"
+ latin:keyHintLabel="_"
+ latin:moreKeys="_"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<include
latin:keyboardLayout="@xml/key_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/row_hebrew4.xml b/java/res/xml-sw600dp/row_hebrew4.xml
deleted file mode 100644
index f429f97fb..000000000
--- a/java/res/xml-sw600dp/row_hebrew4.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="9.0%p"
- latin:backgroundType="functional"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyWidth="10.0%p" />
- <include
- latin:keyboardLayout="@xml/key_shortcut" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
- <include
- latin:keyXPos="28.0%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <include
- latin:keyboardLayout="@xml/key_f2" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw600dp/row_pcqwerty5.xml b/java/res/xml-sw600dp/row_pcqwerty5.xml
index 3c4a46660..b854f1051 100644
--- a/java/res/xml-sw600dp/row_pcqwerty5.xml
+++ b/java/res/xml-sw600dp/row_pcqwerty5.xml
@@ -38,9 +38,23 @@
latin:keyStyle="spaceKeyStyle"
latin:keyXPos="25.5%p"
latin:keyWidth="49.0%p" />
- <include
- latin:keyXPos="-9.0%p"
- latin:keyWidth="fillRight"
- latin:keyboardLayout="@xml/key_shortcut" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+ >
+ <include
+ latin:keyXPos="-9.0%p"
+ latin:keyWidth="9.0%p"
+ latin:keyboardLayout="@xml/key_shortcut" />
+ </case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
+ <default>
+ <include
+ latin:keyXPos="-9.0%p"
+ latin:keyWidth="9.0%p"
+ latin:backgroundType="functional"
+ latin:keyboardLayout="@xml/key_f2" />
+ </default>
+ </switch>
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/row_qwerty4.xml b/java/res/xml-sw600dp/row_qwerty4.xml
index fa433635e..7969dd8a5 100644
--- a/java/res/xml-sw600dp/row_qwerty4.xml
+++ b/java/res/xml-sw600dp/row_qwerty4.xml
@@ -34,12 +34,10 @@
latin:keyboardLayout="@xml/key_f1" />
<include
latin:keyXPos="28.0%p"
- latin:keyboardLayout="@xml/key_space"
+ latin:keyboardLayout="@xml/key_space_5kw"
latin:backgroundType="normal" />
<include
- latin:keyboardLayout="@xml/key_apostrophe" />
- <include
- latin:keyboardLayout="@xml/key_dash" />
+ latin:keyboardLayout="@xml/keys_comma_period" />
<include
latin:keyboardLayout="@xml/key_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/row_symbols4.xml b/java/res/xml-sw600dp/row_symbols4.xml
deleted file mode 100644
index f138d8ef4..000000000
--- a/java/res/xml-sw600dp/row_symbols4.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="9.0%p"
- latin:backgroundType="functional"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="10.0%p" />
- <Key
- latin:keyLabel="/" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
- <include
- latin:keyXPos="28.0%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <Key
- latin:keyLabel="&quot;"
- latin:moreKeys="!text/more_keys_for_tablet_double_quote" />
- <Key
- latin:keyLabel="_" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw600dp/row_symbols_shift4.xml b/java/res/xml-sw600dp/row_symbols_shift4.xml
deleted file mode 100644
index 29befa92a..000000000
--- a/java/res/xml-sw600dp/row_symbols_shift4.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="9.0%p"
- latin:backgroundType="functional"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="10.0%p" />
- <!-- Here is empty space. -->
- <include
- latin:keyXPos="28.0%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml b/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml
index b11bbba1b..254d3fdba 100644
--- a/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml
+++ b/java/res/xml-sw600dp/rowkeys_pcqwerty1.xml
@@ -21,93 +21,87 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <switch>
- <case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
- >
- <include
- latin:keyboardLayout="@xml/keys_pcqwerty_symbols1" />
- </case>
- <!-- keyboardLayoutSetElement="alphabet*" -->
- <default>
- <!-- U+00AC: "¬" NOT SIGN -->
- <Key
- latin:keyLabel="`"
- latin:keyHintLabel="~"
- latin:additionalMoreKeys="~"
- latin:moreKeys="&#x00AC;"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <!-- U+00A1: "¡" NVERTED EXCLAMATION MARK -->
- <Key
- latin:keyLabel="1"
- latin:keyHintLabel="!"
- latin:additionalMoreKeys="!"
- latin:moreKeys="&#x00A1;,!text/more_keys_for_symbols_1"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="2"
- latin:keyHintLabel="\@"
- latin:additionalMoreKeys="\@"
- latin:moreKeys="!text/more_keys_for_symbols_2"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="3"
- latin:keyHintLabel="\#"
- latin:additionalMoreKeys="\#"
- latin:moreKeys="!text/more_keys_for_symbols_3"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="4"
- latin:keyHintLabel="$"
- latin:additionalMoreKeys="$"
- latin:moreKeys="!text/more_keys_for_symbols_4"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="5"
- latin:keyHintLabel="%"
- latin:additionalMoreKeys="\\%"
- latin:moreKeys="!text/more_keys_for_symbols_5"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="6"
- latin:keyHintLabel="^"
- latin:additionalMoreKeys="^"
- latin:moreKeys="!text/more_keys_for_symbols_6"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="7"
- latin:keyHintLabel="&amp;"
- latin:additionalMoreKeys="&amp;"
- latin:moreKeys="!text/more_keys_for_symbols_7"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="8"
- latin:keyHintLabel="*"
- latin:additionalMoreKeys="*"
- latin:moreKeys="!text/more_keys_for_symbols_8"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="9"
- latin:keyHintLabel="("
- latin:additionalMoreKeys="("
- latin:moreKeys="!text/more_keys_for_symbols_9"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="0"
- latin:keyHintLabel=")"
- latin:additionalMoreKeys=")"
- latin:moreKeys="!text/more_keys_for_symbols_0"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="-"
- latin:keyHintLabel="_"
- latin:moreKeys="_"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- <Key
- latin:keyLabel="="
- latin:keyHintLabel="+"
- latin:moreKeys="+"
- latin:keyStyle="hasShiftedLetterHintStyle" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="`"
+ latin:keyHintLabel="~"
+ latin:additionalMoreKeys="~"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ <Key
+ latin:keyLabel="1"
+ latin:keyHintLabel="!"
+ latin:additionalMoreKeys="!"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_exclamation,!text/more_keys_for_symbols_1" />
+ <Key
+ latin:keyLabel="2"
+ latin:keyHintLabel="\@"
+ latin:additionalMoreKeys="\@"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_2" />
+ <Key
+ latin:keyLabel="3"
+ latin:keyHintLabel="\#"
+ latin:additionalMoreKeys="\#"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_3" />
+ <Key
+ latin:keyLabel="4"
+ latin:keyHintLabel="$"
+ latin:additionalMoreKeys="$"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_4" />
+ <Key
+ latin:keyLabel="5"
+ latin:keyHintLabel="%"
+ latin:additionalMoreKeys="\\%"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_5" />
+ <Key
+ latin:keyLabel="6"
+ latin:keyHintLabel="^"
+ latin:additionalMoreKeys="^"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_6" />
+ <Key
+ latin:keyLabel="7"
+ latin:keyHintLabel="&amp;"
+ latin:additionalMoreKeys="&amp;"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_7" />
+ <Key
+ latin:keyLabel="8"
+ latin:keyHintLabel="*"
+ latin:additionalMoreKeys="*"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_8" />
+ <Key
+ latin:keyLabel="9"
+ latin:keyHintLabel="("
+ latin:additionalMoreKeys="("
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_9" />
+ <Key
+ latin:keyLabel="0"
+ latin:keyHintLabel=")"
+ latin:additionalMoreKeys=")"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="!text/more_keys_for_symbols_0" />
+ <!-- U+2013: "–" EN DASH
+ U+2014: "—" EM DASH
+ U+00B7: "·" MIDDLE DOT -->
+ <Key
+ latin:keyLabel="-"
+ latin:keyHintLabel="_"
+ latin:additionalMoreKeys="_"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="&#x2013;,&#x2014;,&#x00B7;" />
+ <!-- U+221E: "∞" INFINITY
+ U+2260: "≠" NOT EQUAL TO
+ U+2248: "≈" ALMOST EQUAL TO -->
+ <Key
+ latin:keyLabel="="
+ latin:keyHintLabel="+"
+ latin:additionalMoreKeys="+"
+ latin:keyStyle="hasShiftedLetterHintStyle"
+ latin:moreKeys="&#x221E;,&#x2260;,&#x2248;" />
</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_symbols2.xml b/java/res/xml-sw600dp/rowkeys_symbols2.xml
deleted file mode 100644
index 14abb42f9..000000000
--- a/java/res/xml-sw600dp/rowkeys_symbols2.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:languageCode="fa"
- >
- <!-- U+066C: "٬" ARABIC THOUSANDS SEPARATOR -->
- <Key
- latin:keyLabel="&#x066C;"
- latin:keyHintLabel="&amp;"
- latin:keyLabelFlags="hasPopupHint|hasShiftedLetterHint"
- latin:moreKeys="&amp;" />
- </case>
- <default>
- <Key
- latin:keyLabel="\#" />
- </default>
- </switch>
- <Key
- latin:keyStyle="currencyKeyStyle" />
- <Key
- latin:keyLabel="!text/keylabel_for_symbols_percent"
- latin:moreKeys="!text/more_keys_for_symbols_percent" />
- <switch>
- <case
- latin:languageCode="fa"
- >
- <!-- U+066B: "٫" ARABIC DECIMAL SEPARATOR -->
- <Key
- latin:keyLabel="&#x066B;"
- latin:keyHintLabel="\#"
- latin:keyLabelFlags="hasPopupHint|hasShiftedLetterHint"
- latin:moreKeys="\#" />
- </case>
- <default>
- <Key
- latin:keyLabel="&amp;" />
- </default>
- </switch>
- <Key
- latin:keyLabel="*"
- latin:moreKeys="!text/more_keys_for_star" />
- <!-- U+2013: "–" EN DASH
- U+2014: "—" EM DASH
- U+00B7: "·" MIDDLE DOT -->
- <Key
- latin:keyLabel="-"
- latin:moreKeys="_,&#x2013;,&#x2014;,&#x00B7;" />
- <Key
- latin:keyLabel="+"
- latin:moreKeys="!text/more_keys_for_plus" />
- <include
- latin:keyboardLayout="@xml/keys_parentheses" />
-</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_symbols3.xml b/java/res/xml-sw600dp/rowkeys_symbols3.xml
deleted file mode 100644
index 30fba3812..000000000
--- a/java/res/xml-sw600dp/rowkeys_symbols3.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/keys_less_greater" />
- <!-- U+2260: "≠" NOT EQUAL TO
- U+2248: "≈" ALMOST EQUAL TO -->
- <Key
- latin:keyLabel="="
- latin:moreKeys="&#x2260;,&#x2248;" />
- <switch>
- <case
- latin:mode="url"
- >
- <Key
- latin:keyLabel="\'" />
- </case>
- <default>
- <Key
- latin:keyLabel=":" />
- </default>
- </switch>
- <Key
- latin:keyLabel="!text/keylabel_for_symbols_semicolon"
- latin:moreKeys="!text/more_keys_for_symbols_semicolon" />
- <Key
- latin:keyLabel="!text/keylabel_for_comma"
- latin:moreKeys="!text/more_keys_for_comma" />
- <Key
- latin:keyLabel="." />
- <Key
- latin:keyLabel="!"
- latin:moreKeys="!text/more_keys_for_symbols_exclamation" />
- <Key
- latin:keyLabel="!text/keylabel_for_symbols_question"
- latin:moreKeys="!text/more_keys_for_symbols_question" />
-</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml b/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml
deleted file mode 100644
index 3549fdda4..000000000
--- a/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Key
- latin:keyLabel="~" />
- <Key
- latin:keyLabel="`" />
- <Key
- latin:keyLabel="|" />
- <!-- U+2022: "•" BULLET -->
- <Key
- latin:keyLabel="&#x2022;"
- latin:moreKeys="!text/more_keys_for_bullet" />
- <!-- U+221A: "√" SQUARE ROOT -->
- <Key
- latin:keyLabel="&#x221A;" />
- <!-- U+03C0: "π" GREEK SMALL LETTER PI
- U+03A0: "Π" GREEK CAPITAL LETTER PI -->
- <Key
- latin:keyLabel="&#x03C0;"
- latin:moreKeys="&#x03A0;" />
- <!-- U+00F7: "÷" DIVISION SIGN -->
- <Key
- latin:keyLabel="&#x00F7;" />
- <!-- U+00D7: "×" MULTIPLICATION SIGN -->
- <Key
- latin:keyLabel="&#x00D7;" />
- <!-- U+00A7: "§" SECTION SIGN
- U+00B6: "¶" PILCROW SIGN -->
- <Key
- latin:keyLabel="&#x00A7;"
- latin:moreKeys="&#x00B6;" />
- <!-- U+0394: "Δ" GREEK CAPITAL LETTER DELTA -->
- <Key
- latin:keyLabel="&#x0394;" />
-</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_symbols_shift2.xml b/java/res/xml-sw600dp/rowkeys_symbols_shift2.xml
deleted file mode 100644
index 2048b7335..000000000
--- a/java/res/xml-sw600dp/rowkeys_symbols_shift2.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Key
- latin:keyStyle="moreCurrency1KeyStyle" />
- <Key
- latin:keyStyle="moreCurrency2KeyStyle" />
- <Key
- latin:keyStyle="moreCurrency3KeyStyle" />
- <Key
- latin:keyStyle="moreCurrency4KeyStyle" />
- <!-- U+2191: "↑" UPWARDS ARROW
- U+2193: "↓" DOWNWARDS ARROW
- U+2190: "←" LEFTWARDS ARROW
- U+2192: "→" RIGHTWARDS ARROW -->
- <Key
- latin:keyLabel="^"
- latin:moreKeys="&#x2191;,&#x2193;,&#x2190;,&#x2192;" />
- <!-- U+00B0: "°" DEGREE SIGN
- U+2032: "′" PRIME
- U+2033: "″" DOUBLE PRIME -->
- <Key
- latin:keyLabel="&#x00B0;"
- latin:moreKeys="&#x2032;,&#x2033;" />
- <!-- U+00B1: "±" PLUS-MINUS SIGN
- U+221E: "∞" INFINITY -->
- <Key
- latin:keyLabel="&#x00B1;"
- latin:moreKeys="&#x221E;" />
- <include
- latin:keyboardLayout="@xml/keys_curly_brackets" />
-</merge>
diff --git a/java/res/xml-sw600dp/rowkeys_symbols_shift3.xml b/java/res/xml-sw600dp/rowkeys_symbols_shift3.xml
deleted file mode 100644
index 8bd865639..000000000
--- a/java/res/xml-sw600dp/rowkeys_symbols_shift3.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Key
- latin:keyLabel="\\" />
- <!-- U+00A9: "©" COPYRIGHT SIGN -->
- <Key
- latin:keyLabel="&#x00A9;" />
- <!-- U+00AE: "®" REGISTERED SIGN -->
- <Key
- latin:keyLabel="&#x00AE;" />
- <!-- U+2122: "™" TRADE MARK SIGN -->
- <Key
- latin:keyLabel="&#x2122;" />
- <!-- U+2105: "℅" CARE OF -->
- <Key
- latin:keyLabel="&#x2105;" />
- <include
- latin:keyboardLayout="@xml/keys_square_brackets" />
- <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK -->
- <Key
- latin:keyLabel="&#x00A1;" />
- <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
- <Key
- latin:keyLabel="&#x00BF;" />
-</merge>
diff --git a/java/res/xml-sw600dp/rows_10_10_7_symbols_shift.xml b/java/res/xml-sw600dp/rows_10_10_7_symbols_shift.xml
deleted file mode 100644
index 3d3b59f22..000000000
--- a/java/res/xml-sw600dp/rows_10_10_7_symbols_shift.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="9.0%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="9.0%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="9.0%p"
- >
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="10.0%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift3" />
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols_shift4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_colemak.xml b/java/res/xml-sw600dp/rows_armenian_phonetic.xml
index 073f812e5..9bc2a1821 100644
--- a/java/res/xml-sw768dp/rows_colemak.xml
+++ b/java/res/xml-sw600dp/rows_armenian_phonetic.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2010, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -24,43 +24,43 @@
<include
latin:keyboardLayout="@xml/key_styles_common" />
<Row
- latin:keyWidth="8.282%p"
+ latin:keyWidth="9.0%p"
>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_colemak1" />
<include
- latin:keyboardLayout="@xml/key_colemak_colon" />
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic1" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="9.0%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic2" />
+ <include
+ latin:keyboardLayout="@xml/key_armenian_xeh" />
</Row>
<Row
- latin:keyWidth="8.125%p"
+ latin:keyWidth="9.0%p"
>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_colemak2" />
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic3" />
+ <include
+ latin:keyboardLayout="@xml/key_armenian_sha" />
<Key
latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="8.047%p"
+ latin:keyWidth="8.8889%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
+ latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_colemak3" />
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic4" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_azerty.xml b/java/res/xml-sw600dp/rows_azerty.xml
index 5a5a7d12f..cdc91857f 100644
--- a/java/res/xml-sw600dp/rows_azerty.xml
+++ b/java/res/xml-sw600dp/rows_azerty.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_azerty3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_bulgarian.xml b/java/res/xml-sw600dp/rows_bulgarian.xml
index 263562095..c73aa1c1a 100644
--- a/java/res/xml-sw600dp/rows_bulgarian.xml
+++ b/java/res/xml-sw600dp/rows_bulgarian.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_bulgarian3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_bulgarian_bds.xml b/java/res/xml-sw600dp/rows_bulgarian_bds.xml
index 9439a6346..bc773ee58 100644
--- a/java/res/xml-sw600dp/rows_bulgarian_bds.xml
+++ b/java/res/xml-sw600dp/rows_bulgarian_bds.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_bulgarian_bds3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw600dp/rows_colemak.xml b/java/res/xml-sw600dp/rows_colemak.xml
index 98a24e451..ab059da83 100644
--- a/java/res/xml-sw600dp/rows_colemak.xml
+++ b/java/res/xml-sw600dp/rows_colemak.xml
@@ -52,7 +52,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_colemak3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_east_slavic.xml b/java/res/xml-sw600dp/rows_east_slavic.xml
index b4160d64b..c5045fffc 100644
--- a/java/res/xml-sw600dp/rows_east_slavic.xml
+++ b/java/res/xml-sw600dp/rows_east_slavic.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_east_slavic3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw600dp/rows_georgian.xml b/java/res/xml-sw600dp/rows_georgian.xml
index b0e9e35fd..891cbc109 100644
--- a/java/res/xml-sw600dp/rows_georgian.xml
+++ b/java/res/xml-sw600dp/rows_georgian.xml
@@ -51,7 +51,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_georgian3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_greek.xml b/java/res/xml-sw600dp/rows_greek.xml
index de214c67f..066dc47fb 100644
--- a/java/res/xml-sw600dp/rows_greek.xml
+++ b/java/res/xml-sw600dp/rows_greek.xml
@@ -53,7 +53,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_greek3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_hebrew.xml b/java/res/xml-sw600dp/rows_hebrew.xml
index 9945dee35..852e17683 100644
--- a/java/res/xml-sw600dp/rows_hebrew.xml
+++ b/java/res/xml-sw600dp/rows_hebrew.xml
@@ -49,5 +49,5 @@
latin:keyXPos="10.0%p" />
</Row>
<include
- latin:keyboardLayout="@xml/row_hebrew4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/rows_hindi.xml b/java/res/xml-sw600dp/rows_hindi.xml
index 2a9a419f8..ca581be14 100644
--- a/java/res/xml-sw600dp/rows_hindi.xml
+++ b/java/res/xml-sw600dp/rows_hindi.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_hindi3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw768dp/rows_azerty.xml b/java/res/xml-sw600dp/rows_khmer.xml
index cf4bc92fa..2824a5c2f 100644
--- a/java/res/xml-sw768dp/rows_azerty.xml
+++ b/java/res/xml-sw600dp/rows_khmer.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2010, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -24,44 +24,48 @@
<include
latin:keyboardLayout="@xml/key_styles_common" />
<Row
- latin:keyWidth="8.282%p"
+ latin:keyWidth="7.5%p"
>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_azerty1" />
+ latin:keyboardLayout="@xml/rowkeys_khmer1" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="7.5%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer2" />
</Row>
<Row
- latin:keyWidth="8.125%p"
+ latin:keyWidth="7.5%p"
>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_azerty2" />
+ latin:keyboardLayout="@xml/rowkeys_khmer3" />
<Key
latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="8.047%p"
+ latin:keyWidth="7.5%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
+ latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_azerty3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_khmer4" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Spacer />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </default>
+ </switch>
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw768dp/rows_georgian.xml b/java/res/xml-sw600dp/rows_lao.xml
index 3f8bd4569..446d9bd5a 100644
--- a/java/res/xml-sw768dp/rows_georgian.xml
+++ b/java/res/xml-sw600dp/rows_lao.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -24,44 +24,48 @@
<include
latin:keyboardLayout="@xml/key_styles_common" />
<Row
- latin:keyWidth="8.282%p"
+ latin:keyWidth="7.5%p"
>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_georgian1" />
+ latin:keyboardLayout="@xml/rowkeys_lao1" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"/>
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="7.5%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_lao2" />
</Row>
<Row
- latin:keyWidth="8.125%p"
+ latin:keyWidth="7.5%p"
>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p"/>
<include
- latin:keyboardLayout="@xml/rowkeys_georgian2" />
+ latin:keyboardLayout="@xml/rowkeys_lao3" />
<Key
latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="8.047%p"
+ latin:keyWidth="7.5%p"
>
<Key
latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_georgian3" />
+ latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_lao4" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Spacer />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </default>
+ </switch>
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw600dp/rows_mongolian.xml b/java/res/xml-sw600dp/rows_mongolian.xml
index dc0c1fe5c..8e39e625a 100644
--- a/java/res/xml-sw600dp/rows_mongolian.xml
+++ b/java/res/xml-sw600dp/rows_mongolian.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_mongolian3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw600dp/rows_10_10_7_symbols.xml b/java/res/xml-sw600dp/rows_nepali_romanized.xml
index 0e4710c37..21d1dc6e0 100644
--- a/java/res/xml-sw600dp/rows_10_10_7_symbols.xml
+++ b/java/res/xml-sw600dp/rows_nepali_romanized.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -23,38 +23,35 @@
>
<include
latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
<Row
- latin:keyWidth="9.0%p"
+ latin:keyWidth="8.182%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_symbols1" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_romanized1" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="9.0%p"
+ latin:keyWidth="8.182%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_symbols2" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_romanized2" />
<Key
latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="9.0%p"
+ latin:keyWidth="8.182%p"
>
<Key
- latin:keyStyle="toMoreSymbolKeyStyle"
+ latin:keyStyle="shiftKeyStyle"
latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_symbols3" />
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_romanized3" />
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
</Row>
<include
- latin:keyboardLayout="@xml/row_symbols4" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw768dp/rows_farsi.xml b/java/res/xml-sw600dp/rows_nepali_traditional.xml
index 8d3fb0579..90703da76 100644
--- a/java/res/xml-sw768dp/rows_farsi.xml
+++ b/java/res/xml-sw600dp/rows_nepali_traditional.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -24,38 +24,34 @@
<include
latin:keyboardLayout="@xml/key_styles_common" />
<Row
- latin:keyWidth="7.375%p"
+ latin:keyWidth="8.182%p"
>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_farsi1" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional1" />
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="7.227%p"
+ latin:keyWidth="8.182%p"
>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_farsi2" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional2" />
<Key
latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
<Row
- latin:keyWidth="7.227%p"
+ latin:keyWidth="8.182%p"
>
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_farsi3"
- latin:keyXPos="13.829%p" />
- </Row>
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_left6" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_right5" />
+ </Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml-sw600dp/rows_nordic.xml b/java/res/xml-sw600dp/rows_nordic.xml
index 299bf8908..56fa4066f 100644
--- a/java/res/xml-sw600dp/rows_nordic.xml
+++ b/java/res/xml-sw600dp/rows_nordic.xml
@@ -52,7 +52,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_qwerty3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyXPos="-10.0%p"
diff --git a/java/res/xml-sw600dp/rows_pcqwerty.xml b/java/res/xml-sw600dp/rows_pcqwerty.xml
index fa6080a19..8714815ef 100644
--- a/java/res/xml-sw600dp/rows_pcqwerty.xml
+++ b/java/res/xml-sw600dp/rows_pcqwerty.xml
@@ -26,8 +26,19 @@
<Row
latin:keyWidth="7.0%p"
>
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
+ </case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
+ <default>
+ <include
+ latin:keyboardLayout="@xml/rowkeys_pcqwerty1_shift" />
+ </default>
+ </switch>
<Key
latin:keyStyle="deleteKeyStyle"
latin:keyWidth="fillRight" />
@@ -44,9 +55,7 @@
<Row
latin:keyWidth="7.0%p"
>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabel="!text/label_to_symbol_key_pcqwerty"
+ <Spacer
latin:keyWidth="12.0%p" />
<include
latin:keyboardLayout="@xml/rowkeys_pcqwerty3" />
diff --git a/java/res/xml-sw600dp/rows_qwerty.xml b/java/res/xml-sw600dp/rows_qwerty.xml
index 722f9d138..58ba1d713 100644
--- a/java/res/xml-sw600dp/rows_qwerty.xml
+++ b/java/res/xml-sw600dp/rows_qwerty.xml
@@ -51,7 +51,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_qwerty3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_qwertz.xml b/java/res/xml-sw600dp/rows_qwertz.xml
index f2f832ce7..3b59dec54 100644
--- a/java/res/xml-sw600dp/rows_qwertz.xml
+++ b/java/res/xml-sw600dp/rows_qwertz.xml
@@ -51,7 +51,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_qwertz3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_south_slavic.xml b/java/res/xml-sw600dp/rows_south_slavic.xml
index 6ef664342..5053988cc 100644
--- a/java/res/xml-sw600dp/rows_south_slavic.xml
+++ b/java/res/xml-sw600dp/rows_south_slavic.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_south_slavic3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw600dp/rows_spanish.xml b/java/res/xml-sw600dp/rows_spanish.xml
index bca9bba3a..1092c268e 100644
--- a/java/res/xml-sw600dp/rows_spanish.xml
+++ b/java/res/xml-sw600dp/rows_spanish.xml
@@ -50,7 +50,7 @@
<include
latin:keyboardLayout="@xml/rowkeys_qwerty3" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
<Key
latin:keyStyle="shiftKeyStyle"
latin:keyWidth="fillRight" />
diff --git a/java/res/xml-sw600dp/rows_symbols.xml b/java/res/xml-sw600dp/rows_symbols.xml
index 3d0593dab..fbd8492cd 100644
--- a/java/res/xml-sw600dp/rows_symbols.xml
+++ b/java/res/xml-sw600dp/rows_symbols.xml
@@ -50,12 +50,23 @@
<Key
latin:keyStyle="toMoreSymbolKeyStyle"
latin:keyWidth="10.0%p" />
+ <Key
+ latin:keyLabel="\\" />
+ <Key
+ latin:keyLabel="=" />
<include
latin:keyboardLayout="@xml/rowkeys_symbols3" />
<Key
latin:keyStyle="toMoreSymbolKeyStyle"
latin:keyWidth="fillRight" />
</Row>
- <include
- latin:keyboardLayout="@xml/row_symbols4" />
+ <Row
+ latin:keyWidth="9.0%p"
+ >
+ <Key
+ latin:keyStyle="toAlphaKeyStyle"
+ latin:keyWidth="10.0%p" />
+ <include
+ latin:keyboardLayout="@xml/row_symbols4" />
+ </Row>
</merge>
diff --git a/java/res/xml-sw600dp/rows_symbols_shift.xml b/java/res/xml-sw600dp/rows_symbols_shift.xml
index 0050c0c15..aad047ff6 100644
--- a/java/res/xml-sw600dp/rows_symbols_shift.xml
+++ b/java/res/xml-sw600dp/rows_symbols_shift.xml
@@ -52,10 +52,23 @@
latin:keyWidth="10.0%p" />
<include
latin:keyboardLayout="@xml/rowkeys_symbols_shift3" />
+ <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK -->
+ <Key
+ latin:keyLabel="&#x00A1;" />
+ <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
+ <Key
+ latin:keyLabel="&#x00BF;" />
<Key
latin:keyStyle="backFromMoreSymbolKeyStyle"
latin:keyWidth="fillRight" />
</Row>
- <include
- latin:keyboardLayout="@xml/row_symbols_shift4" />
+ <Row
+ latin:keyWidth="9.0%p"
+ >
+ <Key
+ latin:keyStyle="toAlphaKeyStyle"
+ latin:keyWidth="10%p" />
+ <include
+ latin:keyboardLayout="@xml/row_symbols_shift4" />
+ </Row>
</merge>
diff --git a/java/res/xml-sw600dp/rows_thai.xml b/java/res/xml-sw600dp/rows_thai.xml
index bc89640ac..7738c7f04 100644
--- a/java/res/xml-sw600dp/rows_thai.xml
+++ b/java/res/xml-sw600dp/rows_thai.xml
@@ -59,8 +59,17 @@
latin:keyWidth="10.0%p" />
<include
latin:keyboardLayout="@xml/rowkeys_thai4" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Spacer />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </default>
+ </switch>
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw768dp-land/kbd_phone_symbols.xml b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
deleted file mode 100644
index 6038b1f1e..000000000
--- a/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLeftPadding="10%p"
- latin:keyboardRightPadding="10%p"
- latin:keyWidth="13.250%p"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
->
- <!-- Tablet doesn't have phone symbols keyboard -->
- <include
- latin:keyboardLayout="@xml/rows_phone" />
-</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_number.xml b/java/res/xml-sw768dp/kbd_number.xml
deleted file mode 100644
index 1b46edd50..000000000
--- a/java/res/xml-sw768dp/kbd_number.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="13.250%p"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
->
- <include
- latin:keyboardLayout="@xml/rows_number" />
-</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_phone.xml b/java/res/xml-sw768dp/kbd_phone.xml
deleted file mode 100644
index 947ede050..000000000
--- a/java/res/xml-sw768dp/kbd_phone.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="13.250%p"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
->
- <include
- latin:keyboardLayout="@xml/rows_phone" />
-</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_phone_symbols.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml
deleted file mode 100644
index dd9a6aebd..000000000
--- a/java/res/xml-sw768dp/kbd_phone_symbols.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.
-*/
--->
-
-<Keyboard
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyWidth="13.250%p"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
->
- <!-- Tablet doesn't have phone symbols keyboard -->
- <include
- latin:keyboardLayout="@xml/rows_phone" />
-</Keyboard>
diff --git a/java/res/xml-sw768dp/key_space.xml b/java/res/xml-sw768dp/key_space.xml
deleted file mode 100644
index 58e71d807..000000000
--- a/java/res/xml-sw768dp/key_space.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:languageCode="fa"
- latin:languageSwitchKeyEnabled="true"
- >
- <Key
- latin:keyStyle="languageSwitchKeyStyle" />
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="24.141%p" />
- <Key
- latin:keyStyle="zwnjKeyStyle" />
- </case>
- <case
- latin:languageCode="fa"
- latin:languageSwitchKeyEnabled="false"
- >
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="32.188%p" />
- <Key
- latin:keyStyle="zwnjKeyStyle" />
- </case>
- <case
- latin:languageSwitchKeyEnabled="true"
- >
- <Key
- latin:keyStyle="languageSwitchKeyStyle" />
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="32.188%p" />
- </case>
- <!-- languageSwitchKeyEnabled="false" -->
- <default>
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="40.235%p" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml-sw768dp/key_styles_common.xml b/java/res/xml-sw768dp/key_styles_common.xml
deleted file mode 100644
index 7c0a82a71..000000000
--- a/java/res/xml-sw768dp/key_styles_common.xml
+++ /dev/null
@@ -1,186 +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:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
- >
- <key-style
- latin:styleName="hasShiftedLetterHintStyle"
- latin:keyLabelFlags="hasShiftedLetterHint|shiftedLetterActivated" />
- </case>
- <default>
- <key-style
- latin:styleName="hasShiftedLetterHintStyle"
- latin:keyLabelFlags="hasShiftedLetterHint" />
- </default>
- </switch>
- <!-- Base style for shift key. A single space is used for dummy label in moreKeys. -->
- <key-style
- latin:styleName="baseForShiftKeyStyle"
- latin:code="!code/key_shift"
- latin:keyActionFlags="noKeyPreview"
- latin:keyLabelFlags="preserveCase"
- latin:moreKeys="!noPanelAutoMoreKey!, |!code/key_capslock" />
- <switch>
- <case
- latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetAutomaticShifted"
- >
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:keyIcon="!icon/shift_key_shifted"
- latin:backgroundType="stickyOff"
- latin:parentStyle="baseForShiftKeyStyle" />
- </case>
- <case
- latin:keyboardLayoutSetElement="alphabetShiftLocked|alphabetShiftLockShifted"
- >
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:keyIcon="!icon/shift_key_shifted"
- latin:backgroundType="stickyOn"
- latin:parentStyle="baseForShiftKeyStyle" />
- </case>
- <default>
- <key-style
- latin:styleName="shiftKeyStyle"
- latin:keyIcon="!icon/shift_key"
- latin:backgroundType="stickyOff"
- latin:parentStyle="baseForShiftKeyStyle" />
- </default>
- </switch>
- <key-style
- latin:styleName="deleteKeyStyle"
- latin:code="!code/key_delete"
- latin:keyIcon="!icon/delete_key"
- latin:keyActionFlags="isRepeatable|noKeyPreview"
- latin:backgroundType="functional" />
- <include
- latin:keyboardLayout="@xml/key_styles_enter" />
- <key-style
- latin:styleName="spaceKeyStyle"
- latin:code="!code/key_space"
- latin:keyActionFlags="noKeyPreview|enableLongPress" />
- <!-- U+200C: ZERO WIDTH NON-JOINER
- U+200D: ZERO WIDTH JOINER -->
- <key-style
- latin:styleName="zwnjKeyStyle"
- latin:code="0x200C"
- latin:keyIcon="!icon/zwnj_key"
- latin:moreKeys="!icon/zwj_key|&#x200D;"
- latin:keyLabelFlags="hasPopupHint"
- latin:keyActionFlags="noKeyPreview" />
- <key-style
- latin:styleName="smileyKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/more_keys_for_smiley" />
- <key-style
- latin:styleName="shortcutKeyStyle"
- latin:code="!code/key_shortcut"
- latin:keyIcon="!icon/shortcut_key"
- latin:keyIconDisabled="!icon/shortcut_key_disabled"
- latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="functional" />
- <key-style
- latin:styleName="languageSwitchKeyStyle"
- latin:code="!code/key_language_switch"
- latin:keyIcon="!icon/language_switch_key"
- latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
- latin:altCode="!code/key_space" />
- <key-style
- latin:styleName="emojiKeyStyle"
- latin:code="!code/key_emoji"
- latin:keyIcon="!icon/emoji_key"
- latin:keyActionFlags="noKeyPreview" />
- <key-style
- latin:styleName="settingsKeyStyle"
- latin:code="!code/key_settings"
- latin:keyIcon="!icon/settings_key"
- latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="functional" />
- <switch>
- <case
- latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
- latin:navigatePrevious="true"
- >
- <key-style
- latin:styleName="tabKeyStyle"
- latin:code="!code/key_action_previous"
- latin:keyLabel="!text/label_tab_key"
- latin:keyLabelFlags="fontNormal|preserveCase"
- latin:backgroundType="functional" />
- </case>
- <case
- latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted|alphabetShiftLocked"
- latin:navigateNext="true"
- >
- <key-style
- latin:styleName="tabKeyStyle"
- latin:code="!code/key_action_next"
- latin:keyLabel="!text/label_tab_key"
- latin:keyLabelFlags="fontNormal|preserveCase"
- latin:backgroundType="functional" />
- </case>
- <default>
- <key-style
- latin:styleName="tabKeyStyle"
- latin:code="!code/key_tab"
- latin:keyLabel="!text/label_tab_key"
- latin:keyLabelFlags="fontNormal|preserveCase"
- latin:backgroundType="functional" />
- </default>
- </switch>
- <key-style
- latin:styleName="baseForLayoutSwitchKeyStyle"
- latin:keyLabelFlags="fontNormal|preserveCase"
- latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="functional" />
- <key-style
- latin:styleName="toSymbolKeyStyle"
- latin:code="!code/key_switch_alpha_symbol"
- latin:keyLabel="!text/label_to_symbol_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="toAlphaKeyStyle"
- latin:code="!code/key_switch_alpha_symbol"
- latin:keyLabel="!text/label_to_alpha_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="toMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_more_symbol_for_tablet_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="backFromMoreSymbolKeyStyle"
- latin:code="!code/key_shift"
- latin:keyLabel="!text/label_to_symbol_key"
- latin:parentStyle="baseForLayoutSwitchKeyStyle" />
- <key-style
- latin:styleName="comKeyStyle"
- latin:keyLabel="!text/keylabel_for_popular_domain"
- latin:keyLabelFlags="fontNormal|hasPopupHint|preserveCase"
- latin:keyOutputText="!text/keylabel_for_popular_domain"
- latin:moreKeys="!text/more_keys_for_popular_domain" />
-</merge>
diff --git a/java/res/xml-sw768dp/row_dvorak4.xml b/java/res/xml-sw768dp/row_dvorak4.xml
deleted file mode 100644
index 8f9230d4a..000000000
--- a/java/res/xml-sw768dp/row_dvorak4.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional"
- >
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="5.782%p" />
- <include
- latin:keyboardLayout="@xml/key_settings" />
- <include
- latin:keyboardLayout="@xml/key_shortcut" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
- <include
- latin:keyXPos="29.923%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <include
- latin:keyboardLayout="@xml/key_question_exclamation" />
- <include
- latin:keyboardLayout="@xml/key_dash" />
- <include
- latin:keyboardLayout="@xml/key_f2" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/row_hebrew4.xml b/java/res/xml-sw768dp/row_hebrew4.xml
deleted file mode 100644
index ae14f0296..000000000
--- a/java/res/xml-sw768dp/row_hebrew4.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional"
- >
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="5.782%p" />
- <include
- latin:keyboardLayout="@xml/key_settings" />
- <include
- latin:keyboardLayout="@xml/key_shortcut" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
- <include
- latin:keyXPos="29.923%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <include
- latin:keyboardLayout="@xml/key_f2" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/row_pcqwerty5.xml b/java/res/xml-sw768dp/row_pcqwerty5.xml
deleted file mode 100644
index e27ec878b..000000000
--- a/java/res/xml-sw768dp/row_pcqwerty5.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="8.047%p"
- >
- <include
- latin:keyboardLayout="@xml/key_settings" />
- <switch>
- <case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
- >
- <Spacer
- latin:keyXPos="15.0%p"
- latin:keyWidth="10.5%p" />
- </case>
- <case
- latin:mode="email|url"
- >
- <Key
- latin:keyStyle="comKeyStyle"
- latin:keyXPos="15.0%p"
- latin:keyWidth="10.5%p" />
- </case>
- <default>
- <Spacer
- latin:keyXPos="15.0%p"
- latin:keyWidth="10.5%p" />
- </default>
- </switch>
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="49.0%p" />
- <include
- latin:keyXPos="-8.047%p"
- latin:keyWidth="fillRight"
- latin:keyboardLayout="@xml/key_shortcut" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/row_qwerty4.xml b/java/res/xml-sw768dp/row_qwerty4.xml
deleted file mode 100644
index f1f4214ca..000000000
--- a/java/res/xml-sw768dp/row_qwerty4.xml
+++ /dev/null
@@ -1,51 +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"
->
- <Row
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional"
- >
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="5.782%p" />
- <include
- latin:keyboardLayout="@xml/key_settings" />
- <include
- latin:keyboardLayout="@xml/key_shortcut" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
- <include
- latin:keyXPos="29.923%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <include
- latin:keyboardLayout="@xml/key_apostrophe" />
- <include
- latin:keyboardLayout="@xml/key_dash" />
- <include
- latin:keyboardLayout="@xml/key_f2" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/row_symbols4.xml b/java/res/xml-sw768dp/row_symbols4.xml
deleted file mode 100644
index b801a12a7..000000000
--- a/java/res/xml-sw768dp/row_symbols4.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional"
- >
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyLabel="/" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
- <include
- latin:keyXPos="29.923%p"
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <Key
- latin:keyLabel="&quot;"
- latin:moreKeys="!text/more_keys_for_tablet_double_quote" />
- <Key
- latin:keyLabel="_" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/row_symbols_shift4.xml b/java/res/xml-sw768dp/row_symbols_shift4.xml
deleted file mode 100644
index f71864bc3..000000000
--- a/java/res/xml-sw768dp/row_symbols_shift4.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional"
- >
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="29.923%p" />
- <include
- latin:keyboardLayout="@xml/key_space"
- latin:backgroundType="normal" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/rows_10_10_7_symbols.xml b/java/res/xml-sw768dp/rows_10_10_7_symbols.xml
deleted file mode 100644
index d9b0d2383..000000000
--- a/java/res/xml-sw768dp/rows_10_10_7_symbols.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols3" />
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_10_10_7_symbols_shift.xml b/java/res/xml-sw768dp/rows_10_10_7_symbols_shift.xml
deleted file mode 100644
index a317dbf84..000000000
--- a/java/res/xml-sw768dp/rows_10_10_7_symbols_shift.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift3" />
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols_shift4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_bulgarian.xml b/java/res/xml-sw768dp/rows_bulgarian.xml
deleted file mode 100644
index bdc1262f3..000000000
--- a/java/res/xml-sw768dp/rows_bulgarian.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.375%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_bulgarian1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_bulgarian2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.186%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_bulgarian3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_bulgarian_bds.xml b/java/res/xml-sw768dp/rows_bulgarian_bds.xml
deleted file mode 100644
index 58c46113e..000000000
--- a/java/res/xml-sw768dp/rows_bulgarian_bds.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.375%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_bulgarian_bds1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_bulgarian_bds2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_bulgarian_bds3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_dvorak.xml b/java/res/xml-sw768dp/rows_dvorak.xml
deleted file mode 100644
index 60d5dd604..000000000
--- a/java/res/xml-sw768dp/rows_dvorak.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_dvorak1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_dvorak2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_dvorak3" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_dvorak4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_east_slavic.xml b/java/res/xml-sw768dp/rows_east_slavic.xml
deleted file mode 100644
index 420307d3e..000000000
--- a/java/res/xml-sw768dp/rows_east_slavic.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_east_slavic1" />
- <Key
- latin:keyLabel="!text/keylabel_for_east_slavic_row1_12" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_east_slavic2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_east_slavic3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_greek.xml b/java/res/xml-sw768dp/rows_greek.xml
deleted file mode 100644
index 9e1e00b73..000000000
--- a/java/res/xml-sw768dp/rows_greek.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/key_greek_semicolon" />
- <include
- latin:keyboardLayout="@xml/rowkeys_greek1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"/>
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_greek2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_greek3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_hebrew.xml b/java/res/xml-sw768dp/rows_hebrew.xml
deleted file mode 100644
index a5f6dfe09..000000000
--- a/java/res/xml-sw768dp/rows_hebrew.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_hebrew1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_hebrew2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_hebrew3"
- latin:keyXPos="13.829%p" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_hebrew4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_hindi.xml b/java/res/xml-sw768dp/rows_hindi.xml
deleted file mode 100644
index 6baf09e10..000000000
--- a/java/res/xml-sw768dp/rows_hindi.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.375%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_hindi1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_hindi2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_hindi3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_mongolian.xml b/java/res/xml-sw768dp/rows_mongolian.xml
deleted file mode 100644
index 5f37f8773..000000000
--- a/java/res/xml-sw768dp/rows_mongolian.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.375%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_mongolian1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_mongolian2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_mongolian3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_nordic.xml b/java/res/xml-sw768dp/rows_nordic.xml
deleted file mode 100644
index 13d9399e8..000000000
--- a/java/res/xml-sw768dp/rows_nordic.xml
+++ /dev/null
@@ -1,71 +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"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.375%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_nordic1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_nordic2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <Spacer
- latin:keyWidth="3.689%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_number_normal.xml b/java/res/xml-sw768dp/rows_number_normal.xml
deleted file mode 100644
index de49aba91..000000000
--- a/java/res/xml-sw768dp/rows_number_normal.xml
+++ /dev/null
@@ -1,175 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="+"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="1"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="2"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="3"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="/"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <switch>
- <case
- latin:mode="time|datetime"
- >
- <Key
- latin:keyLabel=","
- latin:keyLabelFlags="hasPopupHint"
- latin:moreKeys="!text/more_keys_for_am_pm"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- </case>
- <default>
- <Key
- latin:keyLabel=","
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- </default>
- </switch>
- <Key
- latin:keyLabel="4"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="5"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="6"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyLabel="("
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel=")"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <switch>
- <case
- latin:mode="time|datetime"
- >
- <Key
- latin:keyLabel=":"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- </case>
- <default>
- <Key
- latin:keyLabel="="
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- </default>
- </switch>
- <Key
- latin:keyLabel="7"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="8"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="9"
- latin:keyStyle="numKeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer />
- </Row>
- <Row>
- <include
- latin:keyboardLayout="@xml/key_settings"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="24.140%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyLabel="0"
- latin:keyStyle="numKeyStyle" />
- <Key
- latin:keyLabel="\#"
- latin:keyStyle="numKeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer
- latin:keyWidth="fillRight" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/rows_number_password.xml b/java/res/xml-sw768dp/rows_number_password.xml
deleted file mode 100644
index cfa221491..000000000
--- a/java/res/xml-sw768dp/rows_number_password.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row>
- <Key
- latin:keyStyle="numTabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyStyle="num1KeyStyle"
- latin:keyXPos="32.076%p" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="32.076%p" />
- <Key
- latin:keyStyle="num4KeyStyle" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="32.076%p" />
- <Key
- latin:keyStyle="num7KeyStyle" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer />
- </Row>
- <Row>
- <include
- latin:keyboardLayout="@xml/key_settings"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyXPos="45.326%p"
- latin:keyStyle="num0KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/rows_pcqwerty.xml b/java/res/xml-sw768dp/rows_pcqwerty.xml
deleted file mode 100644
index a8447288f..000000000
--- a/java/res/xml-sw768dp/rows_pcqwerty.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.0%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.0%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="9.0%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty2" />
- </Row>
- <Row
- latin:keyWidth="7.0%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabel="!text/label_to_symbol_key_pcqwerty"
- latin:keyWidth="12.0%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty3" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.0%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="15.0%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty4" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_pcqwerty5" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_pcqwerty_symbols.xml b/java/res/xml-sw768dp/rows_pcqwerty_symbols.xml
deleted file mode 100644
index 956da97fb..000000000
--- a/java/res/xml-sw768dp/rows_pcqwerty_symbols.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="7.0%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.0%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="9.0%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty2" />
- </Row>
- <Row
- latin:keyWidth="7.0%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="12.0%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty3" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.0%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty4"
- latin:keyXPos="15.0%p" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_pcqwerty5" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_phone.xml b/java/res/xml-sw768dp/rows_phone.xml
deleted file mode 100644
index d06a63b2c..000000000
--- a/java/res/xml-sw768dp/rows_phone.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_number" />
- <Row>
- <Key
- latin:keyStyle="numTabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <Key
- latin:keyLabel="-"
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="+"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="numPauseKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="num1KeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num2KeyStyle" />
- <Key
- latin:keyStyle="num3KeyStyle" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyLabel=","
- latin:keyStyle="numKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="."
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="numWaitKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="num4KeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num5KeyStyle" />
- <Key
- latin:keyStyle="num6KeyStyle" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyXPos="-11.172%p"
- latin:keyWidth="fillRight" />
- </Row>
- <Row>
- <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
- <Spacer
- latin:keyWidth="13.829%p" />
- <Key
- latin:keyLabel="("
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel=")"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyLabel="N"
- latin:keyStyle="numKeyStyle"
- latin:keyWidth="8.047%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="num7KeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num8KeyStyle" />
- <Key
- latin:keyStyle="num9KeyStyle" />
- <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
- <Spacer />
- </Row>
- <Row>
- <include
- latin:keyboardLayout="@xml/key_settings"
- latin:keyWidth="8.047%p" />
- <Key
- latin:keyStyle="spaceKeyStyle"
- latin:keyXPos="13.829%p"
- latin:keyWidth="24.140%p"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="numStarKeyStyle"
- latin:keyXPos="43.125%p" />
- <Key
- latin:keyStyle="num0KeyStyle" />
- <Key
- latin:keyLabel="\#"
- latin:keyStyle="numKeyStyle" />
- </Row>
-</merge>
diff --git a/java/res/xml-sw768dp/rows_qwerty.xml b/java/res/xml-sw768dp/rows_qwerty.xml
deleted file mode 100644
index 8af18ed72..000000000
--- a/java/res/xml-sw768dp/rows_qwerty.xml
+++ /dev/null
@@ -1,68 +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"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"/>
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_qwertz.xml b/java/res/xml-sw768dp/rows_qwertz.xml
deleted file mode 100644
index 0dd206d45..000000000
--- a/java/res/xml-sw768dp/rows_qwertz.xml
+++ /dev/null
@@ -1,68 +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"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_qwertz1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"/>
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_qwertz3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_south_slavic.xml b/java/res/xml-sw768dp/rows_south_slavic.xml
deleted file mode 100644
index 6b44c4e6a..000000000
--- a/java/res/xml-sw768dp/rows_south_slavic.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.375%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_south_slavic1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.227%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_south_slavic2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.000%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_south_slavic3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_spanish.xml b/java/res/xml-sw768dp/rows_spanish.xml
deleted file mode 100644
index 4520c100d..000000000
--- a/java/res/xml-sw768dp/rows_spanish.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"/>
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="10.167%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_spanish2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty3" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_symbols.xml b/java/res/xml-sw768dp/rows_symbols.xml
deleted file mode 100644
index efd77352b..000000000
--- a/java/res/xml-sw768dp/rows_symbols.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols3" />
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_symbols_shift.xml b/java/res/xml-sw768dp/rows_symbols_shift.xml
deleted file mode 100644
index fd1b93d51..000000000
--- a/java/res/xml-sw768dp/rows_symbols_shift.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift3" />
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols_shift4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_thai.xml b/java/res/xml-sw768dp/rows_thai.xml
deleted file mode 100644
index 5f9b383f8..000000000
--- a/java/res/xml-sw768dp/rows_thai.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <Row
- latin:keyWidth="7.079%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_thai1"
- latin:keyXPos="3.799%p" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"/>
- </Row>
- <Row
- latin:keyWidth="7.079%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_thai2" />
- <include
- latin:keyboardLayout="@xml/key_thai_kho_khuat" />
- </Row>
- <Row
- latin:keyWidth="7.079%p"
- >
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_thai3" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="7.181%p"
- >
- <Key
- latin:keyStyle="shiftKeyStyle"
- latin:keyWidth="13.829%p"/>
- <include
- latin:keyboardLayout="@xml/rowkeys_thai4" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_qwerty4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_thai_symbols.xml b/java/res/xml-sw768dp/rows_thai_symbols.xml
deleted file mode 100644
index 528514182..000000000
--- a/java/res/xml-sw768dp/rows_thai_symbols.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_thai_digits"
- latin:keyXPos="7.969%p" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols1" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols3" />
- <Key
- latin:keyStyle="toMoreSymbolKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols4" />
-</merge>
diff --git a/java/res/xml-sw768dp/rows_thai_symbols_shift.xml b/java/res/xml-sw768dp/rows_thai_symbols_shift.xml
deleted file mode 100644
index 9d2694b86..000000000
--- a/java/res/xml-sw768dp/rows_thai_symbols_shift.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <include
- latin:keyboardLayout="@xml/key_styles_common" />
- <include
- latin:keyboardLayout="@xml/key_styles_currency" />
- <Row
- latin:keyWidth="8.282%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_thai_digits"
- latin:keyXPos="7.969%p" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.282%p"
- >
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift1" />
- </Row>
- <Row
- latin:keyWidth="8.125%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
- <Row
- latin:keyWidth="8.047%p"
- >
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyWidth="13.829%p" />
- <include
- latin:keyboardLayout="@xml/rowkeys_symbols_shift3" />
- <Key
- latin:keyStyle="backFromMoreSymbolKeyStyle"
- latin:keyXPos="-13.750%p"
- latin:keyWidth="fillRight" />
- </Row>
- <include
- latin:keyboardLayout="@xml/row_symbols_shift4" />
-</merge>
diff --git a/java/res/xml-v16/key_hindi3_shift_left.xml b/java/res/xml-v16/key_devanagari_sign_anusvara.xml
index 1eb1768a1..27c7bff5a 100644
--- a/java/res/xml-v16/key_hindi3_shift_left.xml
+++ b/java/res/xml-v16/key_devanagari_sign_anusvara.xml
@@ -20,15 +20,13 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
- U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E -->
+ <!-- U+0902: "ं" DEVANAGARI SIGN ANUSVARA -->
<Key
- latin:keyLabel="&#x0901;"
- latin:moreKeys="&#x0945;"
+ latin:keyLabel="&#x0902;"
latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml-v16/key_devanagari_sign_candrabindu.xml b/java/res/xml-v16/key_devanagari_sign_candrabindu.xml
new file mode 100644
index 000000000..03017dd78
--- /dev/null
+++ b/java/res/xml-v16/key_devanagari_sign_candrabindu.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
+ U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignCandrabindu"
+ latin:moreKeys="&#x0945;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariSignCandrabindu" />
+ </default>
+ </switch>
+ <!-- U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU -->
+ <Key
+ latin:keyStyle="moreKeysDevanagariSignCandrabindu"
+ latin:keyLabel="&#x0901;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/key_hindi3_right.xml b/java/res/xml-v16/key_devanagari_sign_nukta.xml
index 232810f98..09c347706 100644
--- a/java/res/xml-v16/key_hindi3_right.xml
+++ b/java/res/xml-v16/key_devanagari_sign_nukta.xml
@@ -20,17 +20,30 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- U+093C: "़" DEVANAGARI SIGN NUKTA
- U+097D: "ॽ" DEVANAGARI LETTER GLOTTAL STOP
- U+0970: "॰" DEVANAGARI ABBREVIATION SIGN
- U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+097D: "ॽ" DEVANAGARI LETTER GLOTTAL STOP
+ U+0970: "॰" DEVANAGARI ABBREVIATION SIGN
+ U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignNukta"
+ latin:moreKeys="&#x097D;,&#x0970;,&#x093D;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariSignNukta" />
+ </default>
+ </switch>
+ <!-- U+093C: "़" DEVANAGARI SIGN NUKTA -->
<Key
+ latin:keyStyle="moreKeysDevanagariSignNukta"
latin:keyLabel="&#x093C;"
- latin:moreKeys="&#x097D;,&#x0970;,&#x093D;"
latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml-v16/keys_hindi3_left2.xml b/java/res/xml-v16/key_devanagari_vowel_sign_candra_o.xml
index 9474c1763..0316a7bde 100644
--- a/java/res/xml-v16/keys_hindi3_left2.xml
+++ b/java/res/xml-v16/key_devanagari_vowel_sign_candra_o.xml
@@ -20,8 +20,8 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
@@ -29,8 +29,4 @@
<Key
latin:keyLabel="&#x0949;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0902: "ं" DEVANAGARI SIGN ANUSVARA -->
- <Key
- latin:keyLabel="&#x0902;"
- latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml-v16/key_devanagari_vowel_sign_vocalic_r.xml b/java/res/xml-v16/key_devanagari_vowel_sign_vocalic_r.xml
new file mode 100644
index 000000000..4dd3e85cc
--- /dev/null
+++ b/java/res/xml-v16/key_devanagari_vowel_sign_vocalic_r.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0944: "ॄ" DEVANAGARI VOWEL SIGN VOCALIC RR -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR"
+ latin:moreKeys="&#x0944;" />
+ </case>
+ <case
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <!-- U+0913: "ओ" DEVANAGARI LETTER O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR"
+ latin:moreKeys="&#x0913;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR" />
+ </default>
+ </switch>
+ <!-- U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R -->
+ <Key
+ latin:keyStyle="moreKeysDevanagariVowelSignVocalicR"
+ latin:keyLabel="&#x0943;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keys_hindi1_left5.xml b/java/res/xml-v16/keys_hindi1_left5.xml
deleted file mode 100644
index e3ad299ff..000000000
--- a/java/res/xml-v16/keys_hindi1_left5.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- The code point U+25CC for key label is needed because the font rendering system prior to
- API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+094C: "ौ" DEVANAGARI VOWEL SIGN AU
- U+094C/U+0902: "ौं" DEVANAGARI VOWEL SIGN AU/DEVANAGARI SIGN ANUSVARA
- U+0967: "१" DEVANAGARI DIGIT ONE -->
- <Key
- latin:keyLabel="&#x094C;"
- latin:moreKeys="&#x094C;&#x0902;,%"
- latin:keyHintLabel="1"
- latin:additionalMoreKeys="&#x0967;,1"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+0948: "ै" DEVANAGARI VOWEL SIGN AI
- U+0948/U+0902: "ैं" DEVANAGARI VOWEL SIGN AI/DEVANAGARI SIGN ANUSVARA
- U+0968: "२" DEVANAGARI DIGIT TWO -->
- <Key
- latin:keyLabel="&#x0948;"
- latin:moreKeys="&#x0948;&#x0902;,%"
- latin:keyHintLabel="2"
- latin:additionalMoreKeys="&#x0968;,2"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+093E: "ा" DEVANAGARI VOWEL SIGN AA
- U+093E/U+0902: "ां" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN ANUSVARA
- U+093E/U+0901: "ाँ" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN CANDRABINDU
- U+0969: "३" DEVANAGARI DIGIT THREE -->
- <Key
- latin:keyLabel="&#x093E;"
- latin:moreKeys="&#x093E;&#x0902;,&#x093E;&#x0901;,%"
- latin:keyHintLabel="3"
- latin:additionalMoreKeys="&#x0969;,3"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+0940: "ी" DEVANAGARI VOWEL SIGN II
- U+0940/U+0902: "ीं" DEVANAGARI VOWEL SIGN II/DEVANAGARI SIGN ANUSVARA
- U+096A: "४" DEVANAGARI DIGIT FOUR -->
- <Key
- latin:keyLabel="&#x0940;"
- latin:moreKeys="&#x0940;&#x0902;,%"
- latin:keyHintLabel="4"
- latin:additionalMoreKeys="&#x096A;,4"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+0942: "ू" DEVANAGARI VOWEL SIGN UU
- U+0942/U+0902: "ूं" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN ANUSVARA
- U+0942/U+0901: "ूँ" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN CANDRABINDU
- U+096B: "५" DEVANAGARI DIGIT FIVE -->
- <Key
- latin:keyLabel="&#x0942;"
- latin:moreKeys="&#x0942;&#x0902;,&#x0942;&#x0901;,%"
- latin:keyHintLabel="5"
- latin:additionalMoreKeys="&#x096B;,5"
- latin:keyLabelFlags="fontNormal" />
-</merge>
diff --git a/java/res/xml-v16/keys_hindi2_left5.xml b/java/res/xml-v16/keys_hindi2_left5.xml
deleted file mode 100644
index 05c4f57e9..000000000
--- a/java/res/xml-v16/keys_hindi2_left5.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- The code point U+25CC for key label is needed because the font rendering system prior to
- API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+094B: "ो" DEVANAGARI VOWEL SIGN O
- U+094B/U+0902: "қं" DEVANAGARI VOWEL SIGN O/DEVANAGARI SIGN ANUSVARA
- U+0949: "ॉ" DEVANAGARI VOWEL SIGN CANDRA O
- U+094A: "ॊ" DEVANAGARI VOWEL SIGN SHORT O -->
- <Key
- latin:keyLabel="&#x094B;"
- latin:moreKeys="&#x094B;&#x0902;,&#x0949;,&#x094A;"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+0947: "े" DEVANAGARI VOWEL SIGN E
- U+0947/U+0902: "ें" DEVANAGARI VOWEL SIGN E/DEVANAGARI SIGN ANUSVARA -->
- <Key
- latin:keyLabel="&#x0947;"
- latin:moreKeys="&#x0947;&#x0902;"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+094D: "्" DEVANAGARI SIGN VIRAMA -->
- <Key
- latin:keyLabel="&#x094D;"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+093F: "ि" DEVANAGARI VOWEL SIGN I
- U+093F/U+0902: "िं" DEVANAGARI VOWEL SIGN I/DEVANAGARI SIGN ANUSVARA -->
- <Key
- latin:keyLabel="&#x093F;"
- latin:moreKeys="&#x093F;&#x0902;"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+0941: "ु" DEVANAGARI VOWEL SIGN U
- U+0941/U+0902: "ुं" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN ANUSVARA
- U+0941/U+0901: "ुँ" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN CANDRABINDU -->
- <Key
- latin:keyLabel="&#x0941;"
- latin:moreKeys="&#x0941;&#x0902;,&#x0941;&#x0901;"
- latin:keyLabelFlags="fontNormal" />
-</merge>
diff --git a/java/res/xml-v16/key_hindi3_shift_right.xml b/java/res/xml-v16/keystyle_devanagari_sign_virama.xml
index 0f26cb55c..a2fbf53d3 100644
--- a/java/res/xml-v16/key_hindi3_shift_right.xml
+++ b/java/res/xml-v16/keystyle_devanagari_sign_virama.xml
@@ -20,15 +20,14 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R
- U+0944: "ॄ" DEVANAGARI VOWEL SIGN VOCALIC RR -->
- <Key
- latin:keyLabel="&#x0943;"
- latin:moreKeys="&#x0944;"
+ <!-- U+094D: "्" DEVANAGARI SIGN VIRAMA -->
+ <key-style
+ latin:styleName="baseKeyDevanagariSignVirama"
+ latin:keyLabel="&#x094D;"
latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml-v16/key_hindi1_shift.xml b/java/res/xml-v16/keystyle_devanagari_sign_visarga.xml
index 19b964367..ac56cb77b 100644
--- a/java/res/xml-v16/key_hindi1_shift.xml
+++ b/java/res/xml-v16/keystyle_devanagari_sign_visarga.xml
@@ -20,13 +20,14 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- U+0903: "ः" DEVANAGARI SIGN VISARGA -->
- <Key
+ <key-style
+ latin:styleName="baseKeyDevanagariSignVisarga"
latin:keyLabel="&#x0903;"
latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml
new file mode 100644
index 000000000..8e256032c
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+093E/U+0902: "ां" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN ANUSVARA
+ U+093E/U+0901: "ाँ" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAa"
+ latin:moreKeys="&#x093E;&#x0902;,&#x093E;&#x0901;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAa" />
+ </default>
+ </switch>
+ <!-- U+093E: "ा" DEVANAGARI VOWEL SIGN AA -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignAa"
+ latin:parentStyle="moreKeysDevanagariVowelSignAa"
+ latin:keyLabel="&#x093E;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml
new file mode 100644
index 000000000..e79033971
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0948/U+0902: "ैं" DEVANAGARI VOWEL SIGN AI/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi"
+ latin:moreKeys="&#x0948;&#x0902;,%" />
+ </case>
+ <case
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <!-- U+0936/U+094D/U+0930: "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi"
+ latin:moreKeys="&#x0936;&#x094D;&#x0930;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi" />
+ </default>
+ </switch>
+ <!-- U+0948: "ै" DEVANAGARI VOWEL SIGN AI -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignAi"
+ latin:parentStyle="moreKeysDevanagariVowelSignAi"
+ latin:keyLabel="&#x0948;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml
new file mode 100644
index 000000000..43387a388
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!--U+094C/U+0902: "ौं" DEVANAGARI VOWEL SIGN AU/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAu"
+ latin:moreKeys="&#x094C;&#x0902;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAu" />
+ </default>
+ </switch>
+ <!-- U+094C: "ौ" DEVANAGARI VOWEL SIGN AU -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignAu"
+ latin:parentStyle="moreKeysDevanagariVowelSignAu"
+ latin:keyLabel="&#x094C;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml
new file mode 100644
index 000000000..c70d9d944
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0947/U+0902: "ें" DEVANAGARI VOWEL SIGN E/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE"
+ latin:moreKeys="&#x0947;&#x0902;" />
+ </case>
+ <case
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <!-- U+0903: "ः‍" DEVANAGARI SIGN VISARGA
+ U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE"
+ latin:moreKeys="&#x0903;,&#x093D;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE" />
+ </default>
+ </switch>
+ <!-- U+0947: "े" DEVANAGARI VOWEL SIGN E -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignE"
+ latin:parentStyle="moreKeysDevanagariVowelSignE"
+ latin:keyLabel="&#x0947;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml
new file mode 100644
index 000000000..845c1b02e
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+093F/U+0902: "िं" DEVANAGARI VOWEL SIGN I/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignI"
+ latin:moreKeys="&#x093F;&#x0902;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignI" />
+ </default>
+ </switch>
+ <!-- U+093F: "ि" DEVANAGARI VOWEL SIGN I -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignI"
+ latin:parentStyle="moreKeysDevanagariVowelSignI"
+ latin:keyLabel="&#x093F;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml
new file mode 100644
index 000000000..0de9650be
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0940/U+0902: "ीं" DEVANAGARI VOWEL SIGN II/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignIi"
+ latin:moreKeys="&#x0940;&#x0902;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignIi" />
+ </default>
+ </switch>
+ <!-- U+0940: "ी" DEVANAGARI VOWEL SIGN II -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignIi"
+ latin:parentStyle="moreKeysDevanagariVowelSignIi"
+ latin:keyLabel="&#x0940;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml
new file mode 100644
index 000000000..06f07fac9
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+094B/U+0902: "қं" DEVANAGARI VOWEL SIGN O/DEVANAGARI SIGN ANUSVARA
+ U+0949: "ॉ" DEVANAGARI VOWEL SIGN CANDRA O
+ U+094A: "ॊ" DEVANAGARI VOWEL SIGN SHORT O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignO"
+ latin:moreKeys="&#x094B;&#x0902;,&#x0949;,&#x094A;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignO" />
+ </default>
+ </switch>
+ <!-- U+094B: "ो" DEVANAGARI VOWEL SIGN O -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignO"
+ latin:parentStyle="moreKeysDevanagariVowelSignO"
+ latin:keyLabel="&#x094B;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml
new file mode 100644
index 000000000..469a27bdf
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0941/U+0902: "ुं" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN ANUSVARA
+ U+0941/U+0901: "ुँ" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignU"
+ latin:moreKeys="&#x0941;&#x0902;,&#x0941;&#x0901;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignU" />
+ </default>
+ </switch>
+ <!-- U+0941: "ु" DEVANAGARI VOWEL SIGN U -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignU"
+ latin:parentStyle="moreKeysDevanagariVowelSignU"
+ latin:keyLabel="&#x0941;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml
new file mode 100644
index 000000000..25867c086
--- /dev/null
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0942/U+0902: "ूं" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN ANUSVARA
+ U+0942/U+0901: "ूँ" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignUu"
+ latin:moreKeys="&#x0942;&#x0902;,&#x0942;&#x0901;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignUu" />
+ </default>
+ </switch>
+ <!-- U+0942: "ू" DEVANAGARI VOWEL SIGN UU -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignUu"
+ latin:parentStyle="moreKeysDevanagariVowelSignUu"
+ latin:keyLabel="&#x0942;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-sw768dp/kbd_thai_symbols_shift.xml b/java/res/xml/kbd_armenian_phonetic.xml
index 135222b22..1eb3c7e7d 100644
--- a/java/res/xml-sw768dp/kbd_thai_symbols_shift.xml
+++ b/java/res/xml/kbd_armenian_phonetic.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -27,5 +27,5 @@
latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_thai_symbols_shift" />
+ latin:keyboardLayout="@xml/rows_armenian_phonetic" />
</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_10_10_7_symbols.xml b/java/res/xml/kbd_emoji_category1.xml
index dd545b5ef..c11a83017 100644
--- a/java/res/xml-sw600dp/kbd_10_10_7_symbols.xml
+++ b/java/res/xml/kbd_emoji_category1.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -20,8 +20,12 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="90%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
>
- <include
- latin:keyboardLayout="@xml/rows_10_10_7_symbols" />
+ <GridRows
+ latin:codesArray="@array/emoji_faces"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
</Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_10_10_7_symbols_shift.xml b/java/res/xml/kbd_emoji_category2.xml
index c36f0097e..d3e5890ea 100644
--- a/java/res/xml-sw600dp/kbd_10_10_7_symbols_shift.xml
+++ b/java/res/xml/kbd_emoji_category2.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -20,8 +20,12 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="90%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
>
- <include
- latin:keyboardLayout="@xml/rows_10_10_7_symbols_shift" />
+ <GridRows
+ latin:codesArray="@array/emoji_objects"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
</Keyboard>
diff --git a/java/res/xml-sw768dp-land/kbd_number.xml b/java/res/xml/kbd_emoji_category3.xml
index 1cb775ef7..0efafa814 100644
--- a/java/res/xml-sw768dp-land/kbd_number.xml
+++ b/java/res/xml/kbd_emoji_category3.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -20,11 +20,12 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLeftPadding="10%p"
- latin:keyboardRightPadding="10%p"
- latin:keyWidth="13.250%p"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="90%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
>
- <include
- latin:keyboardLayout="@xml/rows_number" />
+ <GridRows
+ latin:codesArray="@array/emoji_nature"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
</Keyboard>
diff --git a/java/res/xml-sw768dp-land/kbd_phone.xml b/java/res/xml/kbd_emoji_category4.xml
index 890518210..e5291207f 100644
--- a/java/res/xml-sw768dp-land/kbd_phone.xml
+++ b/java/res/xml/kbd_emoji_category4.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -20,11 +20,12 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:keyboardLeftPadding="10%p"
- latin:keyboardRightPadding="10%p"
- latin:keyWidth="13.250%p"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="90%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
>
- <include
- latin:keyboardLayout="@xml/rows_phone" />
+ <GridRows
+ latin:codesArray="@array/emoji_places"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
</Keyboard>
diff --git a/java/res/xml/kbd_emoji_category5.xml b/java/res/xml/kbd_emoji_category5.xml
new file mode 100644
index 000000000..1836879d6
--- /dev/null
+++ b/java/res/xml/kbd_emoji_category5.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="90%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
+>
+ <GridRows
+ latin:codesArray="@array/emoji_symbols"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
+</Keyboard>
diff --git a/java/res/xml/kbd_emoji_category6.xml b/java/res/xml/kbd_emoji_category6.xml
new file mode 100644
index 000000000..b47ebfec0
--- /dev/null
+++ b/java/res/xml/kbd_emoji_category6.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="90%p"
+ latin:keyLabelSize="60%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
+>
+ <GridRows
+ latin:textsArray="@array/emoji_emoticons"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
+</Keyboard>
diff --git a/java/res/xml/kbd_emoji_recents.xml b/java/res/xml/kbd_emoji_recents.xml
new file mode 100644
index 000000000..73926ecc0
--- /dev/null
+++ b/java/res/xml/kbd_emoji_recents.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:keyWidth="@fraction/emoji_keyboard_key_width"
+ latin:keyLetterSize="@fraction/emoji_keyboard_key_letter_size"
+ latin:keyLabelSize="60%p"
+ latin:rowHeight="@fraction/emoji_keyboard_row_height"
+>
+ <GridRows
+ latin:codesArray="@array/emoji_recents"
+ latin:keyLabelFlags="fontNormal"
+ latin:backgroundType="empty" />
+</Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_thai_symbols.xml b/java/res/xml/kbd_khmer.xml
index 5ddf57446..7a2337a48 100644
--- a/java/res/xml-sw768dp/kbd_thai_symbols.xml
+++ b/java/res/xml/kbd_khmer.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -27,5 +27,5 @@
latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_thai_symbols" />
+ latin:keyboardLayout="@xml/rows_khmer" />
</Keyboard>
diff --git a/java/res/xml/kbd_pcqwerty_symbols.xml b/java/res/xml/kbd_lao.xml
index bfb39e8aa..2bba330de 100644
--- a/java/res/xml/kbd_pcqwerty_symbols.xml
+++ b/java/res/xml/kbd_lao.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -27,5 +27,5 @@
latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_pcqwerty_symbols" />
+ latin:keyboardLayout="@xml/rows_lao" />
</Keyboard>
diff --git a/java/res/xml/kbd_thai_symbols_shift.xml b/java/res/xml/kbd_nepali_romanized.xml
index a2d67caf4..9e4381364 100644
--- a/java/res/xml/kbd_thai_symbols_shift.xml
+++ b/java/res/xml/kbd_nepali_romanized.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_symbols_shift" />
+ latin:keyboardLayout="@xml/rows_nepali_romanized" />
</Keyboard>
diff --git a/java/res/xml/kbd_10_10_7_symbols_shift.xml b/java/res/xml/kbd_nepali_traditional.xml
index a2d67caf4..6854e32bd 100644
--- a/java/res/xml/kbd_10_10_7_symbols_shift.xml
+++ b/java/res/xml/kbd_nepali_traditional.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -20,8 +20,7 @@
<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_symbols_shift" />
+ latin:keyboardLayout="@xml/rows_nepali_traditional" />
</Keyboard>
diff --git a/java/res/xml/key_armenian_sha.xml b/java/res/xml/key_armenian_sha.xml
new file mode 100644
index 000000000..3865c1984
--- /dev/null
+++ b/java/res/xml/key_armenian_sha.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- U+0577: "շ" ARMENIAN SMALL LETTER SHA -->
+ <Key
+ latin:keyLabel="&#x0577;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml/key_armenian_xeh.xml b/java/res/xml/key_armenian_xeh.xml
new file mode 100644
index 000000000..007a5802d
--- /dev/null
+++ b/java/res/xml/key_armenian_xeh.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- U+056D: "խ" ARMENIAN SMALL LETTER XEH -->
+ <Key
+ latin:keyLabel="&#x056D;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml/key_hindi3_shift_left.xml b/java/res/xml/key_devanagari_sign_anusvara.xml
index c5e2f1386..0acd3bcd4 100644
--- a/java/res/xml/key_hindi3_shift_left.xml
+++ b/java/res/xml/key_devanagari_sign_anusvara.xml
@@ -20,17 +20,15 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- U+25CC: "◌" DOTTED CIRCLE
- U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU
- U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E -->
+ U+0902: "ं" DEVANAGARI SIGN ANUSVARA -->
<Key
- latin:keyLabel="&#x25CC;&#x0901;"
- latin:code="0x0901"
- latin:moreKeys="&#x25CC;&#x0945;|&#x0945;"
+ latin:keyLabel="&#x25CC;&#x0902;"
+ latin:code="0x0902"
latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
</merge>
diff --git a/java/res/xml/key_hindi3_right.xml b/java/res/xml/key_devanagari_sign_candrabindu.xml
index 5a97355f6..df0c4e054 100644
--- a/java/res/xml/key_hindi3_right.xml
+++ b/java/res/xml/key_devanagari_sign_candrabindu.xml
@@ -20,19 +20,31 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignCandrabindu"
+ latin:moreKeys="&#x25CC;&#x0945;|&#x0945;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariSignCandrabindu" />
+ </default>
+ </switch>
<!-- U+25CC: "◌" DOTTED CIRCLE
- U+093C: "़" DEVANAGARI SIGN NUKTA
- U+097D: "ॽ" DEVANAGARI LETTER GLOTTAL STOP
- U+0970: "॰" DEVANAGARI ABBREVIATION SIGN
- U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU -->
<Key
- latin:keyLabel="&#x25CC;&#x093C;"
- latin:code="0x093C"
- latin:moreKeys="&#x25CC;&#x097D;|&#x097D;,&#x25CC;&#x0970;|&#x0970;,&#x25CC;&#x093D;|&#x093D;"
+ latin:keyStyle="moreKeysDevanagariSignCandrabindu"
+ latin:keyLabel="&#x25CC;&#x0901;"
+ latin:code="0x0901"
latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
</merge>
diff --git a/java/res/xml/key_devanagari_sign_nukta.xml b/java/res/xml/key_devanagari_sign_nukta.xml
new file mode 100644
index 000000000..f7a03ee90
--- /dev/null
+++ b/java/res/xml/key_devanagari_sign_nukta.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+097D: "ॽ" DEVANAGARI LETTER GLOTTAL STOP
+ U+0970: "॰" DEVANAGARI ABBREVIATION SIGN
+ U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignNukta"
+ latin:moreKeys="&#x25CC;&#x097D;|&#x097D;,&#x25CC;&#x0970;|&#x0970;,&#x25CC;&#x093D;|&#x093D;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariSignNukta" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+093C: "़" DEVANAGARI SIGN NUKTA -->
+ <Key
+ latin:keyStyle="moreKeysDevanagariSignNukta"
+ latin:keyLabel="&#x25CC;&#x093C;"
+ latin:code="0x093C"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keys_hindi3_left2.xml b/java/res/xml/key_devanagari_vowel_sign_candra_o.xml
index 4f1ad16ef..370fc5405 100644
--- a/java/res/xml/keys_hindi3_left2.xml
+++ b/java/res/xml/key_devanagari_vowel_sign_candra_o.xml
@@ -20,8 +20,8 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
@@ -31,10 +31,4 @@
latin:keyLabel="&#x25CC;&#x0949;"
latin:code="0x0949"
latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+0902: "ं" DEVANAGARI SIGN ANUSVARA -->
- <Key
- latin:keyLabel="&#x25CC;&#x0902;"
- latin:code="0x0902"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
</merge>
diff --git a/java/res/xml/key_devanagari_vowel_sign_vocalic_r.xml b/java/res/xml/key_devanagari_vowel_sign_vocalic_r.xml
new file mode 100644
index 000000000..f150d7ed9
--- /dev/null
+++ b/java/res/xml/key_devanagari_vowel_sign_vocalic_r.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0944: "ॄ" DEVANAGARI VOWEL SIGN VOCALIC RR -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR"
+ latin:moreKeys="&#x25CC;&#x0944;|&#x0944;" />
+ </case>
+ <case
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <!-- U+0913: "ओ" DEVANAGARI LETTER O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR"
+ latin:moreKeys="&#x0913;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R -->
+ <Key
+ latin:keyStyle="moreKeysDevanagariVowelSignVocalicR"
+ latin:keyLabel="&#x25CC;&#x0943;"
+ latin:code="0x0943"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml-sw768dp/key_shortcut.xml b/java/res/xml/key_f2.xml
index 2d09ebbfc..473dd210a 100644
--- a/java/res/xml-sw768dp/key_shortcut.xml
+++ b/java/res/xml/key_f2.xml
@@ -23,14 +23,16 @@
>
<switch>
<case
- latin:shortcutKeyEnabled="true"
+ latin:mode="email|url"
>
<Key
- latin:keyStyle="shortcutKeyStyle" />
+ latin:keyStyle="comKeyStyle"
+ latin:keyWidth="fillRight" />
</case>
<default>
- <!-- The empty space instead of shortcut key. -->
- <Spacer />
+ <Key
+ latin:keyStyle="emojiKeyStyle"
+ latin:keyWidth="fillRight" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/key_nepali_traditional_period.xml b/java/res/xml/key_nepali_traditional_period.xml
new file mode 100644
index 000000000..0f575c50b
--- /dev/null
+++ b/java/res/xml/key_nepali_traditional_period.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of Hindi. The files named res/xml/{key,keys}_nepali*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/{key,keys}_nepali*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Key
+ latin:keyLabel=","
+ latin:backgroundType="functional" />
+ </case>
+ <default>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVirama"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="!fixedColumnOrder!4,.,!text/more_keys_for_punctuation"
+ latin:backgroundType="functional" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw768dp/key_settings.xml b/java/res/xml/key_space_3kw.xml
index 0d3bb59a4..20ec882df 100644
--- a/java/res/xml-sw768dp/key_settings.xml
+++ b/java/res/xml/key_space_3kw.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -23,13 +23,19 @@
>
<switch>
<case
- latin:clobberSettingsKey="false"
+ latin:languageSwitchKeyEnabled="true"
>
<Key
- latin:keyStyle="settingsKeyStyle" />
+ latin:keyStyle="languageSwitchKeyStyle" />
+ <Key
+ latin:keyStyle="spaceKeyStyle"
+ latin:keyWidth="20%p" />
</case>
+ <!-- languageSwitchKeyEnabled="false" -->
<default>
- <Spacer />
+ <Key
+ latin:keyStyle="spaceKeyStyle"
+ latin:keyWidth="30%p" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/key_space.xml b/java/res/xml/key_space_5kw.xml
index 02ee42fd2..b6d38fb33 100644
--- a/java/res/xml/key_space.xml
+++ b/java/res/xml/key_space_5kw.xml
@@ -23,7 +23,7 @@
>
<switch>
<case
- latin:languageCode="fa"
+ latin:languageCode="fa|ne"
latin:languageSwitchKeyEnabled="true"
>
<Key
@@ -35,7 +35,7 @@
latin:keyStyle="zwnjKeyStyle" />
</case>
<case
- latin:languageCode="fa"
+ latin:languageCode="fa|ne"
latin:languageSwitchKeyEnabled="false"
>
<Key
diff --git a/java/res/xml/kbd_thai_symbols.xml b/java/res/xml/key_space_symbols.xml
index 4d9861b73..1efc4ff4e 100644
--- a/java/res/xml/kbd_thai_symbols.xml
+++ b/java/res/xml/key_space_symbols.xml
@@ -18,10 +18,9 @@
*/
-->
-<Keyboard
+<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
- latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
>
<include
- latin:keyboardLayout="@xml/rows_symbols" />
-</Keyboard>
+ latin:keyboardLayout="@xml/key_space_3kw" />
+</merge>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 355455e3b..67ed9620d 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -21,6 +21,20 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ >
+ <key-style
+ latin:styleName="hasShiftedLetterHintStyle"
+ latin:keyLabelFlags="hasShiftedLetterHint|shiftedLetterActivated" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="hasShiftedLetterHintStyle"
+ latin:keyLabelFlags="hasShiftedLetterHint" />
+ </default>
+ </switch>
<!-- Base key style for the key which may have settings or tab key as popup key. -->
<include
latin:keyboardLayout="@xml/key_styles_f1" />
@@ -67,30 +81,6 @@
latin:backgroundType="functional" />
<include
latin:keyboardLayout="@xml/key_styles_enter" />
- <switch>
- <!-- Shift + Enter in textMultiLine field. -->
- <case
- latin:isMultiLine="true"
- latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:parentStyle="shiftEnterKeyStyle" />
- </case>
- <!-- Smiley in textShortMessage field.
- Overrides common enter key style. -->
- <case
- latin:mode="im"
- >
- <key-style
- latin:styleName="enterKeyStyle"
- latin:keyLabel=":-)"
- latin:keyOutputText=":-) "
- latin:keyLabelFlags="hasPopupHint"
- latin:moreKeys="!text/more_keys_for_smiley"
- latin:backgroundType="functional" />
- </case>
- </switch>
<key-style
latin:styleName="spaceKeyStyle"
latin:code="!code/key_space"
@@ -129,7 +119,8 @@
latin:styleName="emojiKeyStyle"
latin:code="!code/key_emoji"
latin:keyIcon="!icon/emoji_key"
- latin:keyActionFlags="noKeyPreview" />
+ latin:keyActionFlags="noKeyPreview"
+ latin:backgroundType="functional" />
<key-style
latin:styleName="tabKeyStyle"
latin:code="!code/key_tab"
@@ -193,4 +184,11 @@
latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="!text/more_keys_for_punctuation"
latin:backgroundType="functional" />
+ <key-style
+ latin:styleName="comKeyStyle"
+ latin:keyLabel="!text/keylabel_for_popular_domain"
+ latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase"
+ latin:keyOutputText="!text/keylabel_for_popular_domain"
+ latin:moreKeys="!text/more_keys_for_popular_domain"
+ latin:backgroundType="functional" />
</merge>
diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml
index 76fe0e6b0..84c2abc08 100644
--- a/java/res/xml/key_styles_currency.xml
+++ b/java/res/xml/key_styles_currency.xml
@@ -95,22 +95,26 @@
<!-- fa: Persian (Rial and Afgahni)
hi: Hindi (Indian Rupee)
iw: Hebrew (New Sheqel)
+ lo: Lao (Kip)
mn: Mongolian (Tugrik)
+ ne: Nepali (Nepalese Rupee)
th: Thai (Baht)
uk: Ukrainian (Hryvnia)
vi: Vietnamese (Dong) -->
<!-- TODO: The currency sign of Turkish Lira was created in 2012 and assigned U+20BA for
its unicode, although there is no font glyph for it as of November 2012. -->
+ <!-- TODO: The currency sign of Armenian Dram was created in 2012 and assigned U+058F for
+ its unicode, although there is no font glyph for it as of September 2013. -->
<case
- latin:languageCode="fa|hi|iw|mn|th|uk|vi"
+ latin:languageCode="fa|hi|iw|lo|mn|ne|th|uk|vi"
>
<!-- U+00A3: "£" POUND SIGN
U+20AC: "€" EURO SIGN
U+00A2: "¢" CENT SIGN -->
<key-style
latin:styleName="currencyKeyStyle"
- latin:keyLabel="!text/keylabel_for_currency_generic"
- latin:moreKeys="!text/more_keys_for_currency_generic" />
+ latin:keyLabel="!text/keylabel_for_currency"
+ latin:moreKeys="!text/more_keys_for_currency" />
<key-style
latin:styleName="moreCurrency1KeyStyle"
latin:keyLabel="&#x00A3;" />
diff --git a/java/res/xml/key_symbols_period.xml b/java/res/xml/key_symbols_period.xml
new file mode 100644
index 000000000..6efc9dee3
--- /dev/null
+++ b/java/res/xml/key_symbols_period.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- U+2105: "℅" CARE OF
+ U+2122: "™" TRADE MARK SIGN
+ U+00AE: "®" REGISTERED SIGN
+ U+00A9: "©" COPYRIGHT SIGN
+ U+00A7: "§" SECTION SIGN
+ U+00B6: "¶" PILCROW SIGN
+ U+002C: "," COMMA
+ U+2022: "•" BULLET -->
+ <!-- U+00B0: "°" DEGREE SIGN
+ U+2032: "′" PRIME
+ U+2033: "″" DOUBLE PRIME
+ U+2191: "↑" UPWARDS ARROW
+ U+2193: "↓" DOWNWARDS ARROW
+ U+2190: "←" LEFTWARDS ARROW
+ U+2192: "→" RIGHTWARDS ARROW
+ U+2026: "…" HORIZONTAL ELLIPSIS -->
+ <!-- U+0394: "Δ" GREEK CAPITAL LETTER DELTA
+ U+03A0: "Π" GREEK CAPITAL LETTER PI
+ U+03C0: "π" GREEK SMALL LETTER PI -->
+ <Key
+ latin:keyLabel="."
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="!fixedColumnOrder!8,&#x2105;,&#x2122;,&#x00AE;,&#x00A9;,&#x00A7;,&#x00B6;,\\,,&#x2022;,&#x00B0;,&#x2032;,&#x2033;,&#x2191;,&#x2193;,&#x2190;,&#x2192;,&#x2026;,!text/more_keys_for_bullet,&#x0394;,&#x03A0;,&#x03C0;" />
+</merge>
diff --git a/java/res/xml/keyboard_layout_set_armenian_phonetic.xml b/java/res/xml/keyboard_layout_set_armenian_phonetic.xml
new file mode 100644
index 000000000..35bd43fb9
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_armenian_phonetic.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_armenian_phonetic"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keyboard_layout_set_azerty.xml b/java/res/xml/keyboard_layout_set_azerty.xml
index 4d144edbc..38797f91a 100644
--- a/java/res/xml/keyboard_layout_set_azerty.xml
+++ b/java/res/xml/keyboard_layout_set_azerty.xml
@@ -26,10 +26,10 @@
latin:enableProximityCharsCorrection="true" />
<Element
latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols" />
+ latin:elementKeyboard="@xml/kbd_symbols" />
<Element
latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols_shift" />
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
<Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
diff --git a/java/res/xml/keyboard_layout_set_colemak.xml b/java/res/xml/keyboard_layout_set_colemak.xml
index c18f13225..3061872a8 100644
--- a/java/res/xml/keyboard_layout_set_colemak.xml
+++ b/java/res/xml/keyboard_layout_set_colemak.xml
@@ -26,10 +26,10 @@
latin:enableProximityCharsCorrection="true" />
<Element
latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols" />
+ latin:elementKeyboard="@xml/kbd_symbols" />
<Element
latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols_shift" />
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
<Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
diff --git a/java/res/xml/keyboard_layout_set_dvorak.xml b/java/res/xml/keyboard_layout_set_dvorak.xml
index eb8e0c539..31aeec525 100644
--- a/java/res/xml/keyboard_layout_set_dvorak.xml
+++ b/java/res/xml/keyboard_layout_set_dvorak.xml
@@ -26,10 +26,10 @@
latin:enableProximityCharsCorrection="true" />
<Element
latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols" />
+ latin:elementKeyboard="@xml/kbd_symbols" />
<Element
latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols_shift" />
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
<Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
diff --git a/java/res/xml/keyboard_layout_set_emoji.xml b/java/res/xml/keyboard_layout_set_emoji.xml
new file mode 100644
index 000000000..98e6b6b5c
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_emoji.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="emojiRecents"
+ latin:elementKeyboard="@xml/kbd_emoji_recents" />
+ <Element
+ latin:elementName="emojiCategory1"
+ latin:elementKeyboard="@xml/kbd_emoji_category1" />
+ <Element
+ latin:elementName="emojiCategory2"
+ latin:elementKeyboard="@xml/kbd_emoji_category2" />
+ <Element
+ latin:elementName="emojiCategory3"
+ latin:elementKeyboard="@xml/kbd_emoji_category3" />
+ <Element
+ latin:elementName="emojiCategory4"
+ latin:elementKeyboard="@xml/kbd_emoji_category4" />
+ <Element
+ latin:elementName="emojiCategory5"
+ latin:elementKeyboard="@xml/kbd_emoji_category5" />
+ <Element
+ latin:elementName="emojiCategory6"
+ latin:elementKeyboard="@xml/kbd_emoji_category6" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keyboard_layout_set_hebrew.xml b/java/res/xml/keyboard_layout_set_hebrew.xml
index 212816dfe..d5b25b36c 100644
--- a/java/res/xml/keyboard_layout_set_hebrew.xml
+++ b/java/res/xml/keyboard_layout_set_hebrew.xml
@@ -26,10 +26,10 @@
latin:enableProximityCharsCorrection="true" />
<Element
latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols" />
+ latin:elementKeyboard="@xml/kbd_symbols" />
<Element
latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols_shift" />
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
<Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
diff --git a/java/res/xml/keyboard_layout_set_khmer.xml b/java/res/xml/keyboard_layout_set_khmer.xml
new file mode 100644
index 000000000..181f98b3d
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_khmer.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_khmer"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="alphabetAutomaticShifted"
+ latin:elementKeyboard="@xml/kbd_khmer"
+ latin:enableProximityCharsCorrection="true" />
+ <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+ because the letters on these layouts aren't the ones in different case of the above
+ unshifted layouts. -->
+ <Element
+ latin:elementName="alphabetManualShifted"
+ latin:elementKeyboard="@xml/kbd_khmer" />
+ <Element
+ latin:elementName="alphabetShiftLocked"
+ latin:elementKeyboard="@xml/kbd_khmer" />
+ <Element
+ latin:elementName="alphabetShiftLockShifted"
+ latin:elementKeyboard="@xml/kbd_khmer" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keyboard_layout_set_lao.xml b/java/res/xml/keyboard_layout_set_lao.xml
new file mode 100644
index 000000000..2ffde45db
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_lao.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_lao"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="alphabetAutomaticShifted"
+ latin:elementKeyboard="@xml/kbd_lao"
+ latin:enableProximityCharsCorrection="true" />
+ <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+ because the letters on these layouts aren't the ones in different case of the above
+ unshifted layouts. -->
+ <Element
+ latin:elementName="alphabetManualShifted"
+ latin:elementKeyboard="@xml/kbd_lao" />
+ <Element
+ latin:elementName="alphabetShiftLocked"
+ latin:elementKeyboard="@xml/kbd_lao" />
+ <Element
+ latin:elementName="alphabetShiftLockShifted"
+ latin:elementKeyboard="@xml/kbd_lao" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keyboard_layout_set_nepali_romanized.xml b/java/res/xml/keyboard_layout_set_nepali_romanized.xml
new file mode 100644
index 000000000..fbbc6a5a0
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_nepali_romanized.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_nepali_romanized"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="alphabetAutomaticShifted"
+ latin:elementKeyboard="@xml/kbd_nepali_romanized"
+ latin:enableProximityCharsCorrection="true" />
+ <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+ because the letters on these layouts aren't the ones in different case of the above
+ unshifted layouts. -->
+ <Element
+ latin:elementName="alphabetManualShifted"
+ latin:elementKeyboard="@xml/kbd_nepali_romanized" />
+ <Element
+ latin:elementName="alphabetShiftLocked"
+ latin:elementKeyboard="@xml/kbd_nepali_romanized" />
+ <Element
+ latin:elementName="alphabetShiftLockShifted"
+ latin:elementKeyboard="@xml/kbd_nepali_romanized" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keyboard_layout_set_nepali_traditional.xml b/java/res/xml/keyboard_layout_set_nepali_traditional.xml
new file mode 100644
index 000000000..4a3b60153
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_nepali_traditional.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_nepali_traditional"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="alphabetAutomaticShifted"
+ latin:elementKeyboard="@xml/kbd_nepali_traditional"
+ latin:enableProximityCharsCorrection="true" />
+ <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+ because the letters on these layouts aren't the ones in different case of the above
+ unshifted layouts. -->
+ <Element
+ latin:elementName="alphabetManualShifted"
+ latin:elementKeyboard="@xml/kbd_nepali_traditional" />
+ <Element
+ latin:elementName="alphabetShiftLocked"
+ latin:elementKeyboard="@xml/kbd_nepali_traditional" />
+ <Element
+ latin:elementName="alphabetShiftLockShifted"
+ latin:elementKeyboard="@xml/kbd_nepali_traditional" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keyboard_layout_set_pcqwerty.xml b/java/res/xml/keyboard_layout_set_pcqwerty.xml
index 9367ed00c..67fbd9159 100644
--- a/java/res/xml/keyboard_layout_set_pcqwerty.xml
+++ b/java/res/xml/keyboard_layout_set_pcqwerty.xml
@@ -25,12 +25,6 @@
latin:elementKeyboard="@xml/kbd_pcqwerty"
latin:enableProximityCharsCorrection="true" />
<Element
- latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_pcqwerty_symbols" />
- <Element
- latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_pcqwerty_symbols" />
- <Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
<Element
diff --git a/java/res/xml/keyboard_layout_set_spanish.xml b/java/res/xml/keyboard_layout_set_spanish.xml
index 57cef5234..c454de3b4 100644
--- a/java/res/xml/keyboard_layout_set_spanish.xml
+++ b/java/res/xml/keyboard_layout_set_spanish.xml
@@ -26,10 +26,10 @@
latin:enableProximityCharsCorrection="true" />
<Element
latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols" />
+ latin:elementKeyboard="@xml/kbd_symbols" />
<Element
latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_10_10_7_symbols_shift" />
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
<Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
diff --git a/java/res/xml/keyboard_layout_set_thai.xml b/java/res/xml/keyboard_layout_set_thai.xml
index 94713e3d4..b8f99971b 100644
--- a/java/res/xml/keyboard_layout_set_thai.xml
+++ b/java/res/xml/keyboard_layout_set_thai.xml
@@ -42,10 +42,10 @@
latin:elementKeyboard="@xml/kbd_thai" />
<Element
latin:elementName="symbols"
- latin:elementKeyboard="@xml/kbd_thai_symbols" />
+ latin:elementKeyboard="@xml/kbd_symbols" />
<Element
latin:elementName="symbolsShifted"
- latin:elementKeyboard="@xml/kbd_thai_symbols_shift" />
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
<Element
latin:elementName="phone"
latin:elementKeyboard="@xml/kbd_phone" />
diff --git a/java/res/xml/keys_comma_period.xml b/java/res/xml/keys_comma_period.xml
new file mode 100644
index 000000000..02b46c23a
--- /dev/null
+++ b/java/res/xml/keys_comma_period.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:mode="email|url"
+ >
+ <Key
+ latin:keyLabel="."
+ latin:keyHintLabel="_"
+ latin:moreKeys="_"
+ latin:backgroundType="functional"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ <Key
+ latin:keyLabel=","
+ latin:keyHintLabel="-"
+ latin:moreKeys="-"
+ latin:backgroundType="functional"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ </case>
+ <case
+ latin:languageCode="ar"
+ >
+ <Key
+ latin:keyLabel="!text/keylabel_for_apostrophe"
+ latin:keyHintLabel="!text/keyhintlabel_for_apostrophe"
+ latin:moreKeys="!text/more_keys_for_apostrophe"
+ latin:backgroundType="functional"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ <Key
+ latin:keyLabel="."
+ latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="!text/more_keys_for_arabic_diacritics"
+ latin:backgroundType="functional"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ </case>
+ <case
+ latin:languageCode="fa"
+ >
+ <Key
+ latin:keyLabel="!text/keylabel_for_apostrophe"
+ latin:keyHintLabel="!text/keyhintlabel_for_apostrophe"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="!text/more_keys_for_apostrophe"
+ latin:backgroundType="functional"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ <Key
+ latin:keyLabel="."
+ latin:keyHintLabel="!text/keyhintlabel_for_arabic_diacritics"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="!text/more_keys_for_arabic_diacritics"
+ latin:backgroundType="functional"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
+ </case>
+ <case
+ latin:languageCode="hy"
+ >
+ <!-- U+0589: "։" ARMENIAN FULL STOP -->
+ <Key
+ latin:keyLabel="&#x0589;"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:backgroundType="functional"
+ latin:moreKeys="!text/more_keys_for_punctuation" />
+ <!-- U+055D: "՝" ARMENIAN COMMA -->
+ <Key
+ latin:keyLabel="&#x055D;"
+ latin:backgroundType="functional" />
+ </case>
+ <default>
+ <Key
+ latin:keyLabel="."
+ latin:keyHintLabel="!text/keyhintlabel_for_tablet_period"
+ latin:backgroundType="functional"
+ latin:moreKeys="!text/more_keys_for_tablet_period" />
+ <Key
+ latin:keyLabel="!text/keylabel_for_tablet_comma"
+ latin:keyHintLabel="!text/keyhintlabel_for_tablet_comma"
+ latin:backgroundType="functional"
+ latin:moreKeys="!text/more_keys_for_tablet_comma" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/keys_hindi1_left5.xml b/java/res/xml/keys_hindi1_left5.xml
deleted file mode 100644
index 8757afeaf..000000000
--- a/java/res/xml/keys_hindi1_left5.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- The code point U+25CC for key label is needed because the font rendering system prior to
- API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+094C: "ौ" DEVANAGARI VOWEL SIGN AU
- U+094C/U+0902: "ौं" DEVANAGARI VOWEL SIGN AU/DEVANAGARI SIGN ANUSVARA
- U+0967: "१" DEVANAGARI DIGIT ONE -->
- <Key
- latin:keyLabel="&#x25CC;&#x094C;"
- latin:code="0x094C"
- latin:moreKeys="&#x25CC;&#x094C;&#x0902;|&#x094C;&#x0902;,%"
- latin:keyHintLabel="1"
- latin:additionalMoreKeys="&#x0967;,1"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+0948: "ै" DEVANAGARI VOWEL SIGN AI
- U+0948/U+0902: "ैं" DEVANAGARI VOWEL SIGN AI/DEVANAGARI SIGN ANUSVARA
- U+0968: "२" DEVANAGARI DIGIT TWO -->
- <Key
- latin:keyLabel="&#x25CC;&#x0948;"
- latin:code="0x0948"
- latin:moreKeys="&#x25CC;&#x0948;&#x0902;|&#x0948;&#x0902;,%"
- latin:keyHintLabel="2"
- latin:additionalMoreKeys="&#x0968;,2"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+093E: "ा" DEVANAGARI VOWEL SIGN AA
- U+093E/U+0902: "ां" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN ANUSVARA
- U+093E/U+0901: "ाँ" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN CANDRABINDU
- U+0969: "३" DEVANAGARI DIGIT THREE -->
- <Key
- latin:keyLabel="&#x25CC;&#x093E;"
- latin:code="0x093E"
- latin:moreKeys="&#x25CC;&#x093E;&#x0902;|&#x093E;&#x0902;,&#x25CC;&#x093E;&#x0901;|&#x093E;&#x0901;,%"
- latin:keyHintLabel="3"
- latin:additionalMoreKeys="&#x0969;,3"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+0940: "ी" DEVANAGARI VOWEL SIGN II
- U+0940/U+0902: "ीं" DEVANAGARI VOWEL SIGN II/DEVANAGARI SIGN ANUSVARA
- U+096A: "४" DEVANAGARI DIGIT FOUR -->
- <Key
- latin:keyLabel="&#x25CC;&#x0940;"
- latin:code="0x0940"
- latin:moreKeys="&#x25CC;&#x0940;&#x0902;|&#x0940;&#x0902;,%"
- latin:keyHintLabel="4"
- latin:additionalMoreKeys="&#x096A;,4"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+0942: "ू" DEVANAGARI VOWEL SIGN UU
- U+0942/U+0902: "ूं" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN ANUSVARA
- U+0942/U+0901: "ूँ" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN CANDRABINDU
- U+096B: "५" DEVANAGARI DIGIT FIVE -->
- <Key
- latin:keyLabel="&#x25CC;&#x0942;"
- latin:code="0x0942"
- latin:moreKeys="&#x25CC;&#x0942;&#x0902;|&#x0942;&#x0902;,&#x25CC;&#x0942;&#x0901;|&#x0942;&#x0901;,%"
- latin:keyHintLabel="5"
- latin:additionalMoreKeys="&#x096B;,5"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
-</merge>
diff --git a/java/res/xml/keys_hindi2_left5.xml b/java/res/xml/keys_hindi2_left5.xml
deleted file mode 100644
index 4c3a5e051..000000000
--- a/java/res/xml/keys_hindi2_left5.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- The code point U+25CC for key label is needed because the font rendering system prior to
- API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+094B: "ो" DEVANAGARI VOWEL SIGN O
- U+094B/U+0902: "қं" DEVANAGARI VOWEL SIGN O/DEVANAGARI SIGN ANUSVARA
- U+0949: "ॉ" DEVANAGARI VOWEL SIGN CANDRA O
- U+094A: "ॊ" DEVANAGARI VOWEL SIGN SHORT O -->
- <Key
- latin:keyLabel="&#x25CC;&#x094B;"
- latin:code="0x094B"
- latin:moreKeys="&#x25CC;&#x094B;&#x0902;|&#x094B;&#x0902;,&#x25CC;&#x0949;,&#x094A;|&#x0949;,&#x094A;"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+0947: "े" DEVANAGARI VOWEL SIGN E
- U+0947/U+0902: "ें" DEVANAGARI VOWEL SIGN E/DEVANAGARI SIGN ANUSVARA -->
- <Key
- latin:keyLabel="&#x25CC;&#x0947;"
- latin:code="0x0947"
- latin:moreKeys="&#x25CC;&#x0947;&#x0902;|&#x0947;&#x0902;"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+094D: "्" DEVANAGARI SIGN VIRAMA -->
- <Key
- latin:keyLabel="&#x25CC;&#x094D;"
- latin:code="0x094D"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+093F: "ि" DEVANAGARI VOWEL SIGN I
- U+093F/U+0902: "िं" DEVANAGARI VOWEL SIGN I/DEVANAGARI SIGN ANUSVARA -->
- <Key
- latin:keyLabel="&#x093F;&#x25CC;"
- latin:code="0x093F"
- latin:moreKeys="&#x093F;&#x25CC;&#x0902;|&#x093F;&#x0902;"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
- <!-- U+25CC: "◌" DOTTED CIRCLE
- U+0941: "ु" DEVANAGARI VOWEL SIGN U
- U+0941/U+0902: "ुं" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN ANUSVARA
- U+0941/U+0901: "ुँ" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN CANDRABINDU -->
- <Key
- latin:keyLabel="&#x25CC;&#x0941;"
- latin:code="0x0941"
- latin:moreKeys="&#x25CC;&#x0941;&#x0902;|&#x0941;&#x0902;,&#x25CC;&#x0941;&#x0901;|&#x0941;&#x0901;"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
-</merge>
diff --git a/java/res/xml/keys_less_greater.xml b/java/res/xml/keys_less_greater.xml
index bc9ecdf2f..56d0727dd 100644
--- a/java/res/xml/keys_less_greater.xml
+++ b/java/res/xml/keys_less_greater.xml
@@ -30,20 +30,24 @@
<Key
latin:keyLabel="&#x00AB;"
latin:code="0x00BB"
+ latin:backgroundType="functional"
latin:moreKeys="!text/more_keys_for_less_than" />
<Key
latin:keyLabel="&#x00BB;"
latin:code="0x00AB"
+ latin:backgroundType="functional"
latin:moreKeys="!text/more_keys_for_greater_than" />
</case>
<default>
<Key
latin:keyLabel="&lt;"
latin:code="!code/key_less_than"
+ latin:backgroundType="functional"
latin:moreKeys="!text/more_keys_for_less_than" />
<Key
latin:keyLabel="&gt;"
latin:code="!code/key_greater_than"
+ latin:backgroundType="functional"
latin:moreKeys="!text/more_keys_for_greater_than" />
</default>
</switch>
diff --git a/java/res/xml/keys_pcqwerty2_right3.xml b/java/res/xml/keys_pcqwerty2_right3.xml
index 2065e6b46..6f86477da 100644
--- a/java/res/xml/keys_pcqwerty2_right3.xml
+++ b/java/res/xml/keys_pcqwerty2_right3.xml
@@ -27,25 +27,22 @@
>
<Key
latin:keyLabel="["
- latin:moreKeys="{" />
+ latin:additionalMoreKeys="{" />
<Key
latin:keyLabel="]"
- latin:moreKeys="}" />
- <!-- U+00A6: "¦" BROKEN BAR -->
+ latin:additionalMoreKeys="}" />
<Key
latin:keyLabel="\\"
- latin:moreKeys="\\|,&#x00A6;" />
+ latin:additionalMoreKeys="\\|" />
</case>
- <!-- keyboardLayoutSetElement="alphabet*Shifted|symbols*" -->
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
<default>
<Key
latin:keyLabel="{" />
<Key
latin:keyLabel="}" />
- <!-- U+00A6: "¦" BROKEN BAR -->
<Key
- latin:keyLabel="|"
- latin:moreKeys="&#x00A6;" />
+ latin:keyLabel="|" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/keys_pcqwerty3_right2.xml b/java/res/xml/keys_pcqwerty3_right2.xml
index aa150afb3..8da145b20 100644
--- a/java/res/xml/keys_pcqwerty3_right2.xml
+++ b/java/res/xml/keys_pcqwerty3_right2.xml
@@ -27,12 +27,13 @@
>
<Key
latin:keyLabel=";"
- latin:moreKeys=":" />
+ latin:additionalMoreKeys=":" />
<Key
latin:keyLabel="\'"
- latin:moreKeys="!fixedColumnOrder!4,!text/double_quotes,&quot;,!text/single_quotes" />
+ latin:additionalMoreKeys="&quot;"
+ latin:moreKeys="!fixedColumnOrder!4,!text/double_quotes,%,!text/single_quotes" />
</case>
- <!-- keyboardLayoutSetElement="alphabet*Shifted|symbols*" -->
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
<default>
<Key
latin:keyLabel=":" />
diff --git a/java/res/xml/keys_pcqwerty4_right3.xml b/java/res/xml/keys_pcqwerty4_right3.xml
index 7795b3d8b..e6084cb45 100644
--- a/java/res/xml/keys_pcqwerty4_right3.xml
+++ b/java/res/xml/keys_pcqwerty4_right3.xml
@@ -27,16 +27,16 @@
>
<Key
latin:keyLabel=","
- latin:moreKeys="&lt;" />
+ latin:additionalMoreKeys="&lt;" />
<Key
latin:keyLabel="."
- latin:moreKeys="&gt;" />
- <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
+ latin:additionalMoreKeys="&gt;" />
<Key
latin:keyLabel="/"
- latin:moreKeys="\?,&#x00BF;" />
+ latin:additionalMoreKeys="\?"
+ latin:moreKeys="!text/more_keys_for_symbols_question" />
</case>
- <!-- keyboardLayoutSetElement="alphabet*Shifted|symbols*" -->
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
<default>
<!-- U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
@@ -50,10 +50,9 @@
<Key
latin:keyLabel="&gt;"
latin:moreKeys="!fixedColumnOrder!3,&#x203A;,&#x2265;,&#x00BB;" />
- <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
<Key
latin:keyLabel="\?"
- latin:moreKeys="&#x00BF;" />
+ latin:moreKeys="!text/more_keys_for_symbols_question" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/keys_pcqwerty_symbols2.xml b/java/res/xml/keys_pcqwerty_symbols2.xml
deleted file mode 100644
index d0ea984e8..000000000
--- a/java/res/xml/keys_pcqwerty_symbols2.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+2022: "•" BULLET -->
- <Key
- latin:keyLabel="&#x2022;"
- latin:moreKeys="!text/more_keys_for_bullet" />
- <!-- U+00B1: "±" PLUS-MINUS SIGN -->
- <Key
- latin:keyLabel="&#x00B1;" />
- <!-- U+00AC: "¬" NOT SIGN -->
- <Key
- latin:keyLabel="&#x00AC;" />
- <!-- U+00A6: "¦" BROKEN BAR -->
- <Key
- latin:keyLabel="&#x00A6;" />
- <!-- U+221A: "√" SQUARE ROOT -->
- <Key
- latin:keyLabel="&#x221A;" />
- <!-- U+03C0: "π" GREEK SMALL LETTER PI
- U+03A0: "Π" GREEK CAPITAL LETTER PI -->
- <Key
- latin:keyLabel="&#x03C0;"
- latin:moreKeys="&#x03A0;" />
- <!-- U+03CC: "σ" GREEK SMALL LETTER SIGMA
- U+03A3: "Σ" GREEK CAPITAL LETTER SIGMA -->
- <Key
- latin:keyLabel="&#x03C3;"
- latin:moreKeys="&#x03A3;" />
- <!-- U+00B5: "µ" MICRO SIGN -->
- <Key
- latin:keyLabel="&#x00B5;" />
- <!-- U+00F7: "÷" DIVISION SIGN -->
- <Key
- latin:keyLabel="&#x00F7;" />
- <!-- U+00D7: "×" MULTIPLICATION SIGN -->
- <Key
- latin:keyLabel="&#x00D7;" />
-</merge>
diff --git a/java/res/xml/keys_pcqwerty_symbols3.xml b/java/res/xml/keys_pcqwerty_symbols3.xml
deleted file mode 100644
index 35279deaf..000000000
--- a/java/res/xml/keys_pcqwerty_symbols3.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+00A3: "£" POUND SIGN; -->
- <Key
- latin:keyLabel="&#x00A3;" />
- <!-- U+00A2: "¢" CENT SIGN -->
- <Key
- latin:keyLabel="&#x00A2;" />
- <!-- U+20AC: "€" EURO SIGN -->
- <Key
- latin:keyLabel="&#x20AC;" />
- <!-- U+00A5: "¥" YEN SIGN -->
- <Key
- latin:keyLabel="&#x00A5;" />
- <!-- U+00A4: "¤" CURRENCY SIGN -->
- <Key
- latin:keyLabel="&#x00A4;" />
- <!-- U+00B0: "°" DEGREE SIGN
- U+2032: "′" PRIME
- U+2033: "″" DOUBLE PRIME -->
- <Key
- latin:keyLabel="&#x00B0;"
- latin:moreKeys="&#x2032;,&#x2033;" />
- <!-- U+2260: "≠" NOT EQUAL TO -->
- <Key
- latin:keyLabel="&#x2260;" />
- <!-- U+2248: "≈" ALMOST EQUAL TO -->
- <Key
- latin:keyLabel="&#x2248;" />
- <!-- U+221E: "∞" INFINITY -->
- <Key
- latin:keyLabel="&#x221E;" />
-</merge>
diff --git a/java/res/xml/keys_pcqwerty_symbols4.xml b/java/res/xml/keys_pcqwerty_symbols4.xml
deleted file mode 100644
index 3c628f0e0..000000000
--- a/java/res/xml/keys_pcqwerty_symbols4.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <!-- U+2122: "™" TRADE MARK SIGN -->
- <Key
- latin:keyLabel="&#x2122;" />
- <!-- U+00AE: "®" REGISTERED SIGN -->
- <Key
- latin:keyLabel="&#x00AE;" />
- <!-- U+00A9: "©" COPYRIGHT SIGN -->
- <Key
- latin:keyLabel="&#x00A9;" />
- <!-- U+00B6: "¶" PILCROW SIGN -->
- <Key
- latin:keyLabel="&#x00B6;" />
- <!-- U+00A7: "§" SECTION SIGN -->
- <Key
- latin:keyLabel="&#x00A7;" />
- <!-- U+2191: "↑" UPWARDS ARROW
- U+2193: "↓" DOWNWARDS ARROW
- U+2190: "←" LEFTWARDS ARROW
- U+2192: "→" RIGHTWARDS ARROW -->
- <Key
- latin:keyLabel="&#x2191;"
- latin:moreKeys="&#x2193;" />
- <Key
- latin:keyLabel="&#x2190;"
- latin:moreKeys="&#x2192;" />
-</merge>
diff --git a/java/res/xml/key_hindi3_shift_right.xml b/java/res/xml/keystyle_devanagari_sign_virama.xml
index 0da116ab8..b22fbe842 100644
--- a/java/res/xml/key_hindi3_shift_right.xml
+++ b/java/res/xml/keystyle_devanagari_sign_virama.xml
@@ -20,17 +20,16 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- U+25CC: "◌" DOTTED CIRCLE
- U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R
- U+0944: "ॄ" DEVANAGARI VOWEL SIGN VOCALIC RR -->
- <Key
- latin:keyLabel="&#x25CC;&#x0943;"
- latin:code="0x0943"
- latin:moreKeys="&#x25CC;&#x0944;|&#x0944;"
+ U+094D: "्" DEVANAGARI SIGN VIRAMA -->
+ <key-style
+ latin:styleName="baseKeyDevanagariSignVirama"
+ latin:keyLabel="&#x25CC;&#x094D;"
+ latin:code="0x094D"
latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
-</merge>
+ </merge>
diff --git a/java/res/xml/key_hindi1_shift.xml b/java/res/xml/keystyle_devanagari_sign_visarga.xml
index 0db5ae9af..cb294951f 100644
--- a/java/res/xml/key_hindi1_shift.xml
+++ b/java/res/xml/keystyle_devanagari_sign_visarga.xml
@@ -20,14 +20,15 @@
<!-- The code point U+25CC for key label is needed because the font rendering system prior to
API version 16 can't automatically render dotted circle for incomplete combining letter
- of Hindi. The files named res/xml/{key,keys}_hindi*.xml have this U+25CC hack, although the
- counterpart files named res/xml-v16/{key,keys}_hindi*.xml don't have this hack. -->
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- U+25CC: "◌" DOTTED CIRCLE
U+0903: "ः" DEVANAGARI SIGN VISARGA -->
- <Key
+ <key-style
+ latin:styleName="baseKeyDevanagariSignVisarga"
latin:keyLabel="&#x25CC;&#x0903;"
latin:code="0x0903"
latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml b/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml
new file mode 100644
index 000000000..2e78c53ec
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+093E/U+0902: "ां" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN ANUSVARA
+ U+093E/U+0901: "ाँ" DEVANAGARI VOWEL SIGN AA/DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAa"
+ latin:moreKeys="&#x25CC;&#x093E;&#x0902;|&#x093E;&#x0902;,&#x25CC;&#x093E;&#x0901;|&#x093E;&#x0901;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAa" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+093E: "ा" DEVANAGARI VOWEL SIGN AA -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignAa"
+ latin:parentStyle="moreKeysDevanagariVowelSignAa"
+ latin:keyLabel="&#x25CC;&#x093E;"
+ latin:code="0x093E"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml b/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml
new file mode 100644
index 000000000..0554c0e15
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0948/U+0902: "ैं" DEVANAGARI VOWEL SIGN AI/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi"
+ latin:moreKeys="&#x25CC;&#x0948;&#x0902;|&#x0948;&#x0902;,%" />
+ </case>
+ <case
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <!-- U+0936/U+094D/U+0930: "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi"
+ latin:moreKeys="&#x0936;&#x094D;&#x0930;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0948: "ै" DEVANAGARI VOWEL SIGN AI -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignAi"
+ latin:parentStyle="moreKeysDevanagariVowelSignAi"
+ latin:keyLabel="&#x25CC;&#x0948;"
+ latin:code="0x0948"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_au.xml b/java/res/xml/keystyle_devanagari_vowel_sign_au.xml
new file mode 100644
index 000000000..29a11a82e
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_au.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+094C/U+0902: "ौं" DEVANAGARI VOWEL SIGN AU/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAu"
+ latin:moreKeys="&#x25CC;&#x094C;&#x0902;|&#x094C;&#x0902;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAu" />
+ </default>
+ </switch>
+ <!-- U+094C: "ौ" DEVANAGARI VOWEL SIGN AU -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignAu"
+ latin:parentStyle="moreKeysDevanagariVowelSignAu"
+ latin:keyLabel="&#x25CC;&#x094C;"
+ latin:code="0x094C"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_e.xml b/java/res/xml/keystyle_devanagari_vowel_sign_e.xml
new file mode 100644
index 000000000..edd29c791
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_e.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0947/U+0902: "ें" DEVANAGARI VOWEL SIGN E/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE"
+ latin:moreKeys="&#x25CC;&#x0947;&#x0902;|&#x0947;&#x0902;" />
+ </case>
+ <case
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0903: "ः‍" DEVANAGARI SIGN VISARGA
+ U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE"
+ latin:moreKeys="&#x25CC;&#x0903;|&#x0903;,&#x093D;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE" />
+ </default>
+ </switch>
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignE"
+ latin:parentStyle="moreKeysDevanagariVowelSignE"
+ latin:keyLabel="&#x25CC;&#x0947;"
+ latin:code="0x0947"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_i.xml b/java/res/xml/keystyle_devanagari_vowel_sign_i.xml
new file mode 100644
index 000000000..200fed29f
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_i.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+093F/U+0902: "िं" DEVANAGARI VOWEL SIGN I/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignI"
+ latin:moreKeys="&#x093F;&#x25CC;&#x0902;|&#x093F;&#x0902;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignI" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+093F: "ि" DEVANAGARI VOWEL SIGN I -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignI"
+ latin:parentStyle="moreKeysDevanagariVowelSignI"
+ latin:keyLabel="&#x25CC;&#x093F;"
+ latin:code="0x093F"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml b/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml
new file mode 100644
index 000000000..6dc9951df
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+0940: "ी" DEVANAGARI VOWEL SIGN II
+ U+0940/U+0902: "ीं" DEVANAGARI VOWEL SIGN II/DEVANAGARI SIGN ANUSVARA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignIi"
+ latin:moreKeys="&#x25CC;&#x0940;&#x0902;|&#x0940;&#x0902;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignIi" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0940: "ी" DEVANAGARI VOWEL SIGN II -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignIi"
+ latin:parentStyle="moreKeysDevanagariVowelSignIi"
+ latin:keyLabel="&#x25CC;&#x0940;"
+ latin:code="0x0940"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_o.xml b/java/res/xml/keystyle_devanagari_vowel_sign_o.xml
new file mode 100644
index 000000000..233ac8609
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_o.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+094B/U+0902: "қं" DEVANAGARI VOWEL SIGN O/DEVANAGARI SIGN ANUSVARA
+ U+0949: "ॉ" DEVANAGARI VOWEL SIGN CANDRA O
+ U+094A: "ॊ" DEVANAGARI VOWEL SIGN SHORT O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignO"
+ latin:moreKeys="&#x25CC;&#x094B;&#x0902;|&#x094B;&#x0902;,&#x25CC;&#x0949;|&#x0949;,&#x25CC;&#x094A;|&#x094A;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignO" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+094B: "ो" DEVANAGARI VOWEL SIGN O -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignO"
+ latin:parentStyle="moreKeysDevanagariVowelSignO"
+ latin:keyLabel="&#x25CC;&#x094B;"
+ latin:code="0x094B"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_u.xml b/java/res/xml/keystyle_devanagari_vowel_sign_u.xml
new file mode 100644
index 000000000..7291b7099
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_u.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0941/U+0902: "ुं" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN ANUSVARA
+ U+0941/U+0901: "ुँ" DEVANAGARI VOWEL SIGN U/DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignU"
+ latin:moreKeys="&#x25CC;&#x0941;&#x0902;|&#x0941;&#x0902;,&#x25CC;&#x0941;&#x0901;|&#x0941;&#x0901;" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignU" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0941: "ु" DEVANAGARI VOWEL SIGN U -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignU"
+ latin:parentStyle="moreKeysDevanagariVowelSignU"
+ latin:keyLabel="&#x25CC;&#x0941;"
+ latin:code="0x0941"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml b/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml
new file mode 100644
index 000000000..a95ab822d
--- /dev/null
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The code point U+25CC for key label is needed because the font rendering system prior to
+ API version 16 can't automatically render dotted circle for incomplete combining letter
+ of some scripts. The files named res/xml/key_*.xml have this U+25CC hack, although the
+ counterpart files named res/xml-v16/key_*.xml don't have this hack. -->
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSet="hindi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0942/U+0902: "ूं" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN ANUSVARA
+ U+0942/U+0901: "ूँ" DEVANAGARI VOWEL SIGN UU/DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignUu"
+ latin:moreKeys="&#x25CC;&#x0942;&#x0902;|&#x0942;&#x0902;,&#x25CC;&#x0942;&#x0901;|&#x0942;&#x0901;,%" />
+ </case>
+ <default>
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignUu" />
+ </default>
+ </switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0942: "ू" DEVANAGARI VOWEL SIGN UU -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignUu"
+ latin:parentStyle="moreKeysDevanagariVowelSignUu"
+ latin:keyLabel="&#x25CC;&#x0942;"
+ latin:code="0x0942"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 52d715a7a..f0e04c220 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -24,7 +24,7 @@
keyboard_locale: script_name/keyboard_layout_set
af: Afrikaans/qwerty
ar: Arabic/arabic
- (az: Azerbaijani/qwerty) # disabled temporarily. waiting for strnig resources.
+ az: Azerbaijani/qwerty
be: Belarusian/east_slavic
bg: Bulgarian/bulgarian
bg: Bulgarian/bulgarian_bds
@@ -47,19 +47,24 @@
hi: Hindi/hindi
hr: Croatian/qwertz
hu: Hungarian/qwertz
+ hy: Armenian Phonetic/armenian_phonetic
in: Indonesian/qwerty # "id" is official language code of Indonesian.
is: Icelandic/qwerty
it: Italian/qwerty
iw: Hebrew/hebrew # "he" is official language code of Hebrew.
ka: Georgian/georgian
(kk: Kazakh/east_slavic) # disabled temporarily. waiting for strnig resources.
+ km: Khmer/khmer
ky: Kyrgyz/east_slavic
+ lo: Lao/lao
lt: Lithuanian/qwerty
lv: Latvian/qwerty
mk: Macedonian/south_slavic
mn: Mongolian/mongolian
ms: Malay/qwerty
nb: Norwegian Bokmål/nordic
+ ne: Nepali Romanized/nepali_romanized # disabled temporarily
+ ne: Nepali Traditional/nepali_traditional # disabled temporarily
nl: Dutch/qwerty
nl_BE: Dutch Belgium/azerty
pl: Polish/qwerty
@@ -80,6 +85,7 @@
vi: Vietnamese/qwerty
zu: Zulu/qwerty
zz: QWERTY/qwerty
+ (zz: Emoji/emoji)
-->
<!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. -->
<!-- Note: SupportTouchPositionCorrection extra value is obsolete and maintained for backward
@@ -89,427 +95,474 @@
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
android:isDefault="@bool/im_is_default">
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_en_US"
android:subtypeId="0xc9194f98"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_en_GB"
android:subtypeId="0xb045e755"
android:imeSubtypeLocale="en_GB"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x6f972360"
android:imeSubtypeLocale="af"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x590dde40"
android:imeSubtypeLocale="ar"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <!--
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x70b0f974"
android:imeSubtypeLocale="az"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- -->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x1dc3a859"
android:imeSubtypeLocale="be"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x0ba9c0e8"
android:imeSubtypeLocale="bg"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_bulgarian_bds"
android:subtypeId="0x5f51ba9a"
android:imeSubtypeLocale="bg"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xd2e520d5"
android:imeSubtypeLocale="ca"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2d3d2ed0"
android:imeSubtypeLocale="cs"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2df4605d"
android:imeSubtypeLocale="da"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2e2cbe61"
android:imeSubtypeLocale="de"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x0e7802d3"
android:imeSubtypeLocale="el"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=greek"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=greek,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x4090554a"
android:imeSubtypeLocale="eo"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x30a6e00e"
android:imeSubtypeLocale="es"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_es_US"
android:subtypeId="0x84d2efc6"
android:imeSubtypeLocale="es_US"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
<!--
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x623f9286"
android:imeSubtypeLocale="es_419"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
-->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xec2d3955"
android:imeSubtypeLocale="et"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xbe66c254"
android:imeSubtypeLocale="fa"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=farsi"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=farsi,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x31cecda3"
android:imeSubtypeLocale="fi"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x324da12c"
android:imeSubtypeLocale="fr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xeadbb691"
android:imeSubtypeLocale="fr_CA"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x39753b7f"
android:imeSubtypeLocale="hi"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35b7526a"
android:imeSubtypeLocale="hr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35e198ed"
android:imeSubtypeLocale="hu"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
+ />
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_generic"
+ android:subtypeId="0xe39ac3ca"
+ android:imeSubtypeLocale="hy"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=armenian_phonetic,EmojiCapable"
/>
<!-- Java uses the deprecated "in" code instead of the standard "id" code for Indonesian. -->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x7daea460"
android:imeSubtypeLocale="in"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x7df519e5"
android:imeSubtypeLocale="is"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x37885a0b"
android:imeSubtypeLocale="it"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
<!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x66fb18bd"
android:imeSubtypeLocale="iw"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x6e119e6a"
android:imeSubtypeLocale="ka"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian,EmojiCapable"
/>
<!--
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2d73d2f6"
android:imeSubtypeLocale="kk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
-->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_generic"
+ android:subtypeId="0x1365683a"
+ android:imeSubtypeLocale="km"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=khmer,EmojiCapable"
+ />
+ <!-- android:subtypeId="Need this for km" -->
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2e391c04"
android:imeSubtypeLocale="ky"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
+ />
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_generic"
+ android:subtypeId="0x8315772c"
+ android:imeSubtypeLocale="lo"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=lao,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8321bb43"
android:imeSubtypeLocale="lt"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x833dea45"
android:imeSubtypeLocale="lv"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xaf50ab7c"
android:imeSubtypeLocale="mk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xcdcfc3ab"
android:imeSubtypeLocale="mn"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x84c87c61"
android:imeSubtypeLocale="ms"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3f12ee14"
android:imeSubtypeLocale="nb"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <!--
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_generic"
+ android:subtypeId="0xd80a4cee"
+ android:imeSubtypeLocale="ne"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_romanized,EmojiCapable"
+ />
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_nepali_traditional"
+ android:subtypeId="0x5fafea88"
+ android:imeSubtypeLocale="ne"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_traditional,EmojiCapable"
+ />
+ -->
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3f9fd91e"
android:imeSubtypeLocale="nl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x500ca92c"
android:imeSubtypeLocale="nl_BE"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x43098a5c"
android:imeSubtypeLocale="pl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xcafff4a6"
android:imeSubtypeLocale="pt_BR"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xe2fffc5a"
android:imeSubtypeLocale="pt_PT"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8d185978"
android:imeSubtypeLocale="ro"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x763a8752"
android:imeSubtypeLocale="ru"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8e94d413"
android:imeSubtypeLocale="sk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8ea2eb94"
android:imeSubtypeLocale="sl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x77c5196e"
android:imeSubtypeLocale="sr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
<!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_serbian_cyrillic"
android:subtypeId="0xXXXXXXXX"
android:imeSubtypeLocale="sr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_serbian_latin"
android:subtypeId="0xXXXXXXXX"
android:imeSubtypeLocale="sr-Latn"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
-->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x48b4ff43"
android:imeSubtypeLocale="sv"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8f3dee1f"
android:imeSubtypeLocale="sw"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x1f94d5d4"
android:imeSubtypeLocale="th"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=thai"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=thai,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xf08285ef"
android:imeSubtypeLocale="tl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x4a3179de"
android:imeSubtypeLocale="tr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3e84492c"
android:imeSubtypeLocale="uk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x93972eee"
android:imeSubtypeLocale="vi"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x9b13ab76"
android:imeSubtypeLocale="zu"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_no_language_qwerty"
android:subtypeId="0xa239ebad"
android:imeSubtypeLocale="zz"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable,EmojiCapable"
/>
+ <!-- Emoji subtype has to be an addtional subtype added at boot time because ICS doesn't
+ support Emoji. -->
+ <!--
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_emoji"
+ android:subtypeId="0xc14d88b2"
+ android:imeSubtypeLocale="zz"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=emoji,EmojiCapable"
+ />
+ -->
</input-method>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 2a726c438..6c36b0e89 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -42,13 +42,11 @@
android:title="@string/popup_on_keypress"
android:persistent="true"
android:defaultValue="@bool/config_default_key_preview_popup" />
- <ListPreference
- android:key="voice_mode"
+ <CheckBoxPreference
+ android:key="pref_voice_input_key"
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:defaultValue="true" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/correction_category"
diff --git a/java/res/xml/row_dvorak4.xml b/java/res/xml/row_dvorak4.xml
index e6d487e1d..02a95acea 100644
--- a/java/res/xml/row_dvorak4.xml
+++ b/java/res/xml/row_dvorak4.xml
@@ -65,7 +65,7 @@
</switch>
<include
latin:keyXPos="25%p"
- latin:keyboardLayout="@xml/key_space" />
+ latin:keyboardLayout="@xml/key_space_5kw" />
<Key
latin:keyLabel="z"
latin:keyLabelFlags="hasPopupHint"
diff --git a/java/res/xml/row_pcqwerty5.xml b/java/res/xml/row_pcqwerty5.xml
index a8940af6e..4ec908ba1 100644
--- a/java/res/xml/row_pcqwerty5.xml
+++ b/java/res/xml/row_pcqwerty5.xml
@@ -24,36 +24,23 @@
<Row
latin:keyWidth="7.692%p"
>
- <switch>
- <case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="11.538%p" />
- </case>
- <!-- keyboardLayoutSetElement="alphabet*" -->
- <default>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyIcon="!icon/undefined"
- latin:keyLabel="!text/label_to_symbol_key_pcqwerty"
- latin:keyWidth="11.538%p" />
- </default>
- </switch>
+ <Spacer
+ latin:keyWidth="11.538%p" />
<switch>
<case
latin:shortcutKeyEnabled="true"
>
<Key
- latin:keyStyle="shortcutKeyStyle" />
- </case>
+ latin:keyStyle="shortcutKeyStyle"
+ latin:keyWidth="11.538%p" />
+ </case>
<case
latin:clobberSettingsKey="false"
>
<Key
- latin:keyStyle="settingsKeyStyle" />
- </case>
+ latin:keyStyle="settingsKeyStyle"
+ latin:keyWidth="11.538%p" />
+ </case>
</switch>
<switch>
<case
@@ -61,21 +48,33 @@
>
<Key
latin:keyStyle="languageSwitchKeyStyle"
- latin:keyXPos="19.230%p" />
+ latin:keyWidth="11.538%p" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="53.844%p" />
- </case>
+ latin:keyWidth="38.464%p" />
+ </case>
<!-- languageSwitchKeyEnabled="false" -->
<default>
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyXPos="19.230%p"
- latin:keyWidth="61.536%p" />
+ latin:keyWidth="50.002%p" />
</default>
</switch>
<Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyStyle="defaultEnterKeyStyle"
+ latin:keyWidth="15.384%p" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+ >
+ <Spacer />
+ </case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
+ <default>
+ <Key
+ latin:keyStyle="emojiKeyStyle"
+ latin:keyWidth="fillRight" />
+ </default>
+ </switch>
</Row>
</merge>
diff --git a/java/res/xml/row_qwerty4.xml b/java/res/xml/row_qwerty4.xml
index c29fbf2f1..578bc1234 100644
--- a/java/res/xml/row_qwerty4.xml
+++ b/java/res/xml/row_qwerty4.xml
@@ -31,7 +31,7 @@
latin:keyboardLayout="@xml/key_f1" />
<include
latin:keyXPos="25%p"
- latin:keyboardLayout="@xml/key_space" />
+ latin:keyboardLayout="@xml/key_space_5kw" />
<switch>
<case
latin:languageCode="ar|fa"
@@ -42,6 +42,21 @@
latin:moreKeys="!text/more_keys_for_arabic_diacritics"
latin:keyStyle="punctuationKeyStyle" />
</case>
+ <case
+ latin:languageCode="ne"
+ latin:keyboardLayoutSet="nepali_traditional"
+ >
+ <include
+ latin:keyboardLayout="@xml/key_nepali_traditional_period" />
+ </case>
+ <case
+ latin:languageCode="hy"
+ >
+ <!-- U+0589: "։" ARMENIAN FULL STOP -->
+ <Key
+ latin:keyLabel="&#x0589;"
+ latin:keyStyle="punctuationKeyStyle" />
+ </case>
<default>
<Key
latin:keyStyle="punctuationKeyStyle" />
diff --git a/java/res/xml/row_symbols4.xml b/java/res/xml/row_symbols4.xml
index 150ad486c..0bf412fff 100644
--- a/java/res/xml/row_symbols4.xml
+++ b/java/res/xml/row_symbols4.xml
@@ -18,38 +18,29 @@
*/
-->
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="10%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="15%p" />
- <switch>
- <case
- latin:hasShortcutKey="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle" />
- </case>
- <!-- latin:hasShortcutKey="false" -->
- <default>
- <Key
- latin:keyLabel="!text/keylabel_for_comma"
- latin:keyLabelFlags="hasPopupHint"
- latin:additionalMoreKeys="!text/more_keys_for_comma"
- latin:keyStyle="f1MoreKeysStyle" />
- </default>
- </switch>
- <include
- latin:keyXPos="25%p"
- latin:keyboardLayout="@xml/key_space" />
- <Key
- latin:keyStyle="punctuationKeyStyle" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
+
+ <Key
+ latin:backgroundType="functional"
+ latin:keyLabel="_" />
+ <Key
+ latin:backgroundType="functional"
+ latin:keyLabel="/" />
+
+ <switch>
+ <case latin:hasShortcutKey="true" >
+ <Key latin:keyStyle="shortcutKeyStyle" />
+ </case>
+ <!-- latin:hasShortcutKey="false" -->
+ <default>
+ </default>
+ </switch>
+
+ <include latin:keyboardLayout="@xml/key_space_symbols" />
+ <include latin:keyboardLayout="@xml/keys_comma_period" />
+
+ <Key
+ latin:keyStyle="emojiKeyStyle"
+ latin:keyWidth="fillRight" />
+
</merge>
diff --git a/java/res/xml/row_symbols_shift4.xml b/java/res/xml/row_symbols_shift4.xml
index 99a685c45..72d24a321 100644
--- a/java/res/xml/row_symbols_shift4.xml
+++ b/java/res/xml/row_symbols_shift4.xml
@@ -17,31 +17,14 @@
** limitations under the License.
*/
-->
+<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
+
+ <include latin:keyboardLayout="@xml/keys_less_greater" />
+ <include
+ latin:keyboardLayout="@xml/key_space_symbols" />
+ <include latin:keyboardLayout="@xml/keys_comma_period" />
+
+ <include
+ latin:keyboardLayout="@xml/key_f2" />
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Row
- latin:keyWidth="10%p"
- >
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="15%p" />
- <!-- U+201A: "‚" SINGLE LOW-9 QUOTATION MARK
- U+201E: "„" DOUBLE LOW-9 QUOTATION MARK -->
- <Key
- latin:keyLabel="&#x201E;"
- latin:moreKeys="&#x201A;"
- latin:backgroundType="functional" />
- <include
- latin:keyXPos="25%p"
- latin:keyboardLayout="@xml/key_space" />
- <!-- U+2026: "…" HORIZONTAL ELLIPSIS -->
- <Key
- latin:keyLabel="&#x2026;"
- latin:backgroundType="functional" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
- </Row>
</merge>
diff --git a/java/res/xml/rowkeys_armenian_phonetic1.xml b/java/res/xml/rowkeys_armenian_phonetic1.xml
new file mode 100644
index 000000000..1984fae8a
--- /dev/null
+++ b/java/res/xml/rowkeys_armenian_phonetic1.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- U+0567: "է" ARMENIAN SMALL LETTER EH -->
+ <Key
+ latin:keyLabel="&#x0567;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0569: "թ" ARMENIAN SMALL LETTER TO -->
+ <Key
+ latin:keyLabel="&#x0569;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0583: "փ" ARMENIAN SMALL LETTER PIWR -->
+ <Key
+ latin:keyLabel="&#x0583;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0571: "ձ" ARMENIAN SMALL LETTER JA -->
+ <Key
+ latin:keyLabel="&#x0571;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+057B: "ջ" ARMENIAN SMALL LETTER JHEH -->
+ <Key
+ latin:keyLabel="&#x057B;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0580: "ր" ARMENIAN SMALL LETTER REH -->
+ <Key
+ latin:keyLabel="&#x0580;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0579: "չ" ARMENIAN SMALL LETTER CHA -->
+ <Key
+ latin:keyLabel="&#x0579;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0573: "ճ" ARMENIAN SMALL LETTER CHEH -->
+ <Key
+ latin:keyLabel="&#x0573;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+056A: "ժ" ARMENIAN SMALL LETTER ZHE -->
+ <Key
+ latin:keyLabel="&#x056A;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+056E: "ծ" ARMENIAN SMALL LETTER CA -->
+ <Key
+ latin:keyLabel="&#x056E;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml/rowkeys_armenian_phonetic2.xml b/java/res/xml/rowkeys_armenian_phonetic2.xml
new file mode 100644
index 000000000..5dcabc301
--- /dev/null
+++ b/java/res/xml/rowkeys_armenian_phonetic2.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- U+0584: "ք" ARMENIAN SMALL LETTER KEH -->
+ <Key
+ latin:keyLabel="&#x0584;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0578: "ո" ARMENIAN SMALL LETTER VO -->
+ <Key
+ latin:keyLabel="&#x0578;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0565: "ե" ARMENIAN SMALL LETTER ECH
+ U+0587: "և" ARMENIAN SMALL LIGATURE ECH YIWN -->
+ <Key
+ latin:keyLabel="&#x0565;"
+ latin:moreKeys="&#x0587;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+057C: "ռ" ARMENIAN SMALL LETTER RA -->
+ <Key
+ latin:keyLabel="&#x057C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+057F: "տ" ARMENIAN SMALL LETTER TIWN -->
+ <Key
+ latin:keyLabel="&#x057F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0568: "ը" ARMENIAN SMALL LETTER ET -->
+ <Key
+ latin:keyLabel="&#x0568;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0582: "ւ" ARMENIAN SMALL LETTER YIWN -->
+ <Key
+ latin:keyLabel="&#x0582;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+056B: "ի" ARMENIAN SMALL LETTER INI -->
+ <Key
+ latin:keyLabel="&#x056B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0585: "օ" ARMENIAN SMALL LETTER OH -->
+ <Key
+ latin:keyLabel="&#x0585;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+057A: "պ" ARMENIAN SMALL LETTER PEH -->
+ <Key
+ latin:keyLabel="&#x057A;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml-sw768dp/rowkeys_thai_digits.xml b/java/res/xml/rowkeys_armenian_phonetic3.xml
index 55196ebc3..3116811b3 100644
--- a/java/res/xml-sw768dp/rowkeys_thai_digits.xml
+++ b/java/res/xml/rowkeys_armenian_phonetic3.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -21,44 +21,40 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- U+0E51: "๑" THAI DIGIT ONE -->
+ <!-- U+0561: "ա" ARMENIAN SMALL LETTER AYB -->
<Key
- latin:keyLabel="&#x0E51;"
+ latin:keyLabel="&#x0561;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E52: "๒" THAI DIGIT TWO -->
+ <!-- U+057D: "ս" ARMENIAN SMALL LETTER SEH -->
<Key
- latin:keyLabel="&#x0E52;"
+ latin:keyLabel="&#x057D;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E53: "๓" THAI DIGIT THREE -->
+ <!-- U+0564: "դ" ARMENIAN SMALL LETTER DA -->
<Key
- latin:keyLabel="&#x0E53;"
+ latin:keyLabel="&#x0564;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E54: "๔" THAI DIGIT FOUR -->
+ <!-- U+0586: "ֆ" ARMENIAN SMALL LETTER FEH -->
<Key
- latin:keyLabel="&#x0E54;"
+ latin:keyLabel="&#x0586;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E55: "๕" THAI DIGIT FIVE -->
+ <!-- U+0563: "գ" ARMENIAN SMALL LETTER GIM -->
<Key
- latin:keyLabel="&#x0E55;"
+ latin:keyLabel="&#x0563;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E56: "๖" THAI DIGIT SIX -->
+ <!-- U+0570: "հ" ARMENIAN SMALL LETTER HO -->
<Key
- latin:keyLabel="&#x0E56;"
+ latin:keyLabel="&#x0570;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E57: "๗" THAI DIGIT SEVEN -->
+ <!-- U+0575: "յ" ARMENIAN SMALL LETTER YI -->
<Key
- latin:keyLabel="&#x0E57;"
+ latin:keyLabel="&#x0575;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E58: "๘" THAI DIGIT EIGHT -->
+ <!-- U+056F: "կ" ARMENIAN SMALL LETTER KEN -->
<Key
- latin:keyLabel="&#x0E58;"
+ latin:keyLabel="&#x056F;"
latin:keyLabelFlags="fontNormal" />
- <!-- U+0E59: "๙" THAI DIGIT NINE -->
+ <!-- U+056C: "լ" ARMENIAN SMALL LETTER LIWN -->
<Key
- latin:keyLabel="&#x0E59;"
- latin:keyLabelFlags="fontNormal" />
- <!-- U+0E50: "๐" THAI DIGIT ZERO -->
- <Key
- latin:keyLabel="&#x0E50;"
+ latin:keyLabel="&#x056C;"
latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml/rowkeys_armenian_phonetic4.xml b/java/res/xml/rowkeys_armenian_phonetic4.xml
new file mode 100644
index 000000000..922481add
--- /dev/null
+++ b/java/res/xml/rowkeys_armenian_phonetic4.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- U+0566: "զ" ARMENIAN SMALL LETTER ZA -->
+ <Key
+ latin:keyLabel="&#x0566;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0572: "ղ" ARMENIAN SMALL LETTER GHAD -->
+ <Key
+ latin:keyLabel="&#x0572;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0581: "ց" ARMENIAN SMALL LETTER CO -->
+ <Key
+ latin:keyLabel="&#x0581;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+057E: "վ" ARMENIAN SMALL LETTER VEW -->
+ <Key
+ latin:keyLabel="&#x057E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0562: "բ" ARMENIAN SMALL LETTER BEN -->
+ <Key
+ latin:keyLabel="&#x0562;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0576: "ն" ARMENIAN SMALL LETTER NOW -->
+ <Key
+ latin:keyLabel="&#x0576;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0574: "մ" ARMENIAN SMALL LETTER MEN -->
+ <Key
+ latin:keyLabel="&#x0574;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml/rowkeys_hindi1.xml b/java/res/xml/rowkeys_hindi1.xml
index 745747643..c0b3cb913 100644
--- a/java/res/xml/rowkeys_hindi1.xml
+++ b/java/res/xml/rowkeys_hindi1.xml
@@ -62,10 +62,12 @@
latin:keyLabel="&#x092D;"
latin:keyLabelFlags="fontNormal" />
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
<include
- latin:keyboardLayout="@xml/key_hindi1_shift" />
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_visarga" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVisarga" />
<!-- U+0918: "घ" DEVANAGARI LETTER GHA -->
<Key
latin:keyLabel="&#x0918;"
@@ -88,11 +90,57 @@
</case>
<default>
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+0967: "१" DEVANAGARI DIGIT ONE -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAu"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="&#x0967;,1" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+0968: "२" DEVANAGARI DIGIT TWO -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAi"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="&#x0968;,2" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+0969: "३" DEVANAGARI DIGIT THREE -->
<include
- latin:keyboardLayout="@xml/keys_hindi1_left5" />
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_aa" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAa"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="&#x0969;,3" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+096A: "४" DEVANAGARI DIGIT FOUR -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ii" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignIi"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="&#x096A;,4" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+096B: "५" DEVANAGARI DIGIT FIVE -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_uu" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignUu"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="&#x096B;,5" />
<!-- U+092C: "ब" DEVANAGARI LETTER BA
+ U+096C: "६" DEVANAGARI DIGIT SIX
U+092C/U+0952: "ब॒" DEVANAGARI LETTER BA/DEVANAGARI STRESS SIGN ANUDATTA -->
<Key
latin:keyLabel="&#x092C;"
diff --git a/java/res/xml/rowkeys_hindi2.xml b/java/res/xml/rowkeys_hindi2.xml
index 9545b840f..70ac66ee4 100644
--- a/java/res/xml/rowkeys_hindi2.xml
+++ b/java/res/xml/rowkeys_hindi2.xml
@@ -97,10 +97,40 @@
</case>
<default>
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
<include
- latin:keyboardLayout="@xml/keys_hindi2_left5" />
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_o" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignO" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignE" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVirama" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_i" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignI" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_u" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignU" />
<!-- U+092A: "प" DEVANAGARI LETTER PA -->
<Key
latin:keyLabel="&#x092A;"
diff --git a/java/res/xml/rowkeys_hindi3.xml b/java/res/xml/rowkeys_hindi3.xml
index 3014907ed..136bc5f22 100644
--- a/java/res/xml/rowkeys_hindi3.xml
+++ b/java/res/xml/rowkeys_hindi3.xml
@@ -30,10 +30,10 @@
latin:keyLabel="&#x0911;"
latin:keyLabelFlags="fontNormal" />
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
<include
- latin:keyboardLayout="@xml/key_hindi3_shift_left" />
+ latin:keyboardLayout="@xml/key_devanagari_sign_candrabindu" />
<!-- U+0923: "ण" DEVANAGARI LETTER NNA -->
<Key
latin:keyLabel="&#x0923;"
@@ -56,10 +56,10 @@
latin:keyLabel="&#x0937;"
latin:keyLabelFlags="fontNormal" />
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
<include
- latin:keyboardLayout="@xml/key_hindi3_shift_right" />
+ latin:keyboardLayout="@xml/key_devanagari_vowel_sign_vocalic_r" />
<!-- U+091E: "ञ" DEVANAGARI LETTER NYA -->
<Key
latin:keyLabel="&#x091E;"
@@ -67,10 +67,12 @@
</case>
<default>
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
<include
- latin:keyboardLayout="@xml/keys_hindi3_left2" />
+ latin:keyboardLayout="@xml/key_devanagari_vowel_sign_candra_o" />
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_sign_anusvara" />
<!-- U+092E: "म" DEVANAGARI LETTER MA
U+0950: "ॐ" DEVANAGARI OM -->
<Key
@@ -107,10 +109,10 @@
latin:moreKeys="&#x095F;"
latin:keyLabelFlags="fontNormal" />
<!-- Because the font rendering system prior to API version 16 can't automatically
- render dotted circle for incomplete combining letter of Hindi, different set of
- Key definitions are needed based on the API version. -->
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
<include
- latin:keyboardLayout="@xml/key_hindi3_right" />
+ latin:keyboardLayout="@xml/key_devanagari_sign_nukta" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/rowkeys_khmer1.xml b/java/res/xml/rowkeys_khmer1.xml
new file mode 100644
index 000000000..25da66400
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer1.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+200D: ZERO WIDTH JOINER -->
+ <Key
+ latin:keyLabel="!"
+ latin:moreKeys="!icon/zwj_key|&#x200D;" />
+ <!-- U+17D7: "ៗ" KHMER SIGN LEK TOO
+ U+200C: ZERO WIDTH NON-JOINER -->
+ <Key
+ latin:keyLabel="&#x17D7;"
+ latin:moreKeys="!icon/zwnj_key|&#x200C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D1: "៑" KHMER SIGN VIRIAM -->
+ <Key
+ latin:keyLabel="&quot;"
+ latin:keyHintLabel="&#x17D1;"
+ latin:moreKeys="&#x17D1;" />
+ <!-- U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
+ U+20AC: "€" EURO SIGN -->
+ <Key
+ latin:keyLabel="&#x17DB;"
+ latin:keyHintLabel="$"
+ latin:moreKeys="$,&#x20AC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D6: "៖" KHMER SIGN CAMNUC PII KUUH -->
+ <Key
+ latin:keyLabel="%"
+ latin:keyHintLabel="&#x17D6;"
+ latin:moreKeys="&#x17D6;" />
+ <!-- U+17CD: "៍" KHMER SIGN TOANDAKHIAT
+ U+17D9: "៙" KHMER SIGN PHNAEK MUAN -->
+ <Key
+ latin:keyLabel="&#x17CD;"
+ latin:keyHintLabel="&#x17D9;"
+ latin:moreKeys="&#x17D9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D0: "័" KHMER SIGN SAMYOK SANNYA
+ U+17DA: "៚" KHMER SIGN KOOMUUT -->
+ <Key
+ latin:keyLabel="&#x17D0;"
+ latin:keyHintLabel="&#x17DA;"
+ latin:moreKeys="&#x17DA;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CF: "៏" KHMER SIGN AHSDA -->
+ <Key
+ latin:keyLabel="&#x17CF;"
+ latin:keyHintLabel="*"
+ latin:moreKeys="*"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel="("
+ latin:keyHintLabel="{"
+ latin:moreKeys="{,&#x00AB;" />
+ <!-- U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel=")"
+ latin:keyHintLabel="}"
+ latin:moreKeys="},&#x00BB;" />
+ <!-- U+17CC: "៌" KHMER SIGN ROBAT
+ U+00D7: "×" MULTIPLICATION SIGN -->
+ <Key
+ latin:keyLabel="&#x17CC;"
+ latin:keyHintLabel="&#x00D7;"
+ latin:moreKeys="&#x00D7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CE: "៎" KHMER SIGN KAKABAT -->
+ <Key
+ latin:keyLabel="&#x17CE;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+17E1: "១" KHMER DIGIT ONE
+ U+17F1: "៱" KHMER SYMBOL LEK ATTAK MUOY -->
+ <Key
+ latin:keyLabel="&#x17E1;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1"
+ latin:moreKeys="&#x17F1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E2: "២" KHMER DIGIT TWO
+ U+17F2: "៲" KHMER SYMBOL LEK ATTAK PII -->
+ <Key
+ latin:keyLabel="&#x17E2;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2"
+ latin:moreKeys="&#x17F2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E3: "៣" KHMER DIGIT THREE
+ U+17F3: "៳" KHMER SYMBOL LEK ATTAK BEI -->
+ <Key
+ latin:keyLabel="&#x17E3;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
+ latin:moreKeys="&#x17F3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E4: "៤" KHMER DIGIT FOUR
+ U+17F4: "៴" KHMER SYMBOL LEK ATTAK BUON -->
+ <Key
+ latin:keyLabel="&#x17E4;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
+ latin:moreKeys="&#x17F4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E5: "៥" KHMER DIGIT FIVE
+ U+17F5: "៵" KHMER SYMBOL LEK ATTAK PRAM -->
+ <Key
+ latin:keyLabel="&#x17E5;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
+ latin:moreKeys="&#x17F5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E6: "៦" KHMER DIGIT SIX
+ U+17F6: "៶" KHMER SYMBOL LEK ATTAK PRAM-MUOY -->
+ <Key
+ latin:keyLabel="&#x17E6;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
+ latin:moreKeys="&#x17F6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E7: "៧" KHMER DIGIT SEVEN
+ U+17F7: "៷" KHMER SYMBOL LEK ATTAK PRAM-PII -->
+ <Key
+ latin:keyLabel="&#x17E7;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
+ latin:moreKeys="&#x17F7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E8: "៨" KHMER DIGIT EIGHT
+ U+17F8: "៸" KHMER SYMBOL LEK ATTAK PRAM-BEI -->
+ <Key
+ latin:keyLabel="&#x17E8;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
+ latin:moreKeys="&#x17F8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E9: "៩" KHMER DIGIT NINE
+ U+17F9: "៹" KHMER SYMBOL LEK ATTAK PRAM-BUON -->
+ <Key
+ latin:keyLabel="&#x17E9;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
+ latin:moreKeys="&#x17F9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E0: "០" KHMER DIGIT ZERO
+ U+17F0: "៰" KHMER SYMBOL LEK ATTAK SON -->
+ <Key
+ latin:keyLabel="&#x17E0;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0"
+ latin:moreKeys="&#x17F0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A5: "ឥ" KHMER INDEPENDENT VOWEL QI
+ U+17A6: "ឦ" KHMER INDEPENDENT VOWEL QII -->
+ <Key
+ latin:keyLabel="&#x17A5;"
+ latin:keyHintLabel="&#x17A6;"
+ latin:moreKeys=",&#x17A6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B2: "ឲ" KHMER INDEPENDENT VOWEL QOO TYPE TWO
+ U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE -->
+ <Key
+ latin:keyLabel="&#x17B2;"
+ latin:keyHintLabel="&#x17B1;"
+ latin:moreKeys="&#x17B1;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_khmer2.xml b/java/res/xml/rowkeys_khmer2.xml
new file mode 100644
index 000000000..cba2d3b90
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer2.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+1788: "ឈ" KHMER LETTER CHO
+ U+17DC: "ៜ" KHMER SIGN AVAKRAHASANYA -->
+ <Key
+ latin:keyLabel="&#x1788;"
+ latin:keyHintLabel="&#x17DC;"
+ latin:moreKeys="&#x17DC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BA: "ឺ" KHMER VOWEL SIGN YY
+ U+17DD: "៝" KHMER SIGN ATTHACAN -->
+ <Key
+ latin:keyLabel="&#x17BA;"
+ latin:keyHintLabel="&#x17DD;"
+ latin:moreKeys="&#x17DD;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C2: "ែ" KHMER VOWEL SIGN AE -->
+ <Key
+ latin:keyLabel="&#x17C2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AC: "ឬ" KHMER INDEPENDENT VOWEL RYY
+ U+17AB: "ឫ" KHMER INDEPENDENT VOWEL RY -->
+ <Key
+ latin:keyLabel="&#x17AC;"
+ latin:keyHintLabel="&#x17AB;"
+ latin:moreKeys="&#x17AB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1791: "ទ" KHMER LETTER TO -->
+ <Key
+ latin:keyLabel="&#x1791;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BD: "ួ" KHMER VOWEL SIGN UA -->
+ <Key
+ latin:keyLabel="&#x17BD;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BC: "ូ" KHMER VOWEL SIGN UU -->
+ <Key
+ latin:keyLabel="&#x17BC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B8: "ី" KHMER VOWEL SIGN II -->
+ <Key
+ latin:keyLabel="&#x17B8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C5: "ៅ" KHMER VOWEL SIGN AU -->
+ <Key
+ latin:keyLabel="&#x17C5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1797: "ភ" KHMER LETTER PHO -->
+ <Key
+ latin:keyLabel="&#x1797;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BF: "ឿ" KHMER VOWEL SIGN YA -->
+ <Key
+ latin:keyLabel="&#x17BF;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI -->
+ <Key
+ latin:keyLabel="&#x17B0;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+1786: "ឆ" KHMER LETTER CHA -->
+ <Key
+ latin:keyLabel="&#x1786;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B9: "ឹ" KHMER VOWEL SIGN Y -->
+ <Key
+ latin:keyLabel="&#x17B9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C1: "េ" KHMER VOWEL SIGN E -->
+ <Key
+ latin:keyLabel="&#x17C1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179A: "រ" KHMER LETTER RO -->
+ <Key
+ latin:keyLabel="&#x179A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178F: "ត" KHMER LETTER TA -->
+ <Key
+ latin:keyLabel="&#x178F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1799: "យ" KHMER LETTER YO -->
+ <Key
+ latin:keyLabel="&#x1799;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BB: "ុ" KHMER VOWEL SIGN U -->
+ <Key
+ latin:keyLabel="&#x17BB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B7: "ិ" KHMER VOWEL SIGN I -->
+ <Key
+ latin:keyLabel="&#x17B7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C4: "ោ" KHMER VOWEL SIGN OO -->
+ <Key
+ latin:keyLabel="&#x17C4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1795: "ផ" KHMER LETTER PHA -->
+ <Key
+ latin:keyLabel="&#x1795;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C0: "ៀ" KHMER VOWEL SIGN IE -->
+ <Key
+ latin:keyLabel="&#x17C0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AA: "ឪ" KHMER INDEPENDENT VOWEL QUUV
+ U+17A7: "ឧ" KHMER INDEPENDENT VOWEL QU
+ U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE
+ U+17B3: "ឳ" KHMER INDEPENDENT VOWEL QAU
+ U+17A9: "ឩ" KHMER INDEPENDENT VOWEL QUU
+ U+17A8: "ឨ" KHMER INDEPENDENT VOWEL QUK -->
+ <Key
+ latin:keyLabel="&#x17AA;"
+ latin:keyHintLabel="&#x17A7;"
+ latin:moreKeys="&#x17A7;,&#x17B1;,&#x17B3;,&#x17A9;,&#x17A8;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_khmer3.xml b/java/res/xml/rowkeys_khmer3.xml
new file mode 100644
index 000000000..ff6c9ca51
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer3.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+17B6/U+17C6: "ាំ" KHMER VOWEL SIGN AA/KHMER SIGN NIKAHIT -->
+ <Key
+ latin:keyLabel="&#x17B6;&#x17C6;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+17C3: "ៃ" KHMER VOWEL SIGN AI -->
+ <Key
+ latin:keyLabel="&#x17C3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178C: "ឌ" KHMER LETTER DO -->
+ <Key
+ latin:keyLabel="&#x178C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1792: "ធ" KHMER LETTER THO -->
+ <Key
+ latin:keyLabel="&#x1792;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A2: "អ" KHMER LETTER QA -->
+ <Key
+ latin:keyLabel="&#x17A2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C7: "ះ" KHMER SIGN REAHMUK
+ U+17C8: "ៈ" KHMER SIGN YUUKALEAPINTU;-->
+ <Key
+ latin:keyLabel="&#x17C7;"
+ latin:keyHintLabel="&#x17C8;"
+ latin:moreKeys="&#x17C8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1789: "ញ" KHMER LETTER NYO -->
+ <Key
+ latin:keyLabel="&#x1789;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1782: "គ" KHMER LETTER KO
+ U+179D: "ឝ" KHMER LETTER SHA -->
+ <Key
+ latin:keyLabel="&#x1782;"
+ latin:keyHintLabel="&#x179D;"
+ latin:moreKeys="&#x179D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A1: "ឡ" KHMER LETTER LA -->
+ <Key
+ latin:keyLabel="&#x17A1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C4/U+17C7: "ោះ" KHMER VOWEL SIGN OO/KHMER SIGN REAHMUK -->
+ <Key
+ latin:keyLabel="&#x17C4;&#x17C7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C9: "៉" KHMER SIGN MUUSIKATOAN -->
+ <Key
+ latin:keyLabel="&#x17C9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AF: "ឯ" KHMER INDEPENDENT VOWEL QE -->
+ <Key
+ latin:keyLabel="&#x17AF;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+17B6: "ា" KHMER VOWEL SIGN AA -->
+ <Key
+ latin:keyLabel="&#x17B6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179F: "ស" KHMER LETTER SA -->
+ <Key
+ latin:keyLabel="&#x179F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178A: "ដ" KHMER LETTER DA -->
+ <Key
+ latin:keyLabel="&#x178A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1790: "ថ" KHMER LETTER THA -->
+ <Key
+ latin:keyLabel="&#x1790;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1784: "ង" KHMER LETTER NGO -->
+ <Key
+ latin:keyLabel="&#x1784;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A0: "ហ" KHMER LETTER HA -->
+ <Key
+ latin:keyLabel="&#x17A0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D2: "្" KHMER SIGN COENG -->
+ <Key
+ latin:keyLabel="&#x17D2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1780: "ក" KHMER LETTER KA -->
+ <Key
+ latin:keyLabel="&#x1780;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179B: "ល" KHMER LETTER LO -->
+ <Key
+ latin:keyLabel="&#x179B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BE: "ើ" KHMER VOWEL SIGN OE -->
+ <Key
+ latin:keyLabel="&#x17BE;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CB: "់" KHMER SIGN BANTOC -->
+ <Key
+ latin:keyLabel="&#x17CB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AE: "ឮ" KHMER INDEPENDENT VOWEL LYY
+ U+17AD: "ឭ" KHMER INDEPENDENT VOWEL LY
+ U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI -->
+ <Key
+ latin:keyLabel="&#x17AE;"
+ latin:keyHintLabel="&#x17AD;"
+ latin:moreKeys="&#x17AD;,&#x17B0;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_khmer4.xml b/java/res/xml/rowkeys_khmer4.xml
new file mode 100644
index 000000000..fe6c59125
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer4.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+178D: "ឍ" KHMER LETTER TTHO -->
+ <Key
+ latin:keyLabel="&#x178D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1783: "ឃ" KHMER LETTER KHO -->
+ <Key
+ latin:keyLabel="&#x1783;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1787: "ជ" KHMER LETTER CO -->
+ <Key
+ latin:keyLabel="&#x1787;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C1/U+17C7: "េះ" KHMER VOWEL SIGN E/KHMER SIGN REAHMUK -->
+ <Key
+ latin:keyLabel="&#x17C1;&#x17C7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1796: "ព" KHMER LETTER PO
+ U+179E: "ឞ" KHMER LETTER SSO -->
+ <Key
+ latin:keyLabel="&#x1796;"
+ latin:keyHintLabel="&#x179E;"
+ latin:moreKeys="&#x179E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178E: "ណ" KHMER LETTER NNO -->
+ <Key
+ latin:keyLabel="&#x178E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C6: "ំ" KHMER SIGN NIKAHIT -->
+ <Key
+ latin:keyLabel="&#x17C6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BB/U+17C7: "ុះ" KHMER VOWEL SIGN U/KHMER SIGN REAHMUK -->
+ <Key
+ latin:keyLabel="&#x17BB;&#x17C7;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+17D5: "៕" KHMER SIGN BARIYOOSAN -->
+ <Key
+ latin:keyLabel="&#x17D5;"
+ latin:keyLabelFlags="fontNormal" />
+ <Key
+ latin:keyLabel="\?" />
+ </case>
+ <default>
+ <!-- U+178B: "ឋ" KHMER LETTER TTHA -->
+ <Key
+ latin:keyLabel="&#x178B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1781: "ខ" KHMER LETTER KHA -->
+ <Key
+ latin:keyLabel="&#x1781;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1785: "ច" KHMER LETTER CA -->
+ <Key
+ latin:keyLabel="&#x1785;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179C: "វ" KHMER LETTER VO -->
+ <Key
+ latin:keyLabel="&#x179C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1794: "ប" KHMER LETTER BA -->
+ <Key
+ latin:keyLabel="&#x1794;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1793: "ន" KHMER LETTER NO -->
+ <Key
+ latin:keyLabel="&#x1793;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1798: "ម" KHMER LETTER MO -->
+ <Key
+ latin:keyLabel="&#x1798;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BB/U+17C6: "ុំ" KHMER VOWEL SIGN U/KHMER SIGN NIKAHIT -->
+ <Key
+ latin:keyLabel="&#x17BB;&#x17C6;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+17D4: "។" KHMER SIGN KHAN -->
+ <Key
+ latin:keyLabel="&#x17D4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CA: "៊" KHMER SIGN TRIISAP -->
+ <Key
+ latin:keyLabel="&#x17CA;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_lao1.xml b/java/res/xml/rowkeys_lao1.xml
new file mode 100644
index 000000000..fa1ad97d8
--- /dev/null
+++ b/java/res/xml/rowkeys_lao1.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0ED1: "໑" LAO DIGIT ONE -->
+ <Key
+ latin:keyLabel="&#x0ED1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED2: "໒" LAO DIGIT TWO -->
+ <Key
+ latin:keyLabel="&#x0ED2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED3: "໓" LAO DIGIT THREE -->
+ <Key
+ latin:keyLabel="&#x0ED3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED4: "໔" LAO DIGIT FOUR -->
+ <Key
+ latin:keyLabel="&#x0ED4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ECC: "໌" LAO CANCELLATION MARK -->
+ <Key
+ latin:keyLabel="&#x0ECC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EBC: "ຼ" LAO SEMIVOWEL SIGN LO -->
+ <Key
+ latin:keyLabel="&#x0EBC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED5: "໕" LAO DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0ED5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED6: "໖" LAO DIGIT SIX -->
+ <Key
+ latin:keyLabel="&#x0ED6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED7: "໗" LAO DIGIT SEVEN -->
+ <Key
+ latin:keyLabel="&#x0ED7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED8: "໘" LAO DIGIT EIGHT -->
+ <Key
+ latin:keyLabel="&#x0ED8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ED9: "໙" LAO DIGIT NINE -->
+ <Key
+ latin:keyLabel="&#x0ED9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ECD/U+0EC8: "ໍ່" LAO NIGGAHITA/LAO TONE MAI EK -->
+ <Key
+ latin:keyLabel="&#x0ECD;&#x0EC8;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ </case>
+ <default>
+ <!-- U+0EA2: "ຢ" LAO LETTER YO
+ U+0ED1: "໑" LAO DIGIT ONE -->
+ <Key
+ latin:keyLabel="&#x0EA2;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1"
+ latin:moreKeys="&#x0ED1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E9F: "ຟ" LAO LETTER FO SUNG
+ U+0ED2: "໒" LAO DIGIT TWO -->
+ <Key
+ latin:keyLabel="&#x0E9F;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2"
+ latin:moreKeys="&#x0ED2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC2: "ໂ" LAO VOWEL SIGN O
+ U+0ED3: "໓" LAO DIGIT THREE -->
+ <Key
+ latin:keyLabel="&#x0EC2;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
+ latin:moreKeys="&#x0ED3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E96: "ຖ" LAO LETTER THO SUNG
+ U+0ED4: "໔" LAO DIGIT FOUR -->
+ <Key
+ latin:keyLabel="&#x0E96;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
+ latin:moreKeys="&#x0ED4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB8: "ຸ" LAO VOWEL SIGN U -->
+ <Key
+ latin:keyLabel="&#x0EB8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB9: "ູ" LAO VOWEL SIGN UU -->
+ <Key
+ latin:keyLabel="&#x0EB9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E84: "ຄ" LAO LETTER KHO TAM
+ U+0ED5: "໕" LAO DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0E84;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
+ latin:moreKeys="&#x0ED5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E95: "ຕ" LAO LETTER TO
+ U+0ED6: "໖" LAO DIGIT SIX -->
+ <Key
+ latin:keyLabel="&#x0E95;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
+ latin:moreKeys="&#x0ED6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E88: "ຈ" LAO LETTER CO
+ U+0ED7: "໗" LAO DIGIT SEVEN -->
+ <Key
+ latin:keyLabel="&#x0E88;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
+ latin:moreKeys="&#x0ED7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E82: "ຂ" LAO LETTER KHO SUNG
+ U+0ED8: "໘" LAO DIGIT EIGHT -->
+ <Key
+ latin:keyLabel="&#x0E82;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
+ latin:moreKeys="&#x0ED8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E8A: "ຊ" LAO LETTER SO TAM
+ U+0ED9: "໙" LAO DIGIT NINE -->
+ <Key
+ latin:keyLabel="&#x0E8A;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
+ latin:moreKeys="&#x0ED9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ECD: "ໍ" LAO NIGGAHITA -->
+ <Key
+ latin:keyLabel="&#x0ECD;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_lao2.xml b/java/res/xml/rowkeys_lao2.xml
new file mode 100644
index 000000000..fca58ac0e
--- /dev/null
+++ b/java/res/xml/rowkeys_lao2.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0EBB/U+0EC9: "" LAO VOWEL SIGN MAI KON/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EBB;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0ED0: "໐" LAO DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x0ED0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB3/U+0EC9: "ຳ້" LAO VOWEL SIGN AM/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EB3;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <Key
+ latin:keyLabel="_" />
+ <Key
+ latin:keyLabel="+" />
+ <!-- U+0EB4/U+0EC9: "ິ້" LAO VOWEL SIGN I/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EB4;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0EB5/U+0EC9: "ີ້" LAO VOWEL SIGN II/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EB5;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0EA3: "ຣ" LAO LETTER LO LING -->
+ <Key
+ latin:keyLabel="&#x0EA3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EDC: "ໜ" LAO HO NO -->
+ <Key
+ latin:keyLabel="&#x0EDC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EBD: "ຽ" LAO SEMIVOWEL SIGN NYO -->
+ <Key
+ latin:keyLabel="&#x0EBD;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EAB/U+0EBC: "" LAO LETTER HO SUNG/LAO SEMIVOWEL SIGN LO -->
+ <Key
+ latin:keyLabel="&#x0EAB;&#x0EBC;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+201D: "”" RIGHT DOUBLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel="&#x201D;" />
+ </case>
+ <default>
+ <!-- U+0EBB: "ົ" LAO VOWEL SIGN MAI KON -->
+ <Key
+ latin:keyLabel="&#x0EBB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC4: "ໄ" LAO VOWEL SIGN AI
+ U+0ED0: "໐" LAO DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x0EC4;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0"
+ latin:moreKeys="&#x0ED0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB3: "ຳ" LAO VOWEL SIGN AM -->
+ <Key
+ latin:keyLabel="&#x0EB3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E9E: "ພ" LAO LETTER PHO TAM -->
+ <Key
+ latin:keyLabel="&#x0E9E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB0: "ະ" LAO VOWEL SIGN A -->
+ <Key
+ latin:keyLabel="&#x0EB0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB4: "ິ" LAO VOWEL SIGN I -->
+ <Key
+ latin:keyLabel="&#x0EB4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB5: "ີ" LAO VOWEL SIGN II -->
+ <Key
+ latin:keyLabel="&#x0EB5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EAE: "ຮ" LAO LETTER HO TAM -->
+ <Key
+ latin:keyLabel="&#x0EAE;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E99: "ນ" LAO LETTER NO -->
+ <Key
+ latin:keyLabel="&#x0E99;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E8D: "ຍ" LAO LETTER NYO -->
+ <Key
+ latin:keyLabel="&#x0E8D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E9A: "ບ" LAO LETTER BO -->
+ <Key
+ latin:keyLabel="&#x0E9A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EA5: "ລ" LAO LETTER LO LOOT -->
+ <Key
+ latin:keyLabel="&#x0EA5;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_lao3.xml b/java/res/xml/rowkeys_lao3.xml
new file mode 100644
index 000000000..2a6c2d1dd
--- /dev/null
+++ b/java/res/xml/rowkeys_lao3.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0EB1/U+0EC9: "ັ້" LAO VOWEL SIGN MAI KAN/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EB1;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <Key
+ latin:keyLabel=";" />
+ <Key
+ latin:keyLabel="." />
+ <Key
+ latin:keyLabel="," />
+ <Key
+ latin:keyLabel=":" />
+ <!-- U+0ECA: "໊" LAO TONE MAI TI -->
+ <Key
+ latin:keyLabel="&#x0ECA;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0ECB: "໋" LAO TONE MAI CATAWA -->
+ <Key
+ latin:keyLabel="&#x0ECB;"
+ latin:keyLabelFlags="fontNormal" />
+ <Key
+ latin:keyLabel="!" />
+ <Key
+ latin:keyLabel="\?" />
+ <Key
+ latin:keyLabel="%" />
+ <Key
+ latin:keyLabel="=" />
+ <!-- U+201C: "“" LEFT DOUBLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel="&#x201C;" />
+ </case>
+ <default>
+ <!-- U+0EB1: "ັ" LAO VOWEL SIGN MAI KAN -->
+ <Key
+ latin:keyLabel="&#x0EB1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EAB: "ຫ" LAO LETTER HO SUNG -->
+ <Key
+ latin:keyLabel="&#x0EAB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E81: "ກ" LAO LETTER KO -->
+ <Key
+ latin:keyLabel="&#x0E81;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E94: "ດ" LAO LETTER DO -->
+ <Key
+ latin:keyLabel="&#x0E94;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC0: "ເ" LAO VOWEL SIGN E -->
+ <Key
+ latin:keyLabel="&#x0EC0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC9: "້" LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EC9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC8: "່" LAO TONE MAI EK -->
+ <Key
+ latin:keyLabel="&#x0EC8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB2: "າ" LAO VOWEL SIGN AA -->
+ <Key
+ latin:keyLabel="&#x0EB2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EAA: "ສ" LAO LETTER SO SUNG -->
+ <Key
+ latin:keyLabel="&#x0EAA;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EA7: "ວ" LAO LETTER WO -->
+ <Key
+ latin:keyLabel="&#x0EA7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E87: "ງ" LAO LETTER NGO -->
+ <Key
+ latin:keyLabel="&#x0E87;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+201C: "“" LEFT DOUBLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel="&#x201C;" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_lao4.xml b/java/res/xml/rowkeys_lao4.xml
new file mode 100644
index 000000000..fae9cc923
--- /dev/null
+++ b/java/res/xml/rowkeys_lao4.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+20AD: "₭" KIP SIGN -->
+ <Key
+ latin:keyLabel="&#x20AD;" />
+ <Key
+ latin:keyLabel="(" />
+ <!-- U+0EAF: "ຯ" LAO ELLIPSIS -->
+ <Key
+ latin:keyLabel="&#x0EAF;"
+ latin:keyLabelFlags="fontNormal" />
+ <Key
+ latin:keyLabel="\@" />
+ <!-- U+0EB6/U+0EC9: "ຶ້" LAO VOWEL SIGN Y/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EB6;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0EB7/U+0EC9: "ື້" LAO VOWEL SIGN YY/LAO TONE MAI THO -->
+ <Key
+ latin:keyLabel="&#x0EB7;&#x0EC9;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0EC6: "ໆ" LAO KO LA -->
+ <Key
+ latin:keyLabel="&#x0EC6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EDD: "ໝ" LAO HO MO -->
+ <Key
+ latin:keyLabel="&#x0EDD;"
+ latin:keyLabelFlags="fontNormal" />
+ <Key
+ latin:keyLabel="$" />
+ <Key
+ latin:keyLabel=")" />
+ </case>
+ <default>
+ <!-- U+0E9C: "ຜ" LAO LETTER PHO SUNG -->
+ <Key
+ latin:keyLabel="&#x0E9C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E9B: "ປ" LAO LETTER PO -->
+ <Key
+ latin:keyLabel="&#x0E9B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC1: "ແ" LAO VOWEL SIGN EI -->
+ <Key
+ latin:keyLabel="&#x0EC1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EAD: "ອ" LAO LETTER O -->
+ <Key
+ latin:keyLabel="&#x0EAD;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB6: "ຶ" LAO VOWEL SIGN Y -->
+ <Key
+ latin:keyLabel="&#x0EB6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EB7: "ື" LAO VOWEL SIGN YY -->
+ <Key
+ latin:keyLabel="&#x0EB7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E97: "ທ" LAO LETTER THO TAM -->
+ <Key
+ latin:keyLabel="&#x0E97;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EA1: "ມ" LAO LETTER MO -->
+ <Key
+ latin:keyLabel="&#x0EA1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0EC3: "ໃ" LAO VOWEL SIGN AY -->
+ <Key
+ latin:keyLabel="&#x0EC3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0E9D: "ຝ" LAO LETTER FO TAM -->
+ <Key
+ latin:keyLabel="&#x0E9D;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_romanized1.xml b/java/res/xml/rowkeys_nepali_romanized1.xml
new file mode 100644
index 000000000..408a96648
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_romanized1.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0920: "ठ" DEVANAGARI LETTER TTHA -->
+ <Key
+ latin:keyLabel="&#x0920;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0914: "औ" DEVANAGARI LETTER AU -->
+ <Key
+ latin:keyLabel="&#x0914;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAi" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_vowel_sign_vocalic_r" />
+ <!-- U+0925: "थ" DEVANAGARI LETTER THA -->
+ <Key
+ latin:keyLabel="&#x0925;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091E: "ञ" DEVANAGARI LETTER NYA -->
+ <Key
+ latin:keyLabel="&#x091E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_uu" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignUu" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ii" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignIi" />
+ <!-- U+0913: "ओ" DEVANAGARI LETTER O -->
+ <Key
+ latin:keyLabel="&#x0913;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092B: "फ" DEVANAGARI LETTER PHA -->
+ <Key
+ latin:keyLabel="&#x092B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0908: "ई" DEVANAGARI LETTER II -->
+ <Key
+ latin:keyLabel="&#x0908;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+091F: "ट" DEVANAGARI LETTER TTA
+ U+0967: "१" DEVANAGARI DIGIT ONE
+ U+093C: "़" DEVANAGARI SIGN NUKTA -->
+ <Key
+ latin:keyLabel="&#x091F;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="&#x0967;,1"
+ latin:moreKeys="&#x093C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+0968: "२" DEVANAGARI DIGIT TWO -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAu"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="&#x0968;,2" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+0969: "३" DEVANAGARI DIGIT THREE -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignE"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="&#x0969;,3" />
+ <!-- U+0930: "र" DEVANAGARI LETTER RA
+ U+096A: "४" DEVANAGARI DIGIT FOUR -->
+ <Key
+ latin:keyLabel="&#x0930;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="&#x096A;,4"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0924: "त" DEVANAGARI LETTER TA
+ U+096B: "५" DEVANAGARI DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0924;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="&#x096B;,5"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092F: "य" DEVANAGARI LETTER YA
+ U+096C: "६" DEVANAGARI DIGIT SIX -->
+ <Key
+ latin:keyLabel="&#x092F;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="&#x096C;,6"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+096D: "७" DEVANAGARI DIGIT SEVEN -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_u" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignU"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="&#x096D;,7" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+096E: "८" DEVANAGARI DIGIT EIGHT -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_i" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignI"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="&#x096E;,8" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+096F: "९" DEVANAGARI DIGIT NINE -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_o" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignO"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="&#x096F;,9" />
+ <!-- U+092A: "प" DEVANAGARI LETTER PA
+ U+0966: "०" DEVANAGARI DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x092A;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="&#x0966;,0"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0907: "इ" DEVANAGARI LETTER I -->
+ <Key
+ latin:keyLabel="&#x0907;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_romanized2.xml b/java/res/xml/rowkeys_nepali_romanized2.xml
new file mode 100644
index 000000000..66359ffb5
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_romanized2.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0906: "आ" DEVANAGARI LETTER AA -->
+ <Key
+ latin:keyLabel="&#x0906;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0936: "श" DEVANAGARI LETTER SHA -->
+ <Key
+ latin:keyLabel="&#x0936;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0927: "ध" DEVANAGARI LETTER DHA -->
+ <Key
+ latin:keyLabel="&#x0927;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+090A: "ऊ" DEVANAGARI LETTER UU -->
+ <Key
+ latin:keyLabel="&#x090A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0918: "घ" DEVANAGARI LETTER GHA -->
+ <Key
+ latin:keyLabel="&#x0918;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0905: "अ" DEVANAGARI LETTER A -->
+ <Key
+ latin:keyLabel="&#x0905;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091D: "झ" DEVANAGARI LETTER JHA -->
+ <Key
+ latin:keyLabel="&#x091D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0916: "ख" DEVANAGARI LETTER KHA -->
+ <Key
+ latin:keyLabel="&#x0916;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0965: "॥" DEVANAGARI DOUBLE DANDA -->
+ <Key
+ latin:keyLabel="&#x0965;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0910: "ऐ" DEVANAGARI LETTER AI -->
+ <Key
+ latin:keyLabel="&#x0910;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_visarga" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVisarga" />
+ </case>
+ <default>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_aa" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAa" />
+ <!-- U+0938: "स" DEVANAGARI LETTER SA -->
+ <Key
+ latin:keyLabel="&#x0938;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0926: "द" DEVANAGARI LETTER DA -->
+ <Key
+ latin:keyLabel="&#x0926;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0909: "उ" DEVANAGARI LETTER U -->
+ <Key
+ latin:keyLabel="&#x0909;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0917: "ग" DEVANAGARI LETTER GA -->
+ <Key
+ latin:keyLabel="&#x0917;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0939: "ह" DEVANAGARI LETTER HA -->
+ <Key
+ latin:keyLabel="&#x0939;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091C: "ज" DEVANAGARI LETTER JA -->
+ <Key
+ latin:keyLabel="&#x091C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0915: "क" DEVANAGARI LETTER KA -->
+ <Key
+ latin:keyLabel="&#x0915;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0932: "ल" DEVANAGARI LETTER LA -->
+ <Key
+ latin:keyLabel="&#x0932;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+090F: "ए" DEVANAGARI LETTER E -->
+ <Key
+ latin:keyLabel="&#x090F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0950: "ॐ" DEVANAGARI OM -->
+ <Key
+ latin:keyLabel="&#x0950;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_romanized3.xml b/java/res/xml/rowkeys_nepali_romanized3.xml
new file mode 100644
index 000000000..166d028a3
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_romanized3.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R -->
+ <Key
+ latin:keyLabel="&#x090B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0922: "ढ" DEVANAGARI LETTER DDHA -->
+ <Key
+ latin:keyLabel="&#x0922;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091B: "छ" DEVANAGARI LETTER CHA -->
+ <Key
+ latin:keyLabel="&#x091B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_sign_candrabindu" />
+ <!-- U+092D: "भ" DEVANAGARI LETTER BHA -->
+ <Key
+ latin:keyLabel="&#x092D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0923: "ण" DEVANAGARI LETTER NNA -->
+ <Key
+ latin:keyLabel="&#x0923;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_sign_anusvara" />
+ <!-- U+0919: "ङ" DEVANAGARI LETTER NGA -->
+ <Key
+ latin:keyLabel="&#x0919;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVirama" />
+ </case>
+ <default>
+ <!-- U+0937: "ष" DEVANAGARI LETTER SSA -->
+ <Key
+ latin:keyLabel="&#x0937;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0921: "ड" DEVANAGARI LETTER DDA -->
+ <Key
+ latin:keyLabel="&#x0921;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091A: "च" DEVANAGARI LETTER CA -->
+ <Key
+ latin:keyLabel="&#x091A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0935: "व" DEVANAGARI LETTER VA -->
+ <Key
+ latin:keyLabel="&#x0935;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092C: "ब" DEVANAGARI LETTER BHA -->
+ <Key
+ latin:keyLabel="&#x092C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0928: "न" DEVANAGARI LETTER NA -->
+ <Key
+ latin:keyLabel="&#x0928;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092E: "म" DEVANAGARI LETTER MA -->
+ <Key
+ latin:keyLabel="&#x092E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0964: "।" DEVANAGARI DANDA
+ U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <Key
+ latin:keyLabel="&#x0964;"
+ latin:moreKeys="&#x093D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVirama" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_traditional1.xml b/java/res/xml/rowkeys_nepali_traditional1.xml
new file mode 100644
index 000000000..c7883c733
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_traditional1.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0924/U+094D/U+0924: "त्त" DEVANAGARI LETTER TA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER TA
+ U+091E: "ञ" DEVANAGARI LETTER NYA
+ U+091C/U+094D/U+091E: "ज्ञ" DEVANAGARI LETTER JA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER NYA
+ U+0965: "॥" DEVANAGARI DOUBLE DANDA -->
+ <Key
+ latin:keyLabel="&#x0924;&#x094D;&#x0924;"
+ latin:moreKeys="&#x091E;,&#x091C;&#x094D;&#x091E;,&#x0965;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0921/U+094D/U+0922: "ड्ढ" DEVANAGARI LETTER DDA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DDHA
+ U+0908: "ई" DEVANAGARI LETTER II -->
+ <Key
+ latin:keyLabel="&#x0921;&#x094D;&#x0922;"
+ latin:moreKeys="&#x0908;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0910: "ऐ" DEVANAGARI LETTER AI
+ U+0918: "घ" DEVANAGARI LETTER GHA -->
+ <Key
+ latin:keyLabel="&#x0910;"
+ latin:moreKeys="&#x0918;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0926/U+094D/U+0935: "द्व" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER VA
+ U+0926/U+094D/U+0927: "द्ध" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DHA -->
+ <Key
+ latin:keyLabel="&#x0926;&#x094D;&#x0935;"
+ latin:moreKeys="&#x0926;&#x094D;&#x0927;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+091F/U+094D/U+091F: "ट्ट" DEVANAGARI LETTER TTA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER TTA
+ U+091B: "छ" DEVANAGARI LETTER CHA -->
+ <Key
+ latin:keyLabel="&#x091F;&#x094D;&#x091F;"
+ latin:moreKeys="&#x091B;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0920/U+094D/U+0920: "ठ्ठ" DEVANAGARI LETTER TTHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER TTHA
+ U+091F: "ट" DEVANAGARI LETTER TTA -->
+ <Key
+ latin:keyLabel="&#x0920;&#x094D;&#x0920;"
+ latin:moreKeys="&#x091F;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+090A: "ऊ" DEVANAGARI LETTER UU
+ U+0920: "ठ" DEVANAGARI LETTER TTHA -->
+ <Key
+ latin:keyLabel="&#x090A;"
+ latin:moreKeys="&#x0920;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0915/U+094D/U+0937: "क्ष" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER SSA
+ U+0921: "ड" DEVANAGARI LETTER DDA -->
+ <Key
+ latin:keyLabel="&#x0915;&#x094D;&#x0937;"
+ latin:moreKeys="&#x0921;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0907: "इ" DEVANAGARI LETTER I
+ U+0922: "ढ" DEVANAGARI LETTER DDHA -->
+ <Key
+ latin:keyLabel="&#x0907;"
+ latin:moreKeys="&#x0922;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+090F: "ए" DEVANAGARI LETTER E
+ U+0923: "ण" DEVANAGARI LETTER NNA -->
+ <Key
+ latin:keyLabel="&#x090F;"
+ latin:moreKeys="&#x0923;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_vowel_sign_vocalic_r" />
+ </case>
+ <default>
+ <!-- U+091F: "ट" DEVANAGARI LETTER TTA
+ U+0967: "१" DEVANAGARI DIGIT ONE -->
+ <Key
+ latin:keyLabel="&#x091F;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="&#x0967;,1"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0927: "ध" DEVANAGARI LETTER DHA
+ U+0968: "२" DEVANAGARI DIGIT TWO -->
+ <Key
+ latin:keyLabel="&#x0927;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="&#x0968;,2"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092D: "भ" DEVANAGARI LETTER BHA
+ U+0969: "३" DEVANAGARI DIGIT THREE -->
+ <Key
+ latin:keyLabel="&#x092D;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="&#x0969;,3"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091A: "च" DEVANAGARI LETTER CA
+ U+096A: "४" DEVANAGARI DIGIT FOUR -->
+ <Key
+ latin:keyLabel="&#x091A;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="&#x096A;,4"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0924: "त" DEVANAGARI LETTER TA
+ U+096B: "५" DEVANAGARI DIGIT FIVE -->
+ <Key
+ latin:keyLabel="&#x0924;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="&#x096B;,5"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0925: "थ" DEVANAGARI LETTER THA
+ U+096C: "६" DEVANAGARI DIGIT SIX -->
+ <Key
+ latin:keyLabel="&#x0925;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="&#x096C;,6"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0917: "ग" DEVANAGARI LETTER G
+ U+096D: "७" DEVANAGARI DIGIT SEVEN -->
+ <Key
+ latin:keyLabel="&#x0917;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="&#x096D;,7"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0937: "ष" DEVANAGARI LETTER SSA
+ U+096E: "८" DEVANAGARI DIGIT EIGHT -->
+ <Key
+ latin:keyLabel="&#x0937;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="&#x096E;,8"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092F: "य" DEVANAGARI LETTER YA
+ U+096F: "९" DEVANAGARI DIGIT NINE -->
+ <Key
+ latin:keyLabel="&#x092F;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="&#x096F;,9"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0909: "उ" DEVANAGARI LETTER U
+ U+0966: "०" DEVANAGARI DIGIT ZERO -->
+ <Key
+ latin:keyLabel="&#x0909;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="&#x0966;,0"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0907: "इ" DEVANAGARI LETTER I
+ U+0914: "औ" DEVANAGARI LETTER AU -->
+ <Key
+ latin:keyLabel="&#x0907;"
+ latin:moreKeys="&#x0914;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_traditional2.xml b/java/res/xml/rowkeys_nepali_traditional2.xml
new file mode 100644
index 000000000..45620a9d7
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_traditional2.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0906: "आ" DEVANAGARI LETTER AA -->
+ <Key
+ latin:keyLabel="&#x0906;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0919/U+094D: "ङ्" DEVANAGARI LETTER NGA/DEVANAGARI SIGN VIRAMA -->
+ <Key
+ latin:keyLabel="&#x0919;&#x094D;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0921/U+094D/U+0921: "ड्ड" DEVANAGARI LETTER DDA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DDA -->
+ <Key
+ latin:keyLabel="&#x0921;&#x094D;&#x0921;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_sign_candrabindu" />
+ <!-- U+0926/U+094D/U+0926: "द्द" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DA -->
+ <Key
+ latin:keyLabel="&#x0926;&#x094D;&#x0926;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+091D: "झ" DEVANAGARI LETTER JHA -->
+ <Key
+ latin:keyLabel="&#x091D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_o" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignO" />
+ <!-- U+092B: "फ" DEVANAGARI LETTER PHA -->
+ <Key
+ latin:keyLabel="&#x092B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ii" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignIi" />
+ <!-- U+091F/U+094D/U+0920: "ट्ठ" DEVANAGARI LETTER TTA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER TTHA -->
+ <Key
+ latin:keyLabel="&#x091F;&#x094D;&#x0920;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_uu" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignUu" />
+ </case>
+ <default>
+ <!-- U+092C: "ब" DEVANAGARI LETTER BA -->
+ <Key
+ latin:keyLabel="&#x092C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0915: "क" DEVANAGARI LETTER KA -->
+ <Key
+ latin:keyLabel="&#x0915;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092E: "म" DEVANAGARI LETTER MA -->
+ <Key
+ latin:keyLabel="&#x092E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_aa" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAa" />
+ <!-- U+0928: "न" DEVANAGARI LETTER NA -->
+ <Key
+ latin:keyLabel="&#x0928;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091C: "ज" DEVANAGARI LETTER JA -->
+ <Key
+ latin:keyLabel="&#x091C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0935: "व" DEVANAGARI LETTER VA -->
+ <Key
+ latin:keyLabel="&#x0935;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092A: "प" DEVANAGARI LETTER PA -->
+ <Key
+ latin:keyLabel="&#x092A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_i" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignI" />
+ <!-- U+0938: "स" DEVANAGARI LETTER SA -->
+ <Key
+ latin:keyLabel="&#x0938;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_u" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignU" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_traditional3_left6.xml b/java/res/xml/rowkeys_nepali_traditional3_left6.xml
new file mode 100644
index 000000000..1cacced83
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_traditional3_left6.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+0915/U+094D: "क्" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA -->
+ <Key
+ latin:keyLabel="&#x0915;&#x094D;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+0939/U+094D/U+092E: "ह्म" DEVANAGARI LETTER HA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER MA -->
+ <Key
+ latin:keyLabel="&#x0939;&#x094D;&#x092E;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R -->
+ <Key
+ latin:keyLabel="&#x090B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0950: "ॐ" DEVANAGARI OM -->
+ <Key
+ latin:keyLabel="&#x0950;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAu" />
+ <!-- U+0926/U+094D/U+092F: "द्य" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER YA -->
+ <Key
+ latin:keyLabel="&#x0926;&#x094D;&#x092F;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ </case>
+ <default>
+ <!-- U+0936: "श" DEVANAGARI LETTER SHA -->
+ <Key
+ latin:keyLabel="&#x0936;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0939: "ह" DEVANAGARI LETTER HA -->
+ <Key
+ latin:keyLabel="&#x0939;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0905: "अ" DEVANAGARI LETTER A -->
+ <Key
+ latin:keyLabel="&#x0905;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0916: "ख" DEVANAGARI LETTER KHA -->
+ <Key
+ latin:keyLabel="&#x0916;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0926: "द" DEVANAGARI LETTER DA -->
+ <Key
+ latin:keyLabel="&#x0926;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0932: "ल" DEVANAGARI LETTER LA -->
+ <Key
+ latin:keyLabel="&#x0932;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_traditional3_right3.xml b/java/res/xml/rowkeys_nepali_traditional3_right3.xml
new file mode 100644
index 000000000..b2e01e481
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_traditional3_right3.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_sign_anusvara" />
+ <!-- U+0919: "ङ" DEVANAGARI LETTER NGA -->
+ <Key
+ latin:keyLabel="&#x0919;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAi" />
+ </case>
+ <default>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignE" />
+ <!-- U+0964: "।" DEVANAGARI DANDA -->
+ <Key
+ latin:keyLabel="&#x0964;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0930: "र" DEVANAGARI LETTER RA
+ U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U -->
+ <Key
+ latin:keyLabel="&#x0930;"
+ latin:moreKeys="&#x0930;&#x0941;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_nepali_traditional3_right5.xml b/java/res/xml/rowkeys_nepali_traditional3_right5.xml
new file mode 100644
index 000000000..87f061610
--- /dev/null
+++ b/java/res/xml/rowkeys_nepali_traditional3_right5.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/key_devanagari_sign_anusvara" />
+ <!-- U+0919: "ङ" DEVANAGARI LETTER NGA -->
+ <Key
+ latin:keyLabel="&#x0919;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAi" />
+ <!-- U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U -->
+ <Key
+ latin:keyLabel="&#x0930;&#x0941;"
+ latin:moreKeys="!"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <Key
+ latin:keyLabel="\?" />
+ </case>
+ <default>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <!-- U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_visarga" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVisarga"
+ latin:moreKeys="&#x093D;" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" />
+ <!-- Override more keys with empty definition -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignE" />
+ <!-- U+0964: "।" DEVANAGARI DANDA -->
+ <Key
+ latin:keyLabel="&#x0964;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0930: "र" DEVANAGARI LETTER RA -->
+ <Key
+ latin:keyLabel="&#x0930;"
+ latin:moreKeys="!"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVirama"
+ latin:moreKeys="\?" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_pcqwerty1.xml b/java/res/xml/rowkeys_pcqwerty1.xml
index b2d1d374b..de548d0ba 100644
--- a/java/res/xml/rowkeys_pcqwerty1.xml
+++ b/java/res/xml/rowkeys_pcqwerty1.xml
@@ -21,67 +21,61 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <switch>
- <case
- latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
- >
- <!-- U+00AC: "¬" NOT SIGN -->
- <Key
- latin:keyLabel="`"
- latin:moreKeys="~"
- latin:additionalMoreKeys="&#x00AC;" />
- <!-- U+00A1: "¡" NVERTED EXCLAMATION MARK -->
- <Key
- latin:keyLabel="1"
- latin:additionalMoreKeys="!"
- latin:moreKeys="&#x00A1;,!text/more_keys_for_symbols_1" />
- <Key
- latin:keyLabel="2"
- latin:additionalMoreKeys="\@"
- latin:moreKeys="!text/more_keys_for_symbols_2" />
- <Key
- latin:keyLabel="3"
- latin:additionalMoreKeys="\#"
- latin:moreKeys="!text/more_keys_for_symbols_3" />
- <Key
- latin:keyLabel="4"
- latin:additionalMoreKeys="$"
- latin:moreKeys="!text/more_keys_for_symbols_4" />
- <Key
- latin:keyLabel="5"
- latin:additionalMoreKeys="\\%"
- latin:moreKeys="!text/more_keys_for_symbols_5" />
- <Key
- latin:keyLabel="6"
- latin:additionalMoreKeys="^"
- latin:moreKeys="!text/more_keys_for_symbols_6" />
- <Key
- latin:keyLabel="7"
- latin:additionalMoreKeys="&amp;"
- latin:moreKeys="!text/more_keys_for_symbols_7" />
- <Key
- latin:keyLabel="8"
- latin:additionalMoreKeys="*,%"
- latin:moreKeys="!text/more_keys_for_symbols_8" />
- <Key
- latin:keyLabel="9"
- latin:additionalMoreKeys="("
- latin:moreKeys="!text/more_keys_for_symbols_9" />
- <Key
- latin:keyLabel="0"
- latin:additionalMoreKeys=")"
- latin:moreKeys="!text/more_keys_for_symbols_0" />
- <Key
- latin:keyLabel="-"
- latin:moreKeys="_" />
- <Key
- latin:keyLabel="="
- latin:moreKeys="+" />
- </case>
- <!-- keyboardLayoutSetElement="alphabet*Shifted|symbols*" -->
- <default>
- <include
- latin:keyboardLayout="@xml/keys_pcqwerty_symbols1" />
- </default>
- </switch>
+ <Key
+ latin:keyLabel="`"
+ latin:additionalMoreKeys="~" />
+ <Key
+ latin:keyLabel="1"
+ latin:additionalMoreKeys="!,!text/more_keys_for_symbols_exclamation"
+ latin:moreKeys="!text/more_keys_for_symbols_1" />
+ <Key
+ latin:keyLabel="2"
+ latin:additionalMoreKeys="\@"
+ latin:moreKeys="!text/more_keys_for_symbols_2" />
+ <Key
+ latin:keyLabel="3"
+ latin:additionalMoreKeys="\#"
+ latin:moreKeys="!text/more_keys_for_symbols_3" />
+ <Key
+ latin:keyLabel="4"
+ latin:additionalMoreKeys="$"
+ latin:moreKeys="!text/more_keys_for_symbols_4" />
+ <Key
+ latin:keyLabel="5"
+ latin:additionalMoreKeys="\\%"
+ latin:moreKeys="!text/more_keys_for_symbols_5" />
+ <Key
+ latin:keyLabel="6"
+ latin:additionalMoreKeys="^"
+ latin:moreKeys="!text/more_keys_for_symbols_6" />
+ <Key
+ latin:keyLabel="7"
+ latin:additionalMoreKeys="&amp;"
+ latin:moreKeys="!text/more_keys_for_symbols_7" />
+ <Key
+ latin:keyLabel="8"
+ latin:additionalMoreKeys="*"
+ latin:moreKeys="!text/more_keys_for_symbols_8" />
+ <Key
+ latin:keyLabel="9"
+ latin:additionalMoreKeys="("
+ latin:moreKeys="!text/more_keys_for_symbols_9" />
+ <Key
+ latin:keyLabel="0"
+ latin:additionalMoreKeys=")"
+ latin:moreKeys="!text/more_keys_for_symbols_0" />
+ <!-- U+2013: "–" EN DASH
+ U+2014: "—" EM DASH
+ U+00B7: "·" MIDDLE DOT -->
+ <Key
+ latin:keyLabel="-"
+ latin:additionalMoreKeys="_"
+ latin:moreKeys="&#x2013;,&#x2014;,&#x00B7;" />
+ <!-- U+221E: "∞" INFINITY
+ U+2260: "≠" NOT EQUAL TO
+ U+2248: "≈" ALMOST EQUAL TO -->
+ <Key
+ latin:keyLabel="="
+ latin:additionalMoreKeys="+"
+ latin:moreKeys="!fixedColumnOrder!4,&#x221E;,&#x2260;,&#x2248;,%" />
</merge>
diff --git a/java/res/xml/keys_pcqwerty_symbols1.xml b/java/res/xml/rowkeys_pcqwerty1_shift.xml
index 2364e1087..bc39f944e 100644
--- a/java/res/xml/keys_pcqwerty_symbols1.xml
+++ b/java/res/xml/rowkeys_pcqwerty1_shift.xml
@@ -21,37 +21,40 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- U+00AC: "¬" NOT SIGN -->
<Key
- latin:keyLabel="~"
- latin:moreKeys="&#x00AC;" />
- <!-- U+00A1: "¡" NVERTED EXCLAMATION MARK -->
+ latin:keyLabel="~" />
<Key
latin:keyLabel="!"
- latin:moreKeys="&#x00A1;" />
+ latin:additionalMoreKeys="!text/more_keys_for_symbols_exclamation" />
<Key
latin:keyLabel="\@" />
<Key
latin:keyLabel="\#" />
<Key
- latin:keyLabel="$" />
- <!-- U+2030: "‰" PER MILLE SIGN -->
+ latin:keyLabel="$"
+ latin:additionalMoreKeys="!text/more_keys_for_currency_dollar" />
<Key
latin:keyLabel="%"
- latin:moreKeys="&#x2030;" />
+ latin:additionalMoreKeys="!text/more_keys_for_symbols_percent" />
<Key
latin:keyLabel="^" />
<Key
latin:keyLabel="&amp;" />
<Key
latin:keyLabel="*"
- latin:moreKeys="!text/more_keys_for_star" />
+ latin:additionalMoreKeys="!text/more_keys_for_star" />
<Key
latin:keyLabel="(" />
<Key
latin:keyLabel=")" />
<Key
latin:keyLabel="_" />
- <Key
- latin:keyLabel="+" />
+ <!-- U+00B1: "±" PLUS-MINUS SIGN
+ U+00D7: "×" MULTIPLICATION SIGN
+ U+00F7: "÷" DIVISION SIGN
+ U+221A: "√" SQUARE ROOT -->
+ <Key
+ latin:keyLabel="+"
+ latin:additionalMoreKeys="!text/more_keys_for_plus"
+ latin:moreKeys="&#x00B1;,&#x00D7;,&#x00F7;,&#x221A;" />
</merge>
diff --git a/java/res/xml/rowkeys_pcqwerty2.xml b/java/res/xml/rowkeys_pcqwerty2.xml
index cedf47559..8db704d71 100644
--- a/java/res/xml/rowkeys_pcqwerty2.xml
+++ b/java/res/xml/rowkeys_pcqwerty2.xml
@@ -21,21 +21,11 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <switch>
- <case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
- >
- <include
- latin:keyboardLayout="@xml/keys_pcqwerty_symbols2" />
- </case>
- <default>
- <!-- The keys on this PC layout row2 consist of the letters of QWERTY layout row1 and
- some symbols keys. -->
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty1"
- latin:keyLabelFlags="disableAdditionalMoreKeys|disableKeyHintLabel" />
- </default>
- </switch>
+ <!-- The keys on this PC layout row2 consist of the letters of QWERTY layout row1 and
+ some symbols keys. -->
+ <include
+ latin:keyboardLayout="@xml/rowkeys_qwerty1"
+ latin:keyLabelFlags="disableAdditionalMoreKeys|disableKeyHintLabel" />
<include
latin:keyboardLayout="@xml/keys_pcqwerty2_right3" />
</merge>
diff --git a/java/res/xml/rowkeys_pcqwerty3.xml b/java/res/xml/rowkeys_pcqwerty3.xml
index 5044e5feb..ad122d30c 100644
--- a/java/res/xml/rowkeys_pcqwerty3.xml
+++ b/java/res/xml/rowkeys_pcqwerty3.xml
@@ -21,20 +21,10 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <switch>
- <case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
- >
- <include
- latin:keyboardLayout="@xml/keys_pcqwerty_symbols3" />
- </case>
- <default>
- <!-- The keys on this PC layout row3 consist of the letters of QWERTY layout row2 and
- some symbols keys. -->
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty2" />
- </default>
- </switch>
+ <!-- The keys on this PC layout row3 consist of the letters of QWERTY layout row2 and
+ some symbols keys. -->
+ <include
+ latin:keyboardLayout="@xml/rowkeys_qwerty2" />
<include
latin:keyboardLayout="@xml/keys_pcqwerty3_right2" />
</merge>
diff --git a/java/res/xml/rowkeys_pcqwerty4.xml b/java/res/xml/rowkeys_pcqwerty4.xml
index 4071e8c09..b558f4142 100644
--- a/java/res/xml/rowkeys_pcqwerty4.xml
+++ b/java/res/xml/rowkeys_pcqwerty4.xml
@@ -21,20 +21,10 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <switch>
- <case
- latin:keyboardLayoutSetElement="symbols|symbolsShifted"
- >
- <include
- latin:keyboardLayout="@xml/keys_pcqwerty_symbols4" />
- </case>
- <default>
- <!-- The keys on this PC layout row4 consist of the letters of QWERTY layout row3 and
- some symbols keys. -->
- <include
- latin:keyboardLayout="@xml/rowkeys_qwerty3" />
- </default>
- </switch>
+ <!-- The keys on this PC layout row4 consist of the letters of QWERTY layout row3 and
+ some symbols keys. -->
+ <include
+ latin:keyboardLayout="@xml/rowkeys_qwerty3" />
<include
latin:keyboardLayout="@xml/keys_pcqwerty4_right3" />
</merge>
diff --git a/java/res/xml/rowkeys_symbols2.xml b/java/res/xml/rowkeys_symbols2.xml
index 3e27f1579..76cbf6259 100644
--- a/java/res/xml/rowkeys_symbols2.xml
+++ b/java/res/xml/rowkeys_symbols2.xml
@@ -50,9 +50,6 @@
latin:moreKeys="!text/more_keys_for_symbols_percent" />
<Key
latin:keyLabel="&amp;" />
- <Key
- latin:keyLabel="*"
- latin:moreKeys="!text/more_keys_for_star" />
<!-- U+2013: "–" EN DASH
U+2014: "—" EM DASH
U+00B7: "·" MIDDLE DOT -->
diff --git a/java/res/xml/rowkeys_symbols3.xml b/java/res/xml/rowkeys_symbols3.xml
index 7722ca9ae..9f5e620e6 100644
--- a/java/res/xml/rowkeys_symbols3.xml
+++ b/java/res/xml/rowkeys_symbols3.xml
@@ -22,8 +22,8 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<Key
- latin:keyLabel="!"
- latin:moreKeys="!text/more_keys_for_symbols_exclamation" />
+ latin:keyLabel="*"
+ latin:moreKeys="!text/more_keys_for_star" />
<switch>
<case
latin:languageCode="fa"
@@ -54,8 +54,9 @@
latin:keyLabel="!text/keylabel_for_symbols_semicolon"
latin:moreKeys="!text/more_keys_for_symbols_semicolon" />
<Key
- latin:keyLabel="/" />
- <Key
latin:keyLabel="!text/keylabel_for_symbols_question"
latin:moreKeys="!text/more_keys_for_symbols_question" />
+ <Key
+ latin:keyLabel="!"
+ latin:moreKeys="!text/more_keys_for_symbols_exclamation" />
</merge>
diff --git a/java/res/xml/rowkeys_symbols_shift1.xml b/java/res/xml/rowkeys_symbols_shift1.xml
index fea8ae337..6013493e5 100644
--- a/java/res/xml/rowkeys_symbols_shift1.xml
+++ b/java/res/xml/rowkeys_symbols_shift1.xml
@@ -34,17 +34,23 @@
<!-- U+221A: "√" SQUARE ROOT -->
<Key
latin:keyLabel="&#x221A;" />
- <!-- U+03C0: "π" GREEK SMALL LETTER PI
- U+03A0: "Π" GREEK CAPITAL LETTER PI -->
+ <!-- U+03A0: "Π" GREEK CAPITAL LETTER PI
+ U+03C0: "π" GREEK SMALL LETTER PI -->
<Key
- latin:keyLabel="&#x03C0;"
- latin:moreKeys="&#x03A0;" />
+ latin:keyLabel="&#x03A0;"
+ latin:moreKeys="&#x03C0;" />
<!-- U+00F7: "÷" DIVISION SIGN -->
<Key
latin:keyLabel="&#x00F7;" />
<!-- U+00D7: "×" MULTIPLICATION SIGN -->
<Key
latin:keyLabel="&#x00D7;" />
- <include
- latin:keyboardLayout="@xml/keys_curly_brackets" />
+ <!-- U+00B6: "¶" PILCROW SIGN
+ U+00A7: "§" SECTION SIGN -->
+ <Key
+ latin:keyLabel="&#x00B6;"
+ latin:moreKeys="&#x00A7;" />
+ <!-- U+2206: "∆" INCREMENT -->
+ <Key
+ latin:keyLabel="&#x2206;" />
</merge>
diff --git a/java/res/xml/rowkeys_symbols_shift2.xml b/java/res/xml/rowkeys_symbols_shift2.xml
index 3fd8aacb6..36f92143f 100644
--- a/java/res/xml/rowkeys_symbols_shift2.xml
+++ b/java/res/xml/rowkeys_symbols_shift2.xml
@@ -22,19 +22,13 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<Key
- latin:keyStyle="nonSpecialBackgroundTabKeyStyle" />
- <Key
latin:keyStyle="moreCurrency1KeyStyle" />
<Key
latin:keyStyle="moreCurrency2KeyStyle" />
<Key
latin:keyStyle="moreCurrency3KeyStyle" />
- <!-- U+00B0: "°" DEGREE SIGN
- U+2032: "′" PRIME
- U+2033: "″" DOUBLE PRIME -->
<Key
- latin:keyLabel="&#x00B0;"
- latin:moreKeys="&#x2032;,&#x2033;" />
+ latin:keyStyle="moreCurrency4KeyStyle" />
<!-- U+2191: "↑" UPWARDS ARROW
U+2193: "↓" DOWNWARDS ARROW
U+2190: "←" LEFTWARDS ARROW
@@ -42,8 +36,12 @@
<Key
latin:keyLabel="^"
latin:moreKeys="&#x2191;,&#x2193;,&#x2190;,&#x2192;" />
+ <!-- U+00B0: "°" DEGREE SIGN
+ U+2032: "′" PRIME
+ U+2033: "″" DOUBLE PRIME -->
<Key
- latin:keyLabel="_" />
+ latin:keyLabel="&#x00B0;"
+ latin:moreKeys="&#x2032;,&#x2033;" />
<!-- U+2260: "≠" NOT EQUAL TO
U+2248: "≈" ALMOST EQUAL TO
U+221E: "∞" INFINITY -->
@@ -51,5 +49,5 @@
latin:keyLabel="="
latin:moreKeys="&#x2260;,&#x2248;,&#x221E;" />
<include
- latin:keyboardLayout="@xml/keys_square_brackets" />
+ latin:keyboardLayout="@xml/keys_curly_brackets" />
</merge>
diff --git a/java/res/xml/rowkeys_symbols_shift3.xml b/java/res/xml/rowkeys_symbols_shift3.xml
index a35af218f..5fe1c7450 100644
--- a/java/res/xml/rowkeys_symbols_shift3.xml
+++ b/java/res/xml/rowkeys_symbols_shift3.xml
@@ -21,22 +21,20 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- U+2122: "™" TRADE MARK SIGN -->
- <Key
- latin:keyLabel="&#x2122;" />
- <!-- U+00AE: "®" REGISTERED SIGN -->
<Key
- latin:keyLabel="&#x00AE;" />
+ latin:keyLabel="\\" />
<!-- U+00A9: "©" COPYRIGHT SIGN -->
<Key
latin:keyLabel="&#x00A9;" />
- <!-- U+00B6: "¶" PILCROW SIGN
- U+00A7: "§" SECTION SIGN -->
+ <!-- U+00AE: "®" REGISTERED SIGN -->
+ <Key
+ latin:keyLabel="&#x00AE;" />
+ <!-- U+2122: "™" TRADE MARK SIGN -->
<Key
- latin:keyLabel="&#x00B6;"
- latin:moreKeys="&#x00A7;" />
+ latin:keyLabel="&#x2122;" />
+ <!-- U+2105: "℅" CARE OF -->
<Key
- latin:keyLabel="\\" />
+ latin:keyLabel="&#x2105;" />
<include
- latin:keyboardLayout="@xml/keys_less_greater" />
+ latin:keyboardLayout="@xml/keys_square_brackets" />
</merge>
diff --git a/java/res/xml-sw600dp/rows_pcqwerty_symbols.xml b/java/res/xml/rows_armenian_phonetic.xml
index 5e1aa6382..ea8870e1a 100644
--- a/java/res/xml-sw600dp/rows_pcqwerty_symbols.xml
+++ b/java/res/xml/rows_armenian_phonetic.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -26,42 +26,39 @@
<include
latin:keyboardLayout="@xml/key_styles_currency" />
<Row
- latin:keyWidth="7.0%p"
+ latin:keyWidth="10.0%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic1" />
</Row>
<Row
- latin:keyWidth="7.0%p"
+ latin:keyWidth="10.0%p"
>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyWidth="9.0%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty2" />
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic2" />
</Row>
<Row
- latin:keyWidth="7.0%p"
+ latin:keyWidth="10.0%p"
>
- <Key
- latin:keyStyle="toAlphaKeyStyle"
- latin:keyWidth="12.0%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty3" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic3" />
+ <include
+ latin:keyboardLayout="@xml/key_armenian_xeh" />
</Row>
<Row
- latin:keyWidth="7.0%p"
+ latin:keyWidth="9.8000%p"
>
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.8%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_armenian_phonetic4" />
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty4"
- latin:keyXPos="15.0%p" />
+ latin:keyboardLayout="@xml/key_armenian_sha" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/row_pcqwerty5" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/rows_khmer.xml b/java/res/xml/rows_khmer.xml
new file mode 100644
index 000000000..e3993871b
--- /dev/null
+++ b/java/res/xml/rows_khmer.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer1" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer2" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer3" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer4" />
+ <Key
+ latin:keyStyle="deleteKeyStyle" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml/rows_lao.xml b/java/res/xml/rows_lao.xml
new file mode 100644
index 000000000..321f4112a
--- /dev/null
+++ b/java/res/xml/rows_lao.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_lao1" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_lao2" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_lao3" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_lao4" />
+ <Key
+ latin:keyStyle="deleteKeyStyle" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw768dp/rows_arabic.xml b/java/res/xml/rows_nepali_romanized.xml
index 204f6d590..6df09c830 100644
--- a/java/res/xml-sw768dp/rows_arabic.xml
+++ b/java/res/xml/rows_nepali_romanized.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -24,37 +24,28 @@
<include
latin:keyboardLayout="@xml/key_styles_common" />
<Row
- latin:keyWidth="7.375%p"
+ latin:keyWidth="9.091%p"
>
- <Key
- latin:keyStyle="tabKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="7.969%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_arabic1" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_romanized1" />
</Row>
<Row
- latin:keyWidth="7.227%p"
+ latin:keyWidth="9.091%p"
>
- <Key
- latin:keyStyle="toSymbolKeyStyle"
- latin:keyLabelFlags="alignLeft"
- latin:keyWidth="11.172%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_arabic2" />
- <Key
- latin:keyStyle="enterKeyStyle"
- latin:keyWidth="fillRight" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_romanized2" />
</Row>
<Row
- latin:keyWidth="7.227%p"
+ latin:keyWidth="8.711%p"
>
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.8%p" />
<include
- latin:keyboardLayout="@xml/rowkeys_arabic3"
- latin:keyXPos="6.602%p" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_romanized3" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml/rows_pcqwerty_symbols.xml b/java/res/xml/rows_nepali_traditional.xml
index 107a4ad1f..7789135ae 100644
--- a/java/res/xml/rows_pcqwerty_symbols.xml
+++ b/java/res/xml/rows_nepali_traditional.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -26,35 +26,31 @@
<include
latin:keyboardLayout="@xml/key_styles_currency" />
<Row
- latin:keyWidth="7.692%p"
+ latin:keyWidth="9.091%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional1" />
</Row>
<Row
- latin:keyWidth="7.692%p"
+ latin:keyWidth="9.091%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty2" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional2" />
</Row>
<Row
- latin:keyWidth="7.692%p"
+ latin:keyWidth="8.711%p"
>
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.8%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_left6" />
<include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty3"
- latin:keyXPos="3.846%p" />
+ latin:keyboardLayout="@xml/rowkeys_nepali_traditional3_right3" />
<Key
latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"
- latin:visualInsetsLeft="1%p" />
- </Row>
- <Row
- latin:keyWidth="7.692%p"
- >
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty4"
- latin:keyXPos="11.538%p" />
+ latin:keyWidth="fillRight" />
</Row>
<include
- latin:keyboardLayout="@xml/row_pcqwerty5" />
+ latin:keyboardLayout="@xml/row_qwerty4" />
</merge>
diff --git a/java/res/xml/rows_pcqwerty.xml b/java/res/xml/rows_pcqwerty.xml
index a5ed74518..884698963 100644
--- a/java/res/xml/rows_pcqwerty.xml
+++ b/java/res/xml/rows_pcqwerty.xml
@@ -26,8 +26,19 @@
<Row
latin:keyWidth="7.692%p"
>
- <include
- latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_pcqwerty1" />
+ </case>
+ <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
+ <default>
+ <include
+ latin:keyboardLayout="@xml/rowkeys_pcqwerty1_shift" />
+ </default>
+ </switch>
</Row>
<Row
latin:keyWidth="7.692%p"
diff --git a/java/res/xml/rows_symbols.xml b/java/res/xml/rows_symbols.xml
index bd1a57e75..3f102e277 100644
--- a/java/res/xml/rows_symbols.xml
+++ b/java/res/xml/rows_symbols.xml
@@ -35,7 +35,8 @@
latin:keyWidth="10%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_symbols2" />
+ latin:keyboardLayout="@xml/rowkeys_symbols2"
+ latin:keyXPos="5%p" />
</Row>
<Row
latin:keyWidth="10%p"
@@ -51,6 +52,13 @@
latin:keyWidth="fillRight"
latin:visualInsetsLeft="1%p" />
</Row>
- <include
- latin:keyboardLayout="@xml/row_symbols4" />
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyStyle="toAlphaKeyStyle"
+ latin:keyWidth="15%p" />
+ <include
+ latin:keyboardLayout="@xml/row_symbols4" />
+ </Row>
</merge>
diff --git a/java/res/xml/rows_symbols_shift.xml b/java/res/xml/rows_symbols_shift.xml
index 9c03d90b5..45ada2a61 100644
--- a/java/res/xml/rows_symbols_shift.xml
+++ b/java/res/xml/rows_symbols_shift.xml
@@ -35,6 +35,7 @@
latin:keyWidth="10%p"
>
<include
+ latin:keyXPos="5%p"
latin:keyboardLayout="@xml/rowkeys_symbols_shift2" />
</Row>
<Row
@@ -51,6 +52,13 @@
latin:keyWidth="fillRight"
latin:visualInsetsLeft="1%p" />
</Row>
- <include
- latin:keyboardLayout="@xml/row_symbols_shift4" />
+ <Row
+ latin:keyWidth="10%p"
+ >
+ <Key
+ latin:keyStyle="toAlphaKeyStyle"
+ latin:keyWidth="15%p" />
+ <include
+ latin:keyboardLayout="@xml/row_symbols_shift4" />
+ </Row>
</merge>
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 77f323440..7639432aa 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -157,7 +157,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
// Add the virtual children of the root View.
final Keyboard keyboard = mKeyboardView.getKeyboard();
- final Key[] keys = keyboard.mKeys;
+ final Key[] keys = keyboard.getKeys();
for (Key key : keys) {
final int childVirtualViewId = generateVirtualViewIdForKey(key);
rootInfo.addChild(mKeyboardView, childVirtualViewId);
@@ -172,7 +172,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
return null;
}
final String keyDescription = getKeyDescription(key);
- final Rect boundsInParent = key.mHitBox;
+ final Rect boundsInParent = key.getHitBox();
// Calculate the key's in-screen bounds.
mTempBoundsInScreen.set(boundsInParent);
@@ -208,8 +208,8 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
* @param key The key to press.
*/
void simulateKeyPress(final Key key) {
- final int x = key.mHitBox.centerX();
- final int y = key.mHitBox.centerY();
+ final int x = key.getHitBox().centerX();
+ final int y = key.getHitBox().centerY();
final long downTime = SystemClock.uptimeMillis();
final MotionEvent downEvent = MotionEvent.obtain(
downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0);
@@ -300,7 +300,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
}
mVirtualViewIdToKey.clear();
- final Key[] keys = keyboard.mKeys;
+ final Key[] keys = keyboard.getKeys();
for (Key key : keys) {
final int virtualViewId = generateVirtualViewIdForKey(key);
mVirtualViewIdToKey.put(virtualViewId, key);
@@ -325,6 +325,6 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
// The key x- and y-coordinates are stable between layout changes.
// Generate an identifier by bit-shifting the x-coordinate to the
// left-half of the integer and OR'ing with the y-coordinate.
- return ((0xFFFF & key.mX) << (Integer.SIZE / 2)) | (0xFFFF & key.mY);
+ return ((0xFFFF & key.getX()) << (Integer.SIZE / 2)) | (0xFFFF & key.getY());
}
}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 41f5b9a24..58624a2e6 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -97,7 +97,7 @@ public final class KeyCodeDescriptionMapper {
*/
public String getDescriptionForKey(final Context context, final Keyboard keyboard,
final Key key, final boolean shouldObscure) {
- final int code = key.mCode;
+ final int code = key.getCode();
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
@@ -116,8 +116,8 @@ public final class KeyCodeDescriptionMapper {
return getDescriptionForActionKey(context, keyboard, key);
}
- if (!TextUtils.isEmpty(key.mLabel)) {
- final String label = key.mLabel.toString().trim();
+ if (!TextUtils.isEmpty(key.getLabel())) {
+ final String label = key.getLabel().trim();
// First, attempt to map the label to a pre-defined description.
if (mKeyLabelMap.containsKey(label)) {
@@ -126,7 +126,7 @@ public final class KeyCodeDescriptionMapper {
}
// Just attempt to speak the description.
- if (key.mCode != Constants.CODE_UNSPECIFIED) {
+ if (key.getCode() != Constants.CODE_UNSPECIFIED) {
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
}
return null;
@@ -215,8 +215,8 @@ public final class KeyCodeDescriptionMapper {
final int resId;
// Always use the label, if available.
- if (!TextUtils.isEmpty(key.mLabel)) {
- return key.mLabel.toString().trim();
+ if (!TextUtils.isEmpty(key.getLabel())) {
+ return key.getLabel().trim();
}
// Otherwise, use the action ID.
@@ -267,7 +267,7 @@ public final class KeyCodeDescriptionMapper {
*/
private String getDescriptionForKeyCode(final Context context, final Keyboard keyboard,
final Key key, final boolean shouldObscure) {
- final int code = key.mCode;
+ final int code = key.getCode();
// If the key description should be obscured, now is the time to do it.
final boolean isDefinedNonCtrl = Character.isDefined(code) && !Character.isISOControl(code);
@@ -280,8 +280,8 @@ public final class KeyCodeDescriptionMapper {
if (isDefinedNonCtrl) {
return Character.toString((char) code);
}
- if (!TextUtils.isEmpty(key.mLabel)) {
- return key.mLabel;
+ if (!TextUtils.isEmpty(key.getLabel())) {
+ return key.getLabel();
}
return context.getString(R.string.spoken_description_unknown, code);
}
diff --git a/java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java b/java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java
new file mode 100644
index 000000000..385e3e025
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.compat;
+
+import android.app.ActivityManager;
+import android.content.Context;
+
+import java.lang.reflect.Method;
+
+public class ActivityManagerCompatUtils {
+ private static final Object LOCK = new Object();
+ private static volatile Boolean sBoolean = null;
+ private static final Method METHOD_isLowRamDevice = CompatUtils.getMethod(
+ ActivityManager.class, "isLowRamDevice");
+
+ private ActivityManagerCompatUtils() {
+ // Do not instantiate this class.
+ }
+
+ public static boolean isLowRamDevice(Context context) {
+ if (sBoolean == null) {
+ synchronized(LOCK) {
+ if (sBoolean == null) {
+ final ActivityManager am =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ sBoolean = (Boolean)CompatUtils.invoke(am, false, METHOD_isLowRamDevice);
+ }
+ }
+ }
+ return sBoolean;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java b/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java
new file mode 100644
index 000000000..fed134eb9
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard;
+
+import com.android.inputmethod.latin.R;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+public class EmojiCategoryPageIndicatorView extends LinearLayout {
+ private static final float BOTTOM_MARGIN_RATIO = 0.66f;
+ private final Paint mPaint = new Paint();
+ private int mCategoryPageSize = 0;
+ private int mCurrentCategoryPageId = 0;
+ private float mOffset = 0.0f;
+
+ public EmojiCategoryPageIndicatorView(Context context) {
+ this(context, null /* attrs */);
+ }
+
+ public EmojiCategoryPageIndicatorView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mPaint.setColor(context.getResources().getColor(
+ R.color.emoji_category_page_id_view_foreground));
+ }
+
+ public void setCategoryPageId(int size, int id, float offset) {
+ mCategoryPageSize = size;
+ mCurrentCategoryPageId = id;
+ mOffset = offset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mCategoryPageSize == 0) {
+ // If the category is not set yet, just clear and return.
+ canvas.drawColor(0);
+ return;
+ }
+ final float height = getHeight();
+ final float width = getWidth();
+ final float unitWidth = width / mCategoryPageSize;
+ final float left = unitWidth * mCurrentCategoryPageId + mOffset * unitWidth;
+ final float top = 0.0f;
+ final float right = left + unitWidth;
+ final float bottom = height * BOTTOM_MARGIN_RATIO;
+ canvas.drawRect(left, top, right, bottom, mPaint);
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
new file mode 100644
index 000000000..4e61edac2
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
@@ -0,0 +1,766 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard;
+
+import static com.android.inputmethod.latin.Constants.NOT_A_COORDINATE;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TabHost;
+import android.widget.TabHost.OnTabChangeListener;
+import android.widget.TextView;
+
+import com.android.inputmethod.keyboard.internal.DynamicGridKeyboard;
+import com.android.inputmethod.keyboard.internal.ScrollKeyboardView;
+import com.android.inputmethod.keyboard.internal.ScrollViewWithNotifier;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * View class to implement Emoji keyboards.
+ * The Emoji keyboard consists of group of views {@link R.layout#emoji_keyboard_view}.
+ * <ol>
+ * <li> Emoji category tabs.
+ * <li> Delete button.
+ * <li> Emoji keyboard pages that can be scrolled by swiping horizontally or by selecting a tab.
+ * <li> Back to main keyboard button and enter button.
+ * </ol>
+ * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
+ */
+public final class EmojiKeyboardView extends LinearLayout implements OnTabChangeListener,
+ ViewPager.OnPageChangeListener, View.OnClickListener,
+ ScrollKeyboardView.OnKeyClickListener {
+ private static final String TAG = EmojiKeyboardView.class.getSimpleName();
+ private final int mKeyBackgroundId;
+ private final int mEmojiFunctionalKeyBackgroundId;
+ private final KeyboardLayoutSet mLayoutSet;
+ private final ColorStateList mTabLabelColor;
+ private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
+ private EmojiKeyboardAdapter mEmojiKeyboardAdapter;
+
+ private TabHost mTabHost;
+ private ViewPager mEmojiPager;
+ private EmojiCategoryPageIndicatorView mEmojiCategoryPageIndicatorView;
+
+ private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
+
+ private static final int CATEGORY_ID_UNSPECIFIED = -1;
+ public static final int CATEGORY_ID_RECENTS = 0;
+ public static final int CATEGORY_ID_PEOPLE = 1;
+ public static final int CATEGORY_ID_OBJECTS = 2;
+ public static final int CATEGORY_ID_NATURE = 3;
+ public static final int CATEGORY_ID_PLACES = 4;
+ public static final int CATEGORY_ID_SYMBOLS = 5;
+ public static final int CATEGORY_ID_EMOTICONS = 6;
+
+ private static class CategoryProperties {
+ public int mCategoryId;
+ public int mPageCount;
+ public CategoryProperties(final int categoryId, final int pageCount) {
+ mCategoryId = categoryId;
+ mPageCount = pageCount;
+ }
+ }
+
+ private static class EmojiCategory {
+ private static final String[] sCategoryName = {
+ "recents",
+ "people",
+ "objects",
+ "nature",
+ "places",
+ "symbols",
+ "emoticons" };
+ private static final int[] sCategoryIcon = new int[] {
+ R.drawable.ic_emoji_recent_light,
+ R.drawable.ic_emoji_people_light,
+ R.drawable.ic_emoji_objects_light,
+ R.drawable.ic_emoji_nature_light,
+ R.drawable.ic_emoji_places_light,
+ R.drawable.ic_emoji_symbols_light,
+ 0 };
+ private static final String[] sCategoryLabel =
+ { null, null, null, null, null, null, ":-)" };
+ private static final int[] sCategoryElementId = {
+ KeyboardId.ELEMENT_EMOJI_RECENTS,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY1,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY2,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY3,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY4,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY5,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY6 };
+ private final SharedPreferences mPrefs;
+ private final int mMaxPageKeyCount;
+ private final KeyboardLayoutSet mLayoutSet;
+ private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap();
+ private final ArrayList<CategoryProperties> mShownCategories =
+ CollectionUtils.newArrayList();
+ private final ConcurrentHashMap<Long, DynamicGridKeyboard>
+ mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>();
+
+ private int mCurrentCategoryId = CATEGORY_ID_UNSPECIFIED;
+ private int mCurrentCategoryPageId = 0;
+
+ public EmojiCategory(final SharedPreferences prefs, final Resources res,
+ final KeyboardLayoutSet layoutSet) {
+ mPrefs = prefs;
+ mMaxPageKeyCount = res.getInteger(R.integer.emoji_keyboard_max_key_count);
+ mLayoutSet = layoutSet;
+ for (int i = 0; i < sCategoryName.length; ++i) {
+ mCategoryNameToIdMap.put(sCategoryName[i], i);
+ }
+ addShownCategoryId(CATEGORY_ID_RECENTS);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ addShownCategoryId(CATEGORY_ID_PEOPLE);
+ addShownCategoryId(CATEGORY_ID_OBJECTS);
+ addShownCategoryId(CATEGORY_ID_NATURE);
+ addShownCategoryId(CATEGORY_ID_PLACES);
+ mCurrentCategoryId = CATEGORY_ID_PEOPLE;
+ } else {
+ mCurrentCategoryId = CATEGORY_ID_SYMBOLS;
+ }
+ addShownCategoryId(CATEGORY_ID_SYMBOLS);
+ addShownCategoryId(CATEGORY_ID_EMOTICONS);
+ getKeyboard(CATEGORY_ID_RECENTS, 0 /* cagetoryPageId */)
+ .loadRecentKeys(mCategoryKeyboardMap.values());
+ }
+
+ private void addShownCategoryId(int categoryId) {
+ // Load a keyboard of categoryId
+ getKeyboard(categoryId, 0 /* cagetoryPageId */);
+ final CategoryProperties properties =
+ new CategoryProperties(categoryId, getCategoryPageCount(categoryId));
+ mShownCategories.add(properties);
+ }
+
+ public String getCategoryName(int categoryId, int categoryPageId) {
+ return sCategoryName[categoryId] + "-" + categoryPageId;
+ }
+
+ public int getCategoryId(String name) {
+ final String[] strings = name.split("-");
+ return mCategoryNameToIdMap.get(strings[0]);
+ }
+
+ public int getCategoryIcon(int categoryId) {
+ return sCategoryIcon[categoryId];
+ }
+
+ public String getCategoryLabel(int categoryId) {
+ return sCategoryLabel[categoryId];
+ }
+
+ public ArrayList<CategoryProperties> getShownCategories() {
+ return mShownCategories;
+ }
+
+ public int getCurrentCategoryId() {
+ return mCurrentCategoryId;
+ }
+
+ public int getCurrentCategoryPageSize() {
+ return getCategoryPageSize(mCurrentCategoryId);
+ }
+
+ public int getCategoryPageSize(int categoryId) {
+ for (final CategoryProperties prop : mShownCategories) {
+ if (prop.mCategoryId == categoryId) {
+ return prop.mPageCount;
+ }
+ }
+ Log.w(TAG, "Invalid category id: " + categoryId);
+ // Should not reach here.
+ return 0;
+ }
+
+ public void setCurrentCategoryId(int categoryId) {
+ mCurrentCategoryId = categoryId;
+ }
+
+ public void setCurrentCategoryPageId(int id) {
+ mCurrentCategoryPageId = id;
+ }
+
+ public int getCurrentCategoryPageId() {
+ return mCurrentCategoryPageId;
+ }
+
+ public void saveLastTypedCategoryPage() {
+ Settings.writeEmojiCategoryLastTypedId(
+ mPrefs, mCurrentCategoryId, mCurrentCategoryPageId);
+ }
+
+ public boolean isInRecentTab() {
+ return mCurrentCategoryId == CATEGORY_ID_RECENTS;
+ }
+
+ public int getTabIdFromCategoryId(int categoryId) {
+ for (int i = 0; i < mShownCategories.size(); ++i) {
+ if (mShownCategories.get(i).mCategoryId == categoryId) {
+ return i;
+ }
+ }
+ Log.w(TAG, "categoryId not found: " + categoryId);
+ return 0;
+ }
+
+ // Returns the view pager's page position for the categoryId
+ public int getPageIdFromCategoryId(int categoryId) {
+ final int lastSavedCategoryPageId =
+ Settings.readEmojiCategoryLastTypedId(mPrefs, categoryId);
+ int sum = 0;
+ for (int i = 0; i < mShownCategories.size(); ++i) {
+ final CategoryProperties props = mShownCategories.get(i);
+ if (props.mCategoryId == categoryId) {
+ return sum + lastSavedCategoryPageId;
+ }
+ sum += props.mPageCount;
+ }
+ Log.w(TAG, "categoryId not found: " + categoryId);
+ return 0;
+ }
+
+ public int getRecentTabId() {
+ return getTabIdFromCategoryId(CATEGORY_ID_RECENTS);
+ }
+
+ private int getCategoryPageCount(int categoryId) {
+ final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]);
+ return (keyboard.getKeys().length - 1) / mMaxPageKeyCount + 1;
+ }
+
+ // Returns a pair of the category id and the category page id from the view pager's page
+ // position. The category page id is numbered in each category. And the view page position
+ // is the position of the current shown page in the view pager which contains all pages of
+ // all categories.
+ public Pair<Integer, Integer> getCategoryIdAndPageIdFromPagePosition(int position) {
+ int sum = 0;
+ for (CategoryProperties properties : mShownCategories) {
+ final int temp = sum;
+ sum += properties.mPageCount;
+ if (sum > position) {
+ return new Pair<Integer, Integer>(properties.mCategoryId, position - temp);
+ }
+ }
+ return null;
+ }
+
+ // Returns a keyboard from the view pager's page position.
+ public DynamicGridKeyboard getKeyboardFromPagePosition(int position) {
+ final Pair<Integer, Integer> categoryAndId =
+ getCategoryIdAndPageIdFromPagePosition(position);
+ if (categoryAndId != null) {
+ return getKeyboard(categoryAndId.first, categoryAndId.second);
+ }
+ return null;
+ }
+
+ public DynamicGridKeyboard getKeyboard(int categoryId, int id) {
+ synchronized(mCategoryKeyboardMap) {
+ final long key = (((long) categoryId) << Constants.MAX_INT_BIT_COUNT) | id;
+ final DynamicGridKeyboard kbd;
+ if (!mCategoryKeyboardMap.containsKey(key)) {
+ if (categoryId != CATEGORY_ID_RECENTS) {
+ final Keyboard keyboard =
+ mLayoutSet.getKeyboard(sCategoryElementId[categoryId]);
+ final Key[][] sortedKeys = sortKeys(keyboard.getKeys(), mMaxPageKeyCount);
+ for (int i = 0; i < sortedKeys.length; ++i) {
+ final DynamicGridKeyboard tempKbd = new DynamicGridKeyboard(mPrefs,
+ mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
+ mMaxPageKeyCount, categoryId, i /* categoryPageId */);
+ for (Key emojiKey : sortedKeys[i]) {
+ if (emojiKey == null) {
+ break;
+ }
+ tempKbd.addKeyLast(emojiKey);
+ }
+ mCategoryKeyboardMap.put((((long) categoryId)
+ << Constants.MAX_INT_BIT_COUNT) | i, tempKbd);
+ }
+ kbd = mCategoryKeyboardMap.get(key);
+ } else {
+ kbd = new DynamicGridKeyboard(mPrefs,
+ mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
+ mMaxPageKeyCount, categoryId, 0 /* categoryPageId */);
+ mCategoryKeyboardMap.put(key, kbd);
+ }
+ } else {
+ kbd = mCategoryKeyboardMap.get(key);
+ }
+ return kbd;
+ }
+ }
+
+ public int getTotalPageCountOfAllCategories() {
+ int sum = 0;
+ for (CategoryProperties properties : mShownCategories) {
+ sum += properties.mPageCount;
+ }
+ return sum;
+ }
+
+ private Key[][] sortKeys(Key[] inKeys, int maxPageCount) {
+ Key[] keys = Arrays.copyOf(inKeys, inKeys.length);
+ Arrays.sort(keys, 0, keys.length, new Comparator<Key>() {
+ @Override
+ public int compare(Key lhs, Key rhs) {
+ final Rect lHitBox = lhs.getHitBox();
+ final Rect rHitBox = rhs.getHitBox();
+ if (lHitBox.top < rHitBox.top) {
+ return -1;
+ } else if (lHitBox.top > rHitBox.top) {
+ return 1;
+ }
+ if (lHitBox.left < rHitBox.left) {
+ return -1;
+ } else if (lHitBox.left > rHitBox.left) {
+ return 1;
+ }
+ if (lhs.getCode() == rhs.getCode()) {
+ return 0;
+ }
+ return lhs.getCode() < rhs.getCode() ? -1 : 1;
+ }
+ });
+ final int pageCount = (keys.length - 1) / maxPageCount + 1;
+ final Key[][] retval = new Key[pageCount][maxPageCount];
+ for (int i = 0; i < keys.length; ++i) {
+ retval[i / maxPageCount][i % maxPageCount] = keys[i];
+ }
+ return retval;
+ }
+ }
+
+ private final EmojiCategory mEmojiCategory;
+
+ public EmojiKeyboardView(final Context context, final AttributeSet attrs) {
+ this(context, attrs, R.attr.emojiKeyboardViewStyle);
+ }
+
+ public EmojiKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
+ super(context, attrs, defStyle);
+ final TypedArray keyboardViewAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+ mKeyBackgroundId = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_keyBackground, 0);
+ mEmojiFunctionalKeyBackgroundId = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_keyBackgroundEmojiFunctional, 0);
+ keyboardViewAttr.recycle();
+ final TypedArray emojiKeyboardViewAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.EmojiKeyboardView, defStyle, R.style.EmojiKeyboardView);
+ mTabLabelColor = emojiKeyboardViewAttr.getColorStateList(
+ R.styleable.EmojiKeyboardView_emojiTabLabelColor);
+ emojiKeyboardViewAttr.recycle();
+ final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
+ context, null /* editorInfo */);
+ final Resources res = context.getResources();
+ final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res);
+ builder.setSubtype(SubtypeSwitcher.getInstance().getEmojiSubtype());
+ builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
+ emojiLp.mEmojiKeyboardHeight);
+ builder.setOptions(false, false, false /* lanuageSwitchKeyEnabled */);
+ mLayoutSet = builder.build();
+ mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context),
+ context.getResources(), builder.build());
+ mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(context);
+ }
+
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ final Resources res = getContext().getResources();
+ // The main keyboard expands to the entire this {@link KeyboardView}.
+ final int width = ResourceUtils.getDefaultKeyboardWidth(res)
+ + getPaddingLeft() + getPaddingRight();
+ final int height = ResourceUtils.getDefaultKeyboardHeight(res)
+ + res.getDimensionPixelSize(R.dimen.suggestions_strip_height)
+ + getPaddingTop() + getPaddingBottom();
+ setMeasuredDimension(width, height);
+ }
+
+ private void addTab(final TabHost host, final int categoryId) {
+ final String tabId = mEmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */);
+ final TabHost.TabSpec tspec = host.newTabSpec(tabId);
+ tspec.setContent(R.id.emoji_keyboard_dummy);
+ if (mEmojiCategory.getCategoryIcon(categoryId) != 0) {
+ final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate(
+ R.layout.emoji_keyboard_tab_icon, null);
+ iconView.setImageResource(mEmojiCategory.getCategoryIcon(categoryId));
+ tspec.setIndicator(iconView);
+ }
+ if (mEmojiCategory.getCategoryLabel(categoryId) != null) {
+ final TextView textView = (TextView)LayoutInflater.from(getContext()).inflate(
+ R.layout.emoji_keyboard_tab_label, null);
+ textView.setText(mEmojiCategory.getCategoryLabel(categoryId));
+ textView.setTextColor(mTabLabelColor);
+ tspec.setIndicator(textView);
+ }
+ host.addTab(tspec);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mTabHost = (TabHost)findViewById(R.id.emoji_category_tabhost);
+ mTabHost.setup();
+ for (final CategoryProperties properties : mEmojiCategory.getShownCategories()) {
+ addTab(mTabHost, properties.mCategoryId);
+ }
+ mTabHost.setOnTabChangedListener(this);
+ mTabHost.getTabWidget().setStripEnabled(true);
+
+ mEmojiKeyboardAdapter = new EmojiKeyboardAdapter(mEmojiCategory, mLayoutSet, this);
+
+ mEmojiPager = (ViewPager)findViewById(R.id.emoji_keyboard_pager);
+ mEmojiPager.setAdapter(mEmojiKeyboardAdapter);
+ mEmojiPager.setOnPageChangeListener(this);
+ mEmojiPager.setOffscreenPageLimit(0);
+ final Resources res = getResources();
+ final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res);
+ emojiLp.setPagerProperties(mEmojiPager);
+
+ mEmojiCategoryPageIndicatorView =
+ (EmojiCategoryPageIndicatorView)findViewById(R.id.emoji_category_page_id_view);
+ emojiLp.setCategoryPageIdViewProperties(mEmojiCategoryPageIndicatorView);
+
+ setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */);
+
+ final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar);
+ emojiLp.setActionBarProperties(actionBar);
+
+ final ImageView deleteKey = (ImageView)findViewById(R.id.emoji_keyboard_delete);
+ deleteKey.setTag(Constants.CODE_DELETE);
+ deleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
+ final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet);
+ alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
+ alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
+ alphabetKey.setOnClickListener(this);
+ final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
+ spaceKey.setBackgroundResource(mKeyBackgroundId);
+ spaceKey.setTag(Constants.CODE_SPACE);
+ spaceKey.setOnClickListener(this);
+ emojiLp.setKeyProperties(spaceKey);
+ final ImageView sendKey = (ImageView)findViewById(R.id.emoji_keyboard_send);
+ sendKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
+ sendKey.setTag(Constants.CODE_ENTER);
+ sendKey.setOnClickListener(this);
+ }
+
+ @Override
+ public void onTabChanged(final String tabId) {
+ final int categoryId = mEmojiCategory.getCategoryId(tabId);
+ setCurrentCategoryId(categoryId, false /* force */);
+ updateEmojiCategoryPageIdView();
+ }
+
+
+ @Override
+ public void onPageSelected(final int position) {
+ final Pair<Integer, Integer> newPos =
+ mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
+ setCurrentCategoryId(newPos.first /* categoryId */, false /* force */);
+ mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */);
+ updateEmojiCategoryPageIdView();
+ }
+
+ @Override
+ public void onPageScrollStateChanged(final int state) {
+ // Ignore this message. Only want the actual page selected.
+ }
+
+ @Override
+ public void onPageScrolled(final int position, final float positionOffset,
+ final int positionOffsetPixels) {
+ final Pair<Integer, Integer> newPos =
+ mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
+ final int newCategoryId = newPos.first;
+ final int newCategorySize = mEmojiCategory.getCategoryPageSize(newCategoryId);
+ final int currentCategoryId = mEmojiCategory.getCurrentCategoryId();
+ final int currentCategoryPageId = mEmojiCategory.getCurrentCategoryPageId();
+ final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageSize();
+ if (newCategoryId == currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ newCategorySize, newPos.second, positionOffset);
+ } else if (newCategoryId > currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ currentCategorySize, currentCategoryPageId, positionOffset);
+ } else if (newCategoryId < currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ currentCategorySize, currentCategoryPageId, positionOffset - 1);
+ }
+ }
+
+ @Override
+ public void onClick(final View v) {
+ if (v.getTag() instanceof Integer) {
+ final int code = (Integer)v.getTag();
+ registerCode(code);
+ return;
+ }
+ }
+
+ private void registerCode(final int code) {
+ mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
+ mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
+ mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
+ }
+
+ @Override
+ public void onKeyClick(final Key key) {
+ mEmojiKeyboardAdapter.addRecentKey(key);
+ mEmojiCategory.saveLastTypedCategoryPage();
+ final int code = key.getCode();
+ if (code == Constants.CODE_OUTPUT_TEXT) {
+ mKeyboardActionListener.onTextInput(key.getOutputText());
+ return;
+ }
+ registerCode(code);
+ }
+
+ public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) {
+ // TODO:
+ }
+
+ public void setKeyboardActionListener(final KeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ mDeleteKeyOnTouchListener.setKeyboardActionListener(mKeyboardActionListener);
+ }
+
+ private void updateEmojiCategoryPageIdView() {
+ if (mEmojiCategoryPageIndicatorView == null) {
+ return;
+ }
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ mEmojiCategory.getCurrentCategoryPageSize(),
+ mEmojiCategory.getCurrentCategoryPageId(), 0.0f /* offset */);
+ }
+
+ private void setCurrentCategoryId(final int categoryId, final boolean force) {
+ if (mEmojiCategory.getCurrentCategoryId() == categoryId && !force) {
+ return;
+ }
+
+ mEmojiCategory.setCurrentCategoryId(categoryId);
+ final int newTabId = mEmojiCategory.getTabIdFromCategoryId(categoryId);
+ final int newCategoryPageId = mEmojiCategory.getPageIdFromCategoryId(categoryId);
+ if (force || mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(
+ mEmojiPager.getCurrentItem()).first != categoryId) {
+ mEmojiPager.setCurrentItem(newCategoryPageId, false /* smoothScroll */);
+ }
+ if (force || mTabHost.getCurrentTab() != newTabId) {
+ mTabHost.setCurrentTab(newTabId);
+ }
+ }
+
+ private static class EmojiKeyboardAdapter extends PagerAdapter {
+ private final ScrollKeyboardView.OnKeyClickListener mListener;
+ private final DynamicGridKeyboard mRecentsKeyboard;
+ private final SparseArray<ScrollKeyboardView> mActiveKeyboardView =
+ CollectionUtils.newSparseArray();
+ private final EmojiCategory mEmojiCategory;
+ private int mActivePosition = 0;
+
+ public EmojiKeyboardAdapter(final EmojiCategory emojiCategory,
+ final KeyboardLayoutSet layoutSet,
+ final ScrollKeyboardView.OnKeyClickListener listener) {
+ mEmojiCategory = emojiCategory;
+ mListener = listener;
+ mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0);
+ }
+
+ public void addRecentKey(final Key key) {
+ if (mEmojiCategory.isInRecentTab()) {
+ return;
+ }
+ mRecentsKeyboard.addKeyFirst(key);
+ final KeyboardView recentKeyboardView =
+ mActiveKeyboardView.get(mEmojiCategory.getRecentTabId());
+ if (recentKeyboardView != null) {
+ recentKeyboardView.invalidateAllKeys();
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return mEmojiCategory.getTotalPageCountOfAllCategories();
+ }
+
+ @Override
+ public void setPrimaryItem(final View container, final int position, final Object object) {
+ if (mActivePosition == position) {
+ return;
+ }
+ final ScrollKeyboardView oldKeyboardView = mActiveKeyboardView.get(mActivePosition);
+ if (oldKeyboardView != null) {
+ oldKeyboardView.releaseCurrentKey();
+ oldKeyboardView.deallocateMemory();
+ }
+ mActivePosition = position;
+ }
+
+ @Override
+ public Object instantiateItem(final ViewGroup container, final int position) {
+ final Keyboard keyboard =
+ mEmojiCategory.getKeyboardFromPagePosition(position);
+ final LayoutInflater inflater = LayoutInflater.from(container.getContext());
+ final View view = inflater.inflate(
+ R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
+ final ScrollKeyboardView keyboardView = (ScrollKeyboardView)view.findViewById(
+ R.id.emoji_keyboard_page);
+ keyboardView.setKeyboard(keyboard);
+ keyboardView.setOnKeyClickListener(mListener);
+ final ScrollViewWithNotifier scrollView = (ScrollViewWithNotifier)view.findViewById(
+ R.id.emoji_keyboard_scroller);
+ keyboardView.setScrollView(scrollView);
+ container.addView(view);
+ mActiveKeyboardView.put(position, keyboardView);
+ return view;
+ }
+
+ @Override
+ public boolean isViewFromObject(final View view, final Object object) {
+ return view == object;
+ }
+
+ @Override
+ public void destroyItem(final ViewGroup container, final int position,
+ final Object object) {
+ final ScrollKeyboardView keyboardView = mActiveKeyboardView.get(position);
+ if (keyboardView != null) {
+ keyboardView.deallocateMemory();
+ mActiveKeyboardView.remove(position);
+ }
+ container.removeView(keyboardView);
+ }
+ }
+
+ // TODO: Do the same things done in PointerTracker
+ private static class DeleteKeyOnTouchListener implements OnTouchListener {
+ private static final long MAX_REPEAT_COUNT_TIME = 30 * DateUtils.SECOND_IN_MILLIS;
+ private final int mDeleteKeyPressedBackgroundColor;
+ private final long mKeyRepeatStartTimeout;
+ private final long mKeyRepeatInterval;
+
+ public DeleteKeyOnTouchListener(Context context) {
+ final Resources res = context.getResources();
+ mDeleteKeyPressedBackgroundColor =
+ res.getColor(R.color.emoji_key_pressed_background_color);
+ mKeyRepeatStartTimeout = res.getInteger(R.integer.config_key_repeat_start_timeout);
+ mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+ }
+
+ private KeyboardActionListener mKeyboardActionListener =
+ KeyboardActionListener.EMPTY_LISTENER;
+ private DummyRepeatKeyRepeatTimer mTimer;
+
+ private synchronized void startRepeat() {
+ if (mTimer != null) {
+ abortRepeat();
+ }
+ mTimer = new DummyRepeatKeyRepeatTimer();
+ mTimer.start();
+ }
+
+ private synchronized void abortRepeat() {
+ mTimer.abort();
+ mTimer = null;
+ }
+
+ // TODO: Remove
+ // This function is mimicking the repeat code in PointerTracker.
+ // Specifically referring to PointerTracker#startRepeatKey and PointerTracker#onKeyRepeat.
+ private class DummyRepeatKeyRepeatTimer extends Thread {
+ public boolean mAborted = false;
+
+ @Override
+ public void run() {
+ int timeCount = 0;
+ while (timeCount < MAX_REPEAT_COUNT_TIME && !mAborted) {
+ if (timeCount > mKeyRepeatStartTimeout) {
+ pressDelete();
+ }
+ timeCount += mKeyRepeatInterval;
+ try {
+ Thread.sleep(mKeyRepeatInterval);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public void abort() {
+ mAborted = true;
+ }
+ }
+
+ public void pressDelete() {
+ mKeyboardActionListener.onPressKey(
+ Constants.CODE_DELETE, 0 /* repeatCount */, true /* isSinglePointer */);
+ mKeyboardActionListener.onCodeInput(
+ Constants.CODE_DELETE, NOT_A_COORDINATE, NOT_A_COORDINATE);
+ mKeyboardActionListener.onReleaseKey(
+ Constants.CODE_DELETE, false /* withSliding */);
+ }
+
+ public void setKeyboardActionListener(KeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch(event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ v.setBackgroundColor(mDeleteKeyPressedBackgroundColor);
+ pressDelete();
+ startRepeat();
+ return true;
+ case MotionEvent.ACTION_UP:
+ v.setBackgroundColor(0);
+ abortRepeat();
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java
new file mode 100644
index 000000000..267fad5cd
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard;
+
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+
+import android.content.res.Resources;
+import android.support.v4.view.ViewPager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+public class EmojiLayoutParams {
+ private static final int DEFAULT_KEYBOARD_ROWS = 4;
+
+ public final int mEmojiPagerHeight;
+ private final int mEmojiPagerBottomMargin;
+ public final int mEmojiKeyboardHeight;
+ private final int mEmojiCategoryPageIdViewHeight;
+ public final int mEmojiActionBarHeight;
+ public final int mKeyVerticalGap;
+ private final int mKeyHorizontalGap;
+ private final int mBottomPadding;
+ private final int mTopPadding;
+
+ public EmojiLayoutParams(Resources res) {
+ final int defaultKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
+ final int defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
+ mKeyVerticalGap = (int) res.getFraction(R.fraction.key_bottom_gap_ics,
+ (int) defaultKeyboardHeight, (int) defaultKeyboardHeight);
+ mBottomPadding = (int) res.getFraction(R.fraction.keyboard_bottom_padding_ics,
+ (int) defaultKeyboardHeight, (int) defaultKeyboardHeight);
+ mTopPadding = (int) res.getFraction(R.fraction.keyboard_top_padding_ics,
+ (int) defaultKeyboardHeight, (int) defaultKeyboardHeight);
+ mKeyHorizontalGap = (int) (res.getFraction(R.fraction.key_horizontal_gap_ics,
+ defaultKeyboardWidth, defaultKeyboardWidth));
+ mEmojiCategoryPageIdViewHeight =
+ (int) (res.getDimension(R.dimen.emoji_category_page_id_height));
+ final int baseheight = defaultKeyboardHeight - mBottomPadding - mTopPadding
+ + mKeyVerticalGap;
+ mEmojiActionBarHeight = ((int) baseheight) / DEFAULT_KEYBOARD_ROWS
+ - (mKeyVerticalGap - mBottomPadding) / 2;
+ mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight
+ - mEmojiCategoryPageIdViewHeight;
+ mEmojiPagerBottomMargin = mKeyVerticalGap / 2;
+ mEmojiKeyboardHeight = mEmojiPagerHeight - mEmojiPagerBottomMargin - 1;
+ }
+
+ public void setPagerProperties(ViewPager vp) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams();
+ lp.height = mEmojiKeyboardHeight;
+ lp.bottomMargin = mEmojiPagerBottomMargin;
+ vp.setLayoutParams(lp);
+ }
+
+ public void setCategoryPageIdViewProperties(LinearLayout ll) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
+ lp.height = mEmojiCategoryPageIdViewHeight;
+ ll.setLayoutParams(lp);
+ }
+
+ public void setActionBarProperties(LinearLayout ll) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
+ lp.height = mEmojiActionBarHeight;
+ lp.topMargin = 0;
+ lp.bottomMargin = mBottomPadding;
+ ll.setLayoutParams(lp);
+ }
+
+ public void setKeyProperties(ImageView ib) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ib.getLayoutParams();
+ lp.leftMargin = mKeyHorizontalGap / 2;
+ lp.rightMargin = mKeyHorizontalGap / 2;
+ ib.setLayoutParams(lp);
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 61805286d..3ea68806b 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -58,12 +58,12 @@ public class Key implements Comparable<Key> {
/**
* The key code (unicode or custom code) that this key generates.
*/
- public final int mCode;
+ private final int mCode;
/** Label to display */
- public final String mLabel;
+ private final String mLabel;
/** Hint label to display on the key in conjunction with the label */
- public final String mHintLabel;
+ private final String mHintLabel;
/** Flags of the label */
private final int mLabelFlags;
private static final int LABEL_FLAGS_ALIGN_LEFT = 0x01;
@@ -95,18 +95,18 @@ public class Key implements Comparable<Key> {
private final int mIconId;
/** Width of the key, not including the gap */
- public final int mWidth;
+ private final int mWidth;
/** Height of the key, not including the gap */
- public final int mHeight;
+ private final int mHeight;
/** X coordinate of the key in the keyboard layout */
- public final int mX;
+ private final int mX;
/** Y coordinate of the key in the keyboard layout */
- public final int mY;
+ private final int mY;
/** Hit bounding box of the key */
- public final Rect mHitBox = new Rect();
+ private final Rect mHitBox = new Rect();
/** More keys. It is guaranteed that this is null or an array of one or more elements */
- public final MoreKeySpec[] mMoreKeys;
+ private final MoreKeySpec[] mMoreKeys;
/** More keys column number and flags */
private final int mMoreKeysColumnAndFlags;
private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff;
@@ -121,12 +121,13 @@ public class Key implements Comparable<Key> {
private static final String MORE_KEYS_NO_PANEL_AUTO_MORE_KEY = "!noPanelAutoMoreKey!";
/** Background type that represents different key background visual than normal one. */
- public final int mBackgroundType;
- public static final int BACKGROUND_TYPE_NORMAL = 0;
- public static final int BACKGROUND_TYPE_FUNCTIONAL = 1;
- public static final int BACKGROUND_TYPE_ACTION = 2;
- public static final int BACKGROUND_TYPE_STICKY_OFF = 3;
- public static final int BACKGROUND_TYPE_STICKY_ON = 4;
+ private final int mBackgroundType;
+ public static final int BACKGROUND_TYPE_EMPTY = 0;
+ public static final int BACKGROUND_TYPE_NORMAL = 1;
+ public static final int BACKGROUND_TYPE_FUNCTIONAL = 2;
+ public static final int BACKGROUND_TYPE_ACTION = 3;
+ public static final int BACKGROUND_TYPE_STICKY_OFF = 4;
+ public static final int BACKGROUND_TYPE_STICKY_ON = 5;
private final int mActionFlags;
private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
@@ -134,7 +135,7 @@ public class Key implements Comparable<Key> {
private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
- public final KeyVisualAttributes mKeyVisualAttributes;
+ private final KeyVisualAttributes mKeyVisualAttributes;
private final OptionalAttributes mOptionalAttributes;
@@ -150,7 +151,7 @@ public class Key implements Comparable<Key> {
public final int mVisualInsetsLeft;
public final int mVisualInsetsRight;
- public OptionalAttributes(final String outputText, final int altCode,
+ private OptionalAttributes(final String outputText, final int altCode,
final int disabledIconId, final int previewIconId,
final int visualInsetsLeft, final int visualInsetsRight) {
mOutputText = outputText;
@@ -160,6 +161,18 @@ public class Key implements Comparable<Key> {
mVisualInsetsLeft = visualInsetsLeft;
mVisualInsetsRight = visualInsetsRight;
}
+
+ public static OptionalAttributes newInstance(final String outputText, final int altCode,
+ final int disabledIconId, final int previewIconId,
+ final int visualInsetsLeft, final int visualInsetsRight) {
+ if (outputText == null && altCode == CODE_UNSPECIFIED
+ && disabledIconId == ICON_UNDEFINED && previewIconId == ICON_UNDEFINED
+ && visualInsetsLeft == 0 && visualInsetsRight == 0) {
+ return null;
+ }
+ return new OptionalAttributes(outputText, altCode, disabledIconId, previewIconId,
+ visualInsetsLeft, visualInsetsRight);
+ }
}
private final int mHashCode;
@@ -175,7 +188,7 @@ public class Key implements Comparable<Key> {
public Key(final KeyboardParams params, final MoreKeySpec moreKeySpec, final int x, final int y,
final int width, final int height, final int labelFlags) {
this(params, moreKeySpec.mLabel, null, moreKeySpec.mIconId, moreKeySpec.mCode,
- moreKeySpec.mOutputText, x, y, width, height, labelFlags);
+ moreKeySpec.mOutputText, x, y, width, height, labelFlags, BACKGROUND_TYPE_NORMAL);
}
/**
@@ -183,22 +196,19 @@ public class Key implements Comparable<Key> {
*/
public Key(final KeyboardParams params, final String label, final String hintLabel,
final int iconId, final int code, final String outputText, final int x, final int y,
- final int width, final int height, final int labelFlags) {
+ final int width, final int height, final int labelFlags, final int backgroundType) {
mHeight = height - params.mVerticalGap;
mWidth = width - params.mHorizontalGap;
mHintLabel = hintLabel;
mLabelFlags = labelFlags;
- mBackgroundType = BACKGROUND_TYPE_NORMAL;
+ mBackgroundType = backgroundType;
mActionFlags = 0;
mMoreKeys = null;
mMoreKeysColumnAndFlags = 0;
mLabel = label;
- if (outputText == null) {
- mOptionalAttributes = null;
- } else {
- mOptionalAttributes = new OptionalAttributes(outputText, CODE_UNSPECIFIED,
- ICON_UNDEFINED, ICON_UNDEFINED, 0, 0);
- }
+ mOptionalAttributes = OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED,
+ ICON_UNDEFINED, ICON_UNDEFINED,
+ 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */);
mCode = code;
mEnabled = (code != CODE_UNSPECIFIED);
mIconId = iconId;
@@ -224,7 +234,7 @@ public class Key implements Comparable<Key> {
public Key(final Resources res, final KeyboardParams params, final KeyboardRow row,
final XmlPullParser parser) throws XmlPullParserException {
final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
- final int rowHeight = row.mRowHeight;
+ final int rowHeight = row.getRowHeight();
mHeight = rowHeight - params.mVerticalGap;
final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
@@ -259,11 +269,11 @@ public class Key implements Comparable<Key> {
final int previewIconId = KeySpecParser.getIconId(style.getString(keyAttr,
R.styleable.Keyboard_Key_keyIconPreview));
- mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
+ mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
| row.getDefaultKeyLabelFlags();
final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId);
final Locale locale = params.mId.mLocale;
- int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
+ int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
int moreKeysColumn = style.getInt(keyAttr,
@@ -359,15 +369,8 @@ public class Key implements Comparable<Key> {
KeySpecParser.parseCode(style.getString(keyAttr,
R.styleable.Keyboard_Key_altCode), params.mCodesSet, CODE_UNSPECIFIED),
needsToUpperCase, locale);
- if (outputText == null && altCode == CODE_UNSPECIFIED
- && disabledIconId == ICON_UNDEFINED && previewIconId == ICON_UNDEFINED
- && visualInsetsLeft == 0 && visualInsetsRight == 0) {
- mOptionalAttributes = null;
- } else {
- mOptionalAttributes = new OptionalAttributes(outputText, altCode,
- disabledIconId, previewIconId,
- visualInsetsLeft, visualInsetsRight);
- }
+ mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode,
+ disabledIconId, previewIconId, visualInsetsLeft, visualInsetsRight);
mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
keyAttr.recycle();
mHashCode = computeHashCode(this);
@@ -376,6 +379,35 @@ public class Key implements Comparable<Key> {
}
}
+ /**
+ * Copy constructor.
+ *
+ * @param key the original key.
+ */
+ protected Key(final Key key) {
+ // Final attributes.
+ mCode = key.mCode;
+ mLabel = key.mLabel;
+ mHintLabel = key.mHintLabel;
+ mLabelFlags = key.mLabelFlags;
+ mIconId = key.mIconId;
+ mWidth = key.mWidth;
+ mHeight = key.mHeight;
+ mX = key.mX;
+ mY = key.mY;
+ mHitBox.set(key.mHitBox);
+ mMoreKeys = key.mMoreKeys;
+ mMoreKeysColumnAndFlags = key.mMoreKeysColumnAndFlags;
+ mBackgroundType = key.mBackgroundType;
+ mActionFlags = key.mActionFlags;
+ mKeyVisualAttributes = key.mKeyVisualAttributes;
+ mOptionalAttributes = key.mOptionalAttributes;
+ mHashCode = key.mHashCode;
+ // Key state.
+ mPressed = key.mPressed;
+ mEnabled = key.mEnabled;
+ }
+
private static boolean needsToUpperCase(final int labelFlags, final int keyboardElementId) {
if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
switch (keyboardElementId) {
@@ -465,6 +497,7 @@ public class Key implements Comparable<Key> {
private static String backgroundName(final int backgroundType) {
switch (backgroundType) {
+ case BACKGROUND_TYPE_EMPTY: return "empty";
case BACKGROUND_TYPE_NORMAL: return "normal";
case BACKGROUND_TYPE_FUNCTIONAL: return "functional";
case BACKGROUND_TYPE_ACTION: return "action";
@@ -474,6 +507,22 @@ public class Key implements Comparable<Key> {
}
}
+ public int getCode() {
+ return mCode;
+ }
+
+ public String getLabel() {
+ return mLabel;
+ }
+
+ public String getHintLabel() {
+ return mHintLabel;
+ }
+
+ public MoreKeySpec[] getMoreKeys() {
+ return mMoreKeys;
+ }
+
public void markAsLeftEdge(final KeyboardParams params) {
mHitBox.left = params.mLeftPadding;
}
@@ -520,6 +569,10 @@ public class Key implements Comparable<Key> {
&& (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0;
}
+ public KeyVisualAttributes getVisualAttributes() {
+ return mKeyVisualAttributes;
+ }
+
public final Typeface selectTypeface(final KeyDrawParams params) {
// TODO: Handle "bold" here too?
if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
@@ -694,9 +747,26 @@ public class Key implements Comparable<Key> {
? iconSet.getIconDrawable(previewIconId) : iconSet.getIconDrawable(mIconId);
}
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
+
+ public int getX() {
+ return mX;
+ }
+
+ public int getY() {
+ return mY;
+ }
+
public final int getDrawX() {
+ final int x = getX();
final OptionalAttributes attrs = mOptionalAttributes;
- return (attrs == null) ? mX : mX + attrs.mVisualInsetsLeft;
+ return (attrs == null) ? x : x + attrs.mVisualInsetsLeft;
}
public final int getDrawWidth() {
@@ -731,6 +801,10 @@ public class Key implements Comparable<Key> {
mEnabled = enabled;
}
+ public Rect getHitBox() {
+ return mHitBox;
+ }
+
/**
* Detects if a point falls on this key.
* @param x the x-coordinate of the point
@@ -750,9 +824,9 @@ public class Key implements Comparable<Key> {
* @return the square of the distance of the point from the nearest edge of the key
*/
public int squaredDistanceToEdge(final int x, final int y) {
- final int left = mX;
+ final int left = getX();
final int right = left + mWidth;
- final int top = mY;
+ final int top = getY();
final int bottom = top + mHeight;
final int edgeX = x < left ? left : (x > right ? right : x);
final int edgeY = y < top ? top : (y > bottom ? bottom : y);
@@ -788,6 +862,10 @@ public class Key implements Comparable<Key> {
android.R.attr.state_pressed
};
+ private final static int[] KEY_STATE_EMPTY = {
+ android.R.attr.state_empty
+ };
+
// functional normal state (with properties)
private static final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
android.R.attr.state_single
@@ -825,6 +903,8 @@ public class Key implements Comparable<Key> {
return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
case BACKGROUND_TYPE_STICKY_ON:
return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
+ case BACKGROUND_TYPE_EMPTY:
+ return mPressed ? KEY_STATE_PRESSED : KEY_STATE_EMPTY;
default: /* BACKGROUND_TYPE_NORMAL */
return mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
}
@@ -842,7 +922,7 @@ public class Key implements Comparable<Key> {
protected Spacer(final KeyboardParams params, final int x, final int y, final int width,
final int height) {
super(params, null, null, ICON_UNDEFINED, CODE_UNSPECIFIED,
- null, x, y, width, height, 0);
+ null, x, y, width, height, 0, BACKGROUND_TYPE_EMPTY);
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 17e707f95..befb6fa92 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -108,8 +108,9 @@ public class KeyDetector {
if (distance > minDistance) {
continue;
}
- // To take care of hitbox overlaps, we compare mCode here too.
- if (primaryKey == null || distance < minDistance || key.mCode > primaryKey.mCode) {
+ // To take care of hitbox overlaps, we compare key's code here too.
+ if (primaryKey == null || distance < minDistance
+ || key.getCode() > primaryKey.getCode()) {
minDistance = distance;
primaryKey = key;
}
@@ -118,7 +119,7 @@ public class KeyDetector {
}
public static String printableCode(Key key) {
- return key != null ? Constants.printableCode(key.mCode) : "none";
+ return key != null ? Constants.printableCode(key.getCode()) : "none";
}
public static String printableCodes(int[] codes) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index fefac96fd..bc1383aff 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -51,6 +51,11 @@ public class Keyboard {
/** Total width of the keyboard, including the padding and keys */
public final int mOccupiedWidth;
+ /** Base height of the keyboard, used to calculate rows' height */
+ public final int mBaseHeight;
+ /** Base width of the keyboard, used to calculate keys' width */
+ public final int mBaseWidth;
+
/** The padding above the keyboard */
public final int mTopPadding;
/** Default gap between rows */
@@ -69,7 +74,7 @@ public class Keyboard {
public final int mMaxMoreKeysKeyboardColumn;
/** Array of keys and icons in this keyboard */
- public final Key[] mKeys;
+ private final Key[] mKeys;
public final Key[] mShiftKeys;
public final Key[] mAltCodeKeysWhileTyping;
public final KeyboardIconsSet mIconsSet;
@@ -84,6 +89,8 @@ public class Keyboard {
mThemeId = params.mThemeId;
mOccupiedHeight = params.mOccupiedHeight;
mOccupiedWidth = params.mOccupiedWidth;
+ mBaseHeight = params.mBaseHeight;
+ mBaseWidth = params.mBaseWidth;
mMostCommonKeyHeight = params.mMostCommonKeyHeight;
mMostCommonKeyWidth = params.mMostCommonKeyWidth;
mMoreKeysTemplate = params.mMoreKeysTemplate;
@@ -104,6 +111,30 @@ public class Keyboard {
mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled;
}
+ protected Keyboard(final Keyboard keyboard) {
+ mId = keyboard.mId;
+ mThemeId = keyboard.mThemeId;
+ mOccupiedHeight = keyboard.mOccupiedHeight;
+ mOccupiedWidth = keyboard.mOccupiedWidth;
+ mBaseHeight = keyboard.mBaseHeight;
+ mBaseWidth = keyboard.mBaseWidth;
+ mMostCommonKeyHeight = keyboard.mMostCommonKeyHeight;
+ mMostCommonKeyWidth = keyboard.mMostCommonKeyWidth;
+ mMoreKeysTemplate = keyboard.mMoreKeysTemplate;
+ mMaxMoreKeysKeyboardColumn = keyboard.mMaxMoreKeysKeyboardColumn;
+ mKeyVisualAttributes = keyboard.mKeyVisualAttributes;
+ mTopPadding = keyboard.mTopPadding;
+ mVerticalGap = keyboard.mVerticalGap;
+
+ mKeys = keyboard.mKeys;
+ mShiftKeys = keyboard.mShiftKeys;
+ mAltCodeKeysWhileTyping = keyboard.mAltCodeKeysWhileTyping;
+ mIconsSet = keyboard.mIconsSet;
+
+ mProximityInfo = keyboard.mProximityInfo;
+ mProximityCharsCorrectionEnabled = keyboard.mProximityCharsCorrectionEnabled;
+ }
+
public boolean hasProximityCharsCorrection(final int code) {
if (!mProximityCharsCorrectionEnabled) {
return false;
@@ -120,6 +151,19 @@ public class Keyboard {
return mProximityInfo;
}
+ public Key[] getKeys() {
+ return mKeys;
+ }
+
+ public Key getKeyFromOutputText(final String outputText) {
+ for (final Key key : getKeys()) {
+ if (outputText.equals(key.getOutputText())) {
+ return key;
+ }
+ }
+ return null;
+ }
+
public Key getKey(final int code) {
if (code == Constants.CODE_UNSPECIFIED) {
return null;
@@ -130,8 +174,8 @@ public class Keyboard {
return mKeyCache.valueAt(index);
}
- for (final Key key : mKeys) {
- if (key.mCode == code) {
+ for (final Key key : getKeys()) {
+ if (key.getCode() == code) {
mKeyCache.put(code, key);
return key;
}
@@ -146,9 +190,9 @@ public class Keyboard {
return true;
}
- for (final Key key : mKeys) {
+ for (final Key key : getKeys()) {
if (key == aKey) {
- mKeyCache.put(key.mCode, key);
+ mKeyCache.put(key.getCode(), key);
return true;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index b26698665..dc760e685 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -26,10 +26,10 @@ public interface KeyboardActionListener {
*
* @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key,
* the value will be zero.
- * @param isRepeatKey true if pressing has occurred while key repeat input.
+ * @param repeatCount how many times the key was repeated. Zero if it is the first press.
* @param isSinglePointer true if pressing has occurred while no other key is being pressed.
*/
- public void onPressKey(int primaryCode, boolean isRepeatKey, boolean isSinglePointer);
+ public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer);
/**
* Called when the user releases a key. This is sent after the {@link #onCodeInput} is called.
@@ -103,7 +103,7 @@ public interface KeyboardActionListener {
public static class Adapter implements KeyboardActionListener {
@Override
- public void onPressKey(int primaryCode, boolean isRepeatKey, boolean isSinglePointer) {}
+ public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer) {}
@Override
public void onReleaseKey(int primaryCode, boolean withSliding) {}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 1dc3c6a4c..736f13ed6 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -54,6 +54,13 @@ public final class KeyboardId {
public static final int ELEMENT_PHONE = 7;
public static final int ELEMENT_PHONE_SYMBOLS = 8;
public static final int ELEMENT_NUMBER = 9;
+ public static final int ELEMENT_EMOJI_RECENTS = 10;
+ public static final int ELEMENT_EMOJI_CATEGORY1 = 11;
+ public static final int ELEMENT_EMOJI_CATEGORY2 = 12;
+ public static final int ELEMENT_EMOJI_CATEGORY3 = 13;
+ public static final int ELEMENT_EMOJI_CATEGORY4 = 14;
+ public static final int ELEMENT_EMOJI_CATEGORY5 = 15;
+ public static final int ELEMENT_EMOJI_CATEGORY6 = 16;
public final InputMethodSubtype mSubtype;
public final Locale mLocale;
@@ -217,6 +224,13 @@ public final class KeyboardId {
case ELEMENT_PHONE: return "phone";
case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols";
case ELEMENT_NUMBER: return "number";
+ case ELEMENT_EMOJI_RECENTS: return "emojiRecents";
+ case ELEMENT_EMOJI_CATEGORY1: return "emojiCategory1";
+ case ELEMENT_EMOJI_CATEGORY2: return "emojiCategory2";
+ case ELEMENT_EMOJI_CATEGORY3: return "emojiCategory3";
+ case ELEMENT_EMOJI_CATEGORY4: return "emojiCategory4";
+ case ELEMENT_EMOJI_CATEGORY5: return "emojiCategory5";
+ case ELEMENT_EMOJI_CATEGORY6: return "emojiCategory6";
default: return null;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index e97f29452..1eccdf341 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -106,6 +106,8 @@ public final class KeyboardLayoutSet {
EditorInfo mEditorInfo;
boolean mDisableTouchPositionCorrectionDataForTest;
boolean mVoiceKeyEnabled;
+ // TODO: Remove mVoiceKeyOnMain when it's certainly confirmed that we no longer show
+ // the voice input key on the symbol layout
boolean mVoiceKeyOnMain;
boolean mNoSettingsKey;
boolean mLanguageSwitchKeyEnabled;
@@ -162,7 +164,8 @@ public final class KeyboardLayoutSet {
final KeyboardId id = new KeyboardId(keyboardLayoutSetElementId, mParams);
try {
return getKeyboard(elementParams, id);
- } catch (RuntimeException e) {
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "Can't create keyboard: " + id, e);
throw new KeyboardLayoutSetException(e, id);
}
}
@@ -213,7 +216,6 @@ public final class KeyboardLayoutSet {
private final Context mContext;
private final String mPackageName;
private final Resources mResources;
- private final EditorInfo mEditorInfo;
private final Params mParams = new Params();
@@ -223,13 +225,12 @@ public final class KeyboardLayoutSet {
mContext = context;
mPackageName = context.getPackageName();
mResources = context.getResources();
- mEditorInfo = editorInfo;
final Params params = mParams;
params.mMode = getKeyboardMode(editorInfo);
params.mEditorInfo = (editorInfo != null) ? editorInfo : EMPTY_EDITOR_INFO;
params.mNoSettingsKey = InputAttributes.inPrivateImeOptions(
- mPackageName, NO_SETTINGS_KEY, mEditorInfo);
+ mPackageName, NO_SETTINGS_KEY, params.mEditorInfo);
}
public Builder setKeyboardGeometry(final int keyboardWidth, final int keyboardHeight) {
@@ -242,7 +243,7 @@ public final class KeyboardLayoutSet {
final boolean asciiCapable = subtype.containsExtraValueKey(ASCII_CAPABLE);
@SuppressWarnings("deprecation")
final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
- mPackageName, FORCE_ASCII, mEditorInfo);
+ mPackageName, FORCE_ASCII, mParams.mEditorInfo);
final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
mParams.mEditorInfo.imeOptions)
|| deprecatedForceAscii;
@@ -260,13 +261,15 @@ public final class KeyboardLayoutSet {
return this;
}
+ // TODO: Remove mVoiceKeyOnMain when it's certainly confirmed that we no longer show
+ // the voice input key on the symbol layout
public Builder setOptions(final boolean voiceKeyEnabled, final boolean voiceKeyOnMain,
final boolean languageSwitchKeyEnabled) {
@SuppressWarnings("deprecation")
final boolean deprecatedNoMicrophone = InputAttributes.inPrivateImeOptions(
- null, NO_MICROPHONE_COMPAT, mEditorInfo);
+ null, NO_MICROPHONE_COMPAT, mParams.mEditorInfo);
final boolean noMicrophone = InputAttributes.inPrivateImeOptions(
- mPackageName, NO_MICROPHONE, mEditorInfo)
+ mPackageName, NO_MICROPHONE, mParams.mEditorInfo)
|| deprecatedNoMicrophone;
mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone;
mParams.mVoiceKeyOnMain = voiceKeyOnMain;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 1ea0f8b96..cc1ffd183 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -58,19 +58,17 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
private static final KeyboardTheme[] KEYBOARD_THEMES = {
- new KeyboardTheme(0, R.style.KeyboardTheme),
- new KeyboardTheme(1, R.style.KeyboardTheme_HighContrast),
- new KeyboardTheme(6, R.style.KeyboardTheme_Stone),
- new KeyboardTheme(7, R.style.KeyboardTheme_Stone_Bold),
- new KeyboardTheme(8, R.style.KeyboardTheme_Gingerbread),
- new KeyboardTheme(5, R.style.KeyboardTheme_IceCreamSandwich),
+ new KeyboardTheme(0, R.style.KeyboardTheme_ICS),
+ new KeyboardTheme(1, R.style.KeyboardTheme_GB),
};
private SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs;
private InputView mCurrentInputView;
+ private View mMainKeyboardFrame;
private MainKeyboardView mKeyboardView;
+ private EmojiKeyboardView mEmojiKeyboardView;
private LatinIME mLatinIME;
private Resources mResources;
@@ -121,8 +119,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
} catch (NumberFormatException e) {
// Format error, keyboard theme is default to 0.
}
- Log.w(TAG, "Illegal keyboard theme in preference: " + themeIndex + ", default to 0");
- return KEYBOARD_THEMES[0];
+ Log.w(TAG, "Illegal keyboard theme in preference: " + themeIndex + ", default to "
+ + defaultIndex);
+ return KEYBOARD_THEMES[Integer.valueOf(defaultIndex)];
}
private void setContextThemeWrapper(final Context context, final KeyboardTheme keyboardTheme) {
@@ -143,7 +142,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
builder.setSubtype(mSubtypeSwitcher.getCurrentSubtype());
builder.setOptions(
settingsValues.isVoiceKeyEnabled(editorInfo),
- settingsValues.isVoiceKeyOnMain(),
+ true /* always show a voice key on the main keyboard */,
settingsValues.isLanguageSwitchKeyEnabled());
mKeyboardLayoutSet = builder.build();
try {
@@ -170,6 +169,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
private void setKeyboard(final Keyboard keyboard) {
+ // Make {@link MainKeyboardView} visible and hide {@link EmojiKeyboardView}.
+ setMainKeyboardFrame();
final MainKeyboardView keyboardView = mKeyboardView;
final Keyboard oldKeyboard = keyboardView.getKeyboard();
keyboardView.setKeyboard(keyboard);
@@ -256,6 +257,18 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS));
}
+ private void setMainKeyboardFrame() {
+ mMainKeyboardFrame.setVisibility(View.VISIBLE);
+ mEmojiKeyboardView.setVisibility(View.GONE);
+ }
+
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setEmojiKeyboard() {
+ mMainKeyboardFrame.setVisibility(View.GONE);
+ mEmojiKeyboardView.setVisibility(View.VISIBLE);
+ }
+
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setSymbolsShiftedKeyboard() {
@@ -301,6 +314,24 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mState.onCodeInput(code, mLatinIME.getCurrentAutoCapsState());
}
+ public boolean isShowingEmojiKeyboard() {
+ return mEmojiKeyboardView.getVisibility() == View.VISIBLE;
+ }
+
+ public boolean isShowingMoreKeysPanel() {
+ if (isShowingEmojiKeyboard()) {
+ return false;
+ }
+ return mKeyboardView.isShowingMoreKeysPanel();
+ }
+
+ public View getVisibleKeyboardView() {
+ if (isShowingEmojiKeyboard()) {
+ return mEmojiKeyboardView;
+ }
+ return mKeyboardView;
+ }
+
public MainKeyboardView getMainKeyboardView() {
return mKeyboardView;
}
@@ -313,10 +344,16 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
setContextThemeWrapper(mLatinIME, mKeyboardTheme);
mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
R.layout.input_view, null);
+ mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
+ mEmojiKeyboardView = (EmojiKeyboardView)mCurrentInputView.findViewById(
+ R.id.emoji_keyboard_view);
mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
mKeyboardView.setKeyboardActionListener(mLatinIME);
+ mEmojiKeyboardView.setHardwareAcceleratedDrawingEnabled(
+ isHardwareAcceleratedDrawingEnabled);
+ mEmojiKeyboardView.setKeyboardActionListener(mLatinIME);
// This always needs to be set since the accessibility state can
// potentially change without the input view being re-created.
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 054c503d8..aeb9e67b2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -26,6 +26,7 @@ import android.graphics.Paint.Align;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
@@ -196,13 +197,14 @@ public class KeyboardView extends View {
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- if (mKeyboard != null) {
- // The main keyboard expands to the display width.
- final int height = mKeyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
- setMeasuredDimension(widthMeasureSpec, height);
- } else {
+ if (mKeyboard == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
}
+ // The main keyboard expands to the entire this {@link KeyboardView}.
+ final int width = mKeyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
+ final int height = mKeyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
+ setMeasuredDimension(width, height);
}
@Override
@@ -264,9 +266,9 @@ public class KeyboardView extends View {
mClipRegion.setEmpty();
for (final Key key : mInvalidatedKeys) {
if (mKeyboard.hasKey(key)) {
- final int x = key.mX + getPaddingLeft();
- final int y = key.mY + getPaddingTop();
- mWorkingRect.set(x, y, x + key.mWidth, y + key.mHeight);
+ final int x = key.getX() + getPaddingLeft();
+ final int y = key.getY() + getPaddingTop();
+ mWorkingRect.set(x, y, x + key.getWidth(), y + key.getHeight());
mClipRegion.union(mWorkingRect);
}
}
@@ -284,7 +286,7 @@ public class KeyboardView extends View {
// TODO: Confirm if it's really required to draw all keys when hardware acceleration is on.
if (drawAllKeys || isHardwareAccelerated) {
// Draw all keys.
- for (final Key key : mKeyboard.mKeys) {
+ for (final Key key : mKeyboard.getKeys()) {
onDrawKey(key, canvas, paint);
}
} else {
@@ -309,11 +311,11 @@ public class KeyboardView extends View {
private void onDrawKey(final Key key, final Canvas canvas, final Paint paint) {
final int keyDrawX = key.getDrawX() + getPaddingLeft();
- final int keyDrawY = key.mY + getPaddingTop();
+ final int keyDrawY = key.getY() + getPaddingTop();
canvas.translate(keyDrawX, keyDrawY);
final int keyHeight = mKeyboard.mMostCommonKeyHeight - mKeyboard.mVerticalGap;
- final KeyVisualAttributes attr = key.mKeyVisualAttributes;
+ final KeyVisualAttributes attr = key.getVisualAttributes();
final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(keyHeight, attr);
params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
@@ -329,7 +331,7 @@ public class KeyboardView extends View {
protected void onDrawKeyBackground(final Key key, final Canvas canvas) {
final Rect padding = mKeyBackgroundPadding;
final int bgWidth = key.getDrawWidth() + padding.left + padding.right;
- final int bgHeight = key.mHeight + padding.top + padding.bottom;
+ final int bgHeight = key.getHeight() + padding.top + padding.bottom;
final int bgX = -padding.left;
final int bgY = -padding.top;
final int[] drawableState = key.getCurrentDrawableState();
@@ -351,7 +353,7 @@ public class KeyboardView extends View {
protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
final KeyDrawParams params) {
final int keyWidth = key.getDrawWidth();
- final int keyHeight = key.mHeight;
+ final int keyHeight = key.getHeight();
final float centerX = keyWidth * 0.5f;
final float centerY = keyHeight * 0.5f;
@@ -362,8 +364,8 @@ public class KeyboardView extends View {
// Draw key label.
final Drawable icon = key.getIcon(mKeyboard.mIconsSet, params.mAnimAlpha);
float positionX = centerX;
- if (key.mLabel != null) {
- final String label = key.mLabel;
+ final String label = key.getLabel();
+ if (label != null) {
paint.setTypeface(key.selectTypeface(params));
paint.setTextSize(key.selectTextSize(params));
final float labelCharHeight = TypefaceUtils.getCharHeight(
@@ -440,10 +442,12 @@ public class KeyboardView extends View {
}
// Draw hint label.
- if (key.mHintLabel != null) {
- final String hintLabel = key.mHintLabel;
+ final String hintLabel = key.getHintLabel();
+ if (hintLabel != null) {
paint.setTextSize(key.selectHintTextSize(params));
paint.setColor(key.selectHintTextColor(params));
+ // TODO: Should add a way to specify type face for hint letters
+ paint.setTypeface(Typeface.DEFAULT_BOLD);
blendAlpha(paint, params.mAnimAlpha);
final float hintX, hintY;
if (key.hasHintLabel()) {
@@ -464,9 +468,13 @@ public class KeyboardView extends View {
paint.setTextAlign(Align.CENTER);
} else { // key.hasHintLetter()
// The hint letter is placed at top-right corner of the key. Used mainly on phone.
+ final float keyNumericHintLabelReferenceCharWidth =
+ TypefaceUtils.getCharWidth(KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR, paint);
+ final float keyHintLabelStringWidth =
+ TypefaceUtils.getStringWidth(hintLabel, paint);
hintX = keyWidth - mKeyHintLetterPadding
- - TypefaceUtils.getCharWidth(KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR, paint)
- / 2.0f;
+ - Math.max(keyNumericHintLabelReferenceCharWidth, keyHintLabelStringWidth)
+ / 2.0f;
hintY = -paint.ascent();
paint.setTextAlign(Align.CENTER);
}
@@ -480,7 +488,7 @@ public class KeyboardView extends View {
}
// Draw key icon.
- if (key.mLabel == null && icon != null) {
+ if (label == null && icon != null) {
final int iconWidth = Math.min(icon.getIntrinsicWidth(), keyWidth);
final int iconHeight = icon.getIntrinsicHeight();
final int iconX, alignX;
@@ -504,7 +512,7 @@ public class KeyboardView extends View {
}
}
- if (key.hasPopupHint() && key.mMoreKeys != null) {
+ if (key.hasPopupHint() && key.getMoreKeys() != null) {
drawKeyPopupHint(key, canvas, paint, params);
}
}
@@ -513,7 +521,7 @@ public class KeyboardView extends View {
protected void drawKeyPopupHint(final Key key, final Canvas canvas, final Paint paint,
final KeyDrawParams params) {
final int keyWidth = key.getDrawWidth();
- final int keyHeight = key.mHeight;
+ final int keyHeight = key.getHeight();
paint.setTypeface(params.mTypeface);
paint.setTextSize(params.mHintLetterSize);
@@ -601,9 +609,9 @@ public class KeyboardView extends View {
if (mInvalidateAllKeys) return;
if (key == null) return;
mInvalidatedKeys.add(key);
- final int x = key.mX + getPaddingLeft();
- final int y = key.mY + getPaddingTop();
- invalidate(x, y, x + key.mWidth, y + key.mHeight);
+ final int x = key.getX() + getPaddingLeft();
+ final int y = key.getY() + getPaddingTop();
+ invalidate(x, y, x + key.getWidth(), y + key.getHeight());
}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 526c2f1ec..13db47004 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -155,7 +155,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final SlidingKeyInputPreview mSlidingKeyInputPreview;
// Key preview
- private static final int PREVIEW_ALPHA = 240;
private final int mKeyPreviewLayoutId;
private final int mKeyPreviewOffset;
private final int mKeyPreviewHeight;
@@ -183,6 +182,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final NonDistinctMultitouchHelper mNonDistinctMultitouchHelper;
private final KeyTimerHandler mKeyTimerHandler;
+ private final int mLanguageOnSpacebarHorizontalMargin;
private static final class KeyTimerHandler extends StaticInnerHandlerWrapper<MainKeyboardView>
implements TimerProxy {
@@ -217,7 +217,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
startWhileTypingFadeinAnimation(keyboardView);
break;
case MSG_REPEAT_KEY:
- tracker.onKeyRepeat(msg.arg1);
+ tracker.onKeyRepeat(msg.arg1 /* code */, msg.arg2 /* repeatCount */);
break;
case MSG_LONGPRESS_KEY:
keyboardView.onLongPress(tracker);
@@ -230,12 +230,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
@Override
- public void startKeyRepeatTimer(final PointerTracker tracker, final int delay) {
+ public void startKeyRepeatTimer(final PointerTracker tracker, final int repeatCount,
+ final int delay) {
final Key key = tracker.getKey();
if (key == null || delay == 0) {
return;
}
- sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay);
+ sendMessageDelayed(
+ obtainMessage(MSG_REPEAT_KEY, key.getCode(), repeatCount, tracker), delay);
}
public void cancelKeyRepeatTimer() {
@@ -296,7 +298,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
final MainKeyboardView keyboardView = getOuterInstance();
// When user hits the space or the enter key, just cancel the while-typing timer.
- final int typedCode = typedKey.mCode;
+ final int typedCode = typedKey.getCode();
if (typedCode == Constants.CODE_SPACE || typedCode == Constants.CODE_ENTER) {
if (isTyping) {
startWhileTypingFadeinAnimation(keyboardView);
@@ -510,6 +512,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
altCodeKeyWhileTypingFadeinAnimatorResId, this);
mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
+
+ mLanguageOnSpacebarHorizontalMargin =
+ (int) getResources().getDimension(R.dimen.language_on_spacebar_horizontal_margin);
}
@Override
@@ -636,7 +641,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mKeyPreviewLingerTimeout = delay;
}
-
private void locatePreviewPlacerView() {
if (mPreviewPlacerView.getParent() != null) {
return;
@@ -805,13 +809,12 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
// The key preview is placed vertically above the top edge of the parent key with an
// arbitrary offset.
- final int previewY = key.mY - previewHeight + mKeyPreviewOffset
+ final int previewY = key.getY() - previewHeight + mKeyPreviewOffset
+ CoordinateUtils.y(mOriginCoords);
if (background != null) {
- final int hasMoreKeys = (key.mMoreKeys != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
+ final int hasMoreKeys = (key.getMoreKeys() != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]);
- background.setAlpha(PREVIEW_ALPHA);
}
ViewLayoutUtils.placeViewAt(
previewText, previewX, previewY, previewWidth, previewHeight);
@@ -901,7 +904,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) {
- if (key.mMoreKeys == null) {
+ if (key.getMoreKeys() == null) {
return null;
}
Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key);
@@ -936,15 +939,15 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
final KeyboardActionListener listener = mKeyboardActionListener;
if (key.hasNoPanelAutoMoreKey()) {
- final int moreKeyCode = key.mMoreKeys[0].mCode;
+ final int moreKeyCode = key.getMoreKeys()[0].mCode;
tracker.onLongPressed();
- listener.onPressKey(moreKeyCode, false /* isRepeatKey */, true /* isSinglePointer */);
+ listener.onPressKey(moreKeyCode, 0 /* repeatCount */, true /* isSinglePointer */);
listener.onCodeInput(moreKeyCode,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
listener.onReleaseKey(moreKeyCode, false /* withSliding */);
return;
}
- final int code = key.mCode;
+ final int code = key.getCode();
if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) {
// Long pressing the space key invokes IME switcher dialog.
if (listener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) {
@@ -970,13 +973,13 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// keys keyboard is placed at the touch point of the parent key.
final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled)
? CoordinateUtils.x(lastCoords)
- : key.mX + key.mWidth / 2;
+ : key.getX() + key.getWidth() / 2;
// The more keys keyboard is usually vertically aligned with the top edge of the parent key
// (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
// aligned with the bottom edge of the visible part of the key preview.
// {@code mPreviewVisibleOffset} has been set appropriately in
// {@link KeyboardView#showKeyPreview(PointerTracker)}.
- final int pointY = key.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
+ final int pointY = key.getY() + mKeyPreviewDrawParams.mPreviewVisibleOffset;
moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
tracker.onShowMoreKeysPanel(moreKeysPanel);
}
@@ -1172,13 +1175,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
if (key.altCodeWhileTyping() && key.isEnabled()) {
params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha;
}
- if (key.mCode == Constants.CODE_SPACE) {
+ final int code = key.getCode();
+ if (code == Constants.CODE_SPACE) {
drawSpacebar(key, canvas, paint);
// Whether space key needs to show the "..." popup hint for special purposes
if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) {
drawKeyPopupHint(key, canvas, paint, params);
}
- } else if (key.mCode == Constants.CODE_LANGUAGE_SWITCH) {
+ } else if (code == Constants.CODE_LANGUAGE_SWITCH) {
super.onDrawKeyTopVisuals(key, canvas, paint, params);
drawKeyPopupHint(key, canvas, paint, params);
} else {
@@ -1186,26 +1190,27 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
}
- private static boolean fitsTextIntoWidth(final int width, final String text,
- final Paint paint) {
+ private boolean fitsTextIntoWidth(final int width, final String text, final Paint paint) {
+ final int maxTextWidth = width - mLanguageOnSpacebarHorizontalMargin * 2;
paint.setTextScaleX(1.0f);
final float textWidth = TypefaceUtils.getLabelWidth(text, paint);
if (textWidth < width) {
return true;
}
- final float scaleX = width / textWidth;
+ final float scaleX = maxTextWidth / textWidth;
if (scaleX < MINIMUM_XSCALE_OF_LANGUAGE_NAME) {
return false;
}
paint.setTextScaleX(scaleX);
- return TypefaceUtils.getLabelWidth(text, paint) < width;
+ return TypefaceUtils.getLabelWidth(text, paint) < maxTextWidth;
}
// Layout language name on spacebar.
- private static String layoutLanguageOnSpacebar(final Paint paint,
+ private String layoutLanguageOnSpacebar(final Paint paint,
final InputMethodSubtype subtype, final int width) {
+
// Choose appropriate language name to fit into the width.
final String fullText = SubtypeLocaleUtils.getFullDisplayName(subtype);
if (fitsTextIntoWidth(width, fullText, paint)) {
@@ -1226,8 +1231,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
private void drawSpacebar(final Key key, final Canvas canvas, final Paint paint) {
- final int width = key.mWidth;
- final int height = key.mHeight;
+ final int width = key.getWidth();
+ final int height = key.getHeight();
// If input language are explicitly selected.
if (mNeedsToDisplayLanguage) {
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
index a2001cb8f..6b76e2461 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
@@ -39,7 +39,7 @@ public final class MoreKeysDetector extends KeyDetector {
Key nearestKey = null;
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
- for (final Key key : getKeyboard().mKeys) {
+ for (final Key key : getKeyboard().getKeys()) {
final int dist = key.squaredDistanceToEdge(touchX, touchY);
if (dist < nearestDist) {
nearestKey = key;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 3fd29dcfd..8256d4623 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -276,6 +276,7 @@ public final class MoreKeysKeyboard extends Keyboard {
mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2;
mParentKey = parentKey;
+ final MoreKeySpec[] moreKeys = parentKey.getMoreKeys();
final int width, height;
// {@link KeyPreviewDrawParams#mPreviewVisibleWidth} should have been set at
// {@link MainKeyboardView#showKeyPreview(PointerTracker}, though there may be
@@ -283,7 +284,7 @@ public final class MoreKeysKeyboard extends Keyboard {
// zero-division error at
// {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}.
final boolean singleMoreKeyWithPreview = parentKeyboardView.isKeyPreviewPopupEnabled()
- && !parentKey.noKeyPreview() && parentKey.mMoreKeys.length == 1
+ && !parentKey.noKeyPreview() && moreKeys.length == 1
&& keyPreviewDrawParams.mPreviewVisibleWidth > 0;
if (singleMoreKeyWithPreview) {
// Use pre-computed width and height if this more keys keyboard has only one key to
@@ -312,8 +313,8 @@ public final class MoreKeysKeyboard extends Keyboard {
mDivider = null;
dividerWidth = 0;
}
- mParams.setParameters(parentKey.mMoreKeys.length, parentKey.getMoreKeysColumn(),
- width, height, parentKey.mX + parentKey.mWidth / 2,
+ mParams.setParameters(moreKeys.length, parentKey.getMoreKeysColumn(),
+ width, height, parentKey.getX() + parentKey.getWidth() / 2,
parentKeyboard.mId.mWidth, parentKey.isFixedColumnOrderMoreKeys(),
dividerWidth);
}
@@ -321,7 +322,7 @@ public final class MoreKeysKeyboard extends Keyboard {
private static int getMaxKeyWidth(final Key parentKey, final int minKeyWidth,
final float padding, final Paint paint) {
int maxWidth = minKeyWidth;
- for (final MoreKeySpec spec : parentKey.mMoreKeys) {
+ for (final MoreKeySpec spec : parentKey.getMoreKeys()) {
final String label = spec.mLabel;
// If the label is single letter, minKeyWidth is enough to hold the label.
if (label != null && StringUtils.codePointCount(label) > 1) {
@@ -336,7 +337,7 @@ public final class MoreKeysKeyboard extends Keyboard {
public MoreKeysKeyboard build() {
final MoreKeysKeyboardParams params = mParams;
final int moreKeyFlags = mParentKey.getMoreKeyLabelFlags();
- final MoreKeySpec[] moreKeys = mParentKey.mMoreKeys;
+ final MoreKeySpec[] moreKeys = mParentKey.getMoreKeys();
for (int n = 0; n < moreKeys.length; n++) {
final MoreKeySpec moreKeySpec = moreKeys[n];
final int row = n / params.mNumColumns;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index f00f5a99e..973128d36 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -127,7 +127,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
public void onUpEvent(final int x, final int y, final int pointerId, final long eventTime) {
if (mCurrentKey != null && mActivePointerId == pointerId) {
updateReleaseKeyGraphics(mCurrentKey);
- onCodeInput(mCurrentKey.mCode, x, y);
+ onCodeInput(mCurrentKey.getCode(), x, y);
mCurrentKey = null;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index b66ee2a65..d4d0d8718 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -64,7 +64,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
/**
* Get KeyboardActionListener object that is used to register key code and so on.
- * @return the KeyboardActionListner for this PointerTracker
+ * @return the KeyboardActionListner for this PointerTracke
*/
public KeyboardActionListener getKeyboardActionListener();
@@ -94,7 +94,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public interface TimerProxy {
public void startTypingStateTimer(Key typedKey);
public boolean isTypingState();
- public void startKeyRepeatTimer(PointerTracker tracker, int delay);
+ public void startKeyRepeatTimer(PointerTracker tracker, int repeatCount, int delay);
public void startLongPressTimer(PointerTracker tracker, int delay);
public void cancelLongPressTimer();
public void startDoubleTapShiftKeyTimer();
@@ -111,7 +111,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
@Override
public boolean isTypingState() { return false; }
@Override
- public void startKeyRepeatTimer(PointerTracker tracker, int delay) {}
+ public void startKeyRepeatTimer(PointerTracker tracker, int repeatCount, int delay) {}
@Override
public void startLongPressTimer(PointerTracker tracker, int delay) {}
@Override
@@ -490,7 +490,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// Returns true if keyboard has been changed by this callback.
private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key,
- final boolean isRepeatKey) {
+ final int repeatCount) {
// While gesture input is going on, this method should be a no-operation. But when gesture
// input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code>
// are set to false. To keep this method is a no-operation,
@@ -504,13 +504,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
KeyDetector.printableCode(key),
ignoreModifierKey ? " ignoreModifier" : "",
key.isEnabled() ? "" : " disabled",
- isRepeatKey ? " repeat" : ""));
+ repeatCount > 0 ? " repeatCount=" + repeatCount : ""));
}
if (ignoreModifierKey) {
return false;
}
if (key.isEnabled()) {
- mListener.onPressKey(key.mCode, isRepeatKey, getActivePointerTrackerCount() == 1);
+ mListener.onPressKey(key.getCode(), repeatCount, getActivePointerTrackerCount() == 1);
final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
mKeyboardLayoutHasBeenChanged = false;
mTimerProxy.startTypingStateTimer(key);
@@ -776,7 +776,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (sInGesture || !mGestureStrokeWithPreviewPoints.isStartOfAGesture()) {
return;
}
- if (key == null || !Character.isLetter(key.mCode)) {
+ if (key == null || !Character.isLetter(key.getCode())) {
return;
}
if (DEBUG_LISTENER) {
@@ -967,7 +967,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// This onPress call may have changed keyboard layout. Those cases are detected at
// {@link #setKeyboard}. In those cases, we should update key according to the new
// keyboard layout.
- if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false /* isRepeatKey */)) {
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) {
key = onDownKey(x, y, eventTime);
}
@@ -1057,7 +1057,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// at {@link #setKeyboard}. In those cases, we should update key according
// to the new keyboard layout.
Key key = newKey;
- if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false /* isRepeatKey */)) {
+ if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) {
key = onMoveKey(x, y);
}
onMoveToNewKey(key, x, y);
@@ -1075,8 +1075,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
+ " phantom sudden move event (distance=%d) is translated to "
+ "up[%d,%d,%s]/down[%d,%d,%s] events", mPointerId,
getDistance(x, y, lastX, lastY),
- lastX, lastY, Constants.printableCode(oldKey.mCode),
- x, y, Constants.printableCode(key.mCode)));
+ lastX, lastY, Constants.printableCode(oldKey.getCode()),
+ x, y, Constants.printableCode(key.getCode())));
}
// TODO: This should be moved to outside of this nested if-clause?
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -1098,8 +1098,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
+ " bogus down-move-up event (raidus=%.2f key diagonal) is "
+ " translated to up[%d,%d,%s]/down[%d,%d,%s] events",
mPointerId, radiusRatio,
- lastX, lastY, Constants.printableCode(oldKey.mCode),
- x, y, Constants.printableCode(key.mCode)));
+ lastX, lastY, Constants.printableCode(oldKey.getCode()),
+ x, y, Constants.printableCode(key.getCode())));
}
onUpEventInternal(x, y, eventTime);
onDownEventInternal(x, y, eventTime);
@@ -1107,7 +1107,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void processSildeOutFromOldKey(final Key oldKey) {
setReleasedKeyGraphics(oldKey);
- callListenerOnRelease(oldKey, oldKey.mCode, true /* withSliding */);
+ callListenerOnRelease(oldKey, oldKey.getCode(), true /* withSliding */);
startSlidingKeyInput(oldKey);
mTimerProxy.cancelKeyTimers();
}
@@ -1263,7 +1263,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (sInGesture) {
if (currentKey != null) {
- callListenerOnRelease(currentKey, currentKey.mCode, true /* withSliding */);
+ callListenerOnRelease(currentKey, currentKey.getCode(), true /* withSliding */);
}
mayEndBatchInput(eventTime);
return;
@@ -1376,9 +1376,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// doesn't have its more keys. (e.g. spacebar, globe key)
// We always need to start the long press timer if the key has its more keys regardless of
// whether or not we are in the sliding input mode.
- if (mIsInSlidingKeyInput && key.mMoreKeys == null) return;
+ if (mIsInSlidingKeyInput && key.getMoreKeys() == null) return;
final int delay;
- switch (key.mCode) {
+ switch (key.getCode()) {
case Constants.CODE_SHIFT:
delay = sParams.mLongPressShiftLockTimeout;
break;
@@ -1401,7 +1401,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return;
}
- final int code = key.mCode;
+ final int code = key.getCode();
callListenerOnCodeInput(key, code, x, y, eventTime);
callListenerOnRelease(key, code, false /* withSliding */);
}
@@ -1412,17 +1412,19 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (!key.isRepeatable()) return;
// Don't start key repeat when we are in sliding input mode.
if (mIsInSlidingKeyInput) return;
- detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis());
- mTimerProxy.startKeyRepeatTimer(this, sParams.mKeyRepeatStartTimeout);
+ detectAndSendKey(key, key.getX(), key.getY(), SystemClock.uptimeMillis());
+ final int startRepeatCount = 1;
+ mTimerProxy.startKeyRepeatTimer(this, startRepeatCount, sParams.mKeyRepeatStartTimeout);
}
- public void onKeyRepeat(final int code) {
+ public void onKeyRepeat(final int code, final int repeatCount) {
final Key key = getKey();
- if (key == null || key.mCode != code) {
+ if (key == null || key.getCode() != code) {
return;
}
- mTimerProxy.startKeyRepeatTimer(this, sParams.mKeyRepeatInterval);
- callListenerOnPressAndCheckKeyboardLayoutChange(key, true /* isRepeatKey */);
+ final int nextRepeatCount = repeatCount + 1;
+ mTimerProxy.startKeyRepeatTimer(this, nextRepeatCount, sParams.mKeyRepeatInterval);
+ callListenerOnPressAndCheckKeyboardLayoutChange(key, repeatCount);
callListenerOnCodeInput(key, code, mKeyX, mKeyY, SystemClock.uptimeMillis());
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 9b0a33cec..a0316696c 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -96,7 +96,7 @@ public class ProximityInfo {
private static boolean needsProximityInfo(final Key key) {
// Don't include special keys into ProximityInfo.
- return key.mCode >= Constants.CODE_SPACE;
+ return key.getCode() >= Constants.CODE_SPACE;
}
private static int getProximityInfoKeysCount(final Key[] keys) {
@@ -122,7 +122,7 @@ public class ProximityInfo {
if (!needsProximityInfo(neighborKey)) {
continue;
}
- proximityCharsArray[infoIndex] = neighborKey.mCode;
+ proximityCharsArray[infoIndex] = neighborKey.getCode();
infoIndex++;
}
}
@@ -159,11 +159,11 @@ public class ProximityInfo {
if (!needsProximityInfo(key)) {
continue;
}
- keyXCoordinates[infoIndex] = key.mX;
- keyYCoordinates[infoIndex] = key.mY;
- keyWidths[infoIndex] = key.mWidth;
- keyHeights[infoIndex] = key.mHeight;
- keyCharCodes[infoIndex] = key.mCode;
+ keyXCoordinates[infoIndex] = key.getX();
+ keyYCoordinates[infoIndex] = key.getY();
+ keyWidths[infoIndex] = key.getWidth();
+ keyHeights[infoIndex] = key.getHeight();
+ keyCharCodes[infoIndex] = key.getCode();
infoIndex++;
}
@@ -183,7 +183,7 @@ public class ProximityInfo {
if (!needsProximityInfo(key)) {
continue;
}
- final Rect hitBox = key.mHitBox;
+ final Rect hitBox = key.getHitBox();
sweetSpotCenterXs[infoIndex] = hitBox.exactCenterX();
sweetSpotCenterYs[infoIndex] = hitBox.exactCenterY();
sweetSpotRadii[infoIndex] = defaultRadius;
@@ -204,7 +204,7 @@ public class ProximityInfo {
" [%2d] row=%d x/y/r=%7.2f/%7.2f/%5.2f %s code=%s", infoIndex, row,
sweetSpotCenterXs[infoIndex], sweetSpotCenterYs[infoIndex],
sweetSpotRadii[infoIndex], (row < rows ? "correct" : "default"),
- Constants.printableCode(key.mCode)));
+ Constants.printableCode(key.getCode())));
}
infoIndex++;
}
@@ -245,8 +245,8 @@ public class ProximityInfo {
final int threshold = (int) (defaultWidth * SEARCH_DISTANCE);
final int thresholdSquared = threshold * threshold;
// Round-up so we don't have any pixels outside the grid
- final int fullGridWidth = mGridWidth * mCellWidth;
- final int fullGridHeight = mGridHeight * mCellHeight;
+ final int lastPixelXCoordinate = mGridWidth * mCellWidth - 1;
+ final int lastPixelYCoordinate = mGridHeight * mCellHeight - 1;
// For large layouts, 'neighborsFlatBuffer' is about 80k of memory: gridSize is usually 512,
// keycount is about 40 and a pointer to a Key is 4 bytes. This contains, for each cell,
@@ -322,19 +322,21 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
have to align this on the center of the key. Hence, we don't need a separate value for
bottomPixelWithinThreshold and call this yEnd right away.
*/
- final int topPixelWithinThreshold = key.mY - threshold;
+ final int keyX = key.getX();
+ final int keyY = key.getY();
+ final int topPixelWithinThreshold = keyY - threshold;
final int yDeltaToGrid = topPixelWithinThreshold % mCellHeight;
final int yMiddleOfTopCell = topPixelWithinThreshold - yDeltaToGrid + halfCellHeight;
final int yStart = Math.max(halfCellHeight,
yMiddleOfTopCell + (yDeltaToGrid <= halfCellHeight ? 0 : mCellHeight));
- final int yEnd = Math.min(fullGridHeight, key.mY + key.mHeight + threshold);
+ final int yEnd = Math.min(lastPixelYCoordinate, keyY + key.getHeight() + threshold);
- final int leftPixelWithinThreshold = key.mX - threshold;
+ final int leftPixelWithinThreshold = keyX - threshold;
final int xDeltaToGrid = leftPixelWithinThreshold % mCellWidth;
final int xMiddleOfLeftCell = leftPixelWithinThreshold - xDeltaToGrid + halfCellWidth;
final int xStart = Math.max(halfCellWidth,
xMiddleOfLeftCell + (xDeltaToGrid <= halfCellWidth ? 0 : mCellWidth));
- final int xEnd = Math.min(fullGridWidth, key.mX + key.mWidth + threshold);
+ final int xEnd = Math.min(lastPixelXCoordinate, keyX + key.getWidth() + threshold);
int baseIndexOfCurrentRow = (yStart / mCellHeight) * mGridWidth + (xStart / mCellWidth);
for (int centerY = yStart; centerY <= yEnd; centerY += mCellHeight) {
@@ -372,7 +374,7 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
if (index >= destLength) {
break;
}
- final int code = key.mCode;
+ final int code = key.getCode();
if (code <= Constants.CODE_SPACE) {
break;
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/CodesArrayParser.java b/java/src/com/android/inputmethod/keyboard/internal/CodesArrayParser.java
new file mode 100644
index 000000000..c10fdbace
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/CodesArrayParser.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * The string parser of codesArray specification for <GridRows />. The attribute codesArray is an
+ * array of string.
+ * Each element of the array defines a key label by specifying a code point as a hexadecimal string.
+ * A key label may consist of multiple code points separated by comma.
+ * Each element of the array optionally can have an output text definition after vertical bar
+ * marker. An output text may consist of multiple code points separated by comma.
+ * The format of the codesArray element should be:
+ * <pre>
+ * codePointInHex[,codePoint2InHex]*(|outputTextCodePointInHex[,outputTextCodePoint2InHex]*)?
+ * </pre>
+ */
+// TODO: Write unit tests for this class.
+public final class CodesArrayParser {
+ // Constants for parsing.
+ private static final char COMMA = ',';
+ private static final char VERTICAL_BAR = '|';
+ private static final String COMMA_STRING = ",";
+ private static final int BASE_HEX = 16;
+
+ private CodesArrayParser() {
+ // This utility class is not publicly instantiable.
+ }
+
+ private static String getLabelSpec(final String codesArraySpec) {
+ final int pos = codesArraySpec.indexOf(VERTICAL_BAR);
+ return (pos < 0) ? codesArraySpec : codesArraySpec.substring(0, pos);
+ }
+
+ public static String parseLabel(final String codesArraySpec) {
+ final String labelSpec = getLabelSpec(codesArraySpec);
+ final StringBuilder sb = new StringBuilder();
+ for (final String codeInHex : labelSpec.split(COMMA_STRING)) {
+ final int codePoint = Integer.parseInt(codeInHex, BASE_HEX);
+ sb.appendCodePoint(codePoint);
+ }
+ return sb.toString();
+ }
+
+ private static String getCodeSpec(final String codesArraySpec) {
+ final int pos = codesArraySpec.indexOf(VERTICAL_BAR);
+ return (pos < 0) ? codesArraySpec : codesArraySpec.substring(pos + 1);
+ }
+
+ public static int parseCode(final String codesArraySpec) {
+ final String codeSpec = getCodeSpec(codesArraySpec);
+ if (codeSpec.indexOf(COMMA) < 0) {
+ return Integer.parseInt(codeSpec, BASE_HEX);
+ }
+ return Constants.CODE_OUTPUT_TEXT;
+ }
+
+ public static String parseOutputText(final String codesArraySpec) {
+ final String codeSpec = getCodeSpec(codesArraySpec);
+ if (codeSpec.indexOf(COMMA) < 0) {
+ return null;
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (final String codeInHex : codeSpec.split(COMMA_STRING)) {
+ final int codePoint = Integer.parseInt(codeInHex, BASE_HEX);
+ sb.appendCodePoint(codePoint);
+ }
+ return sb.toString();
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
new file mode 100644
index 000000000..0dd71e2ec
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import android.content.SharedPreferences;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.inputmethod.keyboard.EmojiKeyboardView;
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * This is a Keyboard class where you can add keys dynamically shown in a grid layout
+ */
+public class DynamicGridKeyboard extends Keyboard {
+ private static final String TAG = DynamicGridKeyboard.class.getSimpleName();
+ private static final int TEMPLATE_KEY_CODE_0 = 0x30;
+ private static final int TEMPLATE_KEY_CODE_1 = 0x31;
+
+ private final SharedPreferences mPrefs;
+ private final int mLeftPadding;
+ private final int mHorizontalStep;
+ private final int mVerticalStep;
+ private final int mColumnsNum;
+ private final int mMaxKeyCount;
+ private final boolean mIsRecents;
+ private final ArrayDeque<GridKey> mGridKeys = CollectionUtils.newArrayDeque();
+
+ private Key[] mCachedGridKeys;
+
+ public DynamicGridKeyboard(final SharedPreferences prefs, final Keyboard templateKeyboard,
+ final int maxKeyCount, final int categoryId, final int categoryPageId) {
+ super(templateKeyboard);
+ final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0);
+ final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1);
+ mLeftPadding = key0.getX();
+ mHorizontalStep = Math.abs(key1.getX() - key0.getX());
+ mVerticalStep = key0.getHeight() + mVerticalGap;
+ mColumnsNum = mBaseWidth / mHorizontalStep;
+ mMaxKeyCount = maxKeyCount;
+ mIsRecents = categoryId == EmojiKeyboardView.CATEGORY_ID_RECENTS;
+ mPrefs = prefs;
+ }
+
+ private Key getTemplateKey(final int code) {
+ for (final Key key : super.getKeys()) {
+ if (key.getCode() == code) {
+ return key;
+ }
+ }
+ throw new RuntimeException("Can't find template key: code=" + code);
+ }
+
+ public void addKeyFirst(final Key usedKey) {
+ addKey(usedKey, true);
+ if (mIsRecents) {
+ saveRecentKeys();
+ }
+ }
+
+ public void addKeyLast(final Key usedKey) {
+ addKey(usedKey, false);
+ }
+
+ private void addKey(final Key usedKey, final boolean addFirst) {
+ if (usedKey == null) {
+ return;
+ }
+ synchronized (mGridKeys) {
+ mCachedGridKeys = null;
+ final GridKey key = new GridKey(usedKey);
+ while (mGridKeys.remove(key)) {
+ // Remove duplicate keys.
+ }
+ if (addFirst) {
+ mGridKeys.addFirst(key);
+ } else {
+ mGridKeys.addLast(key);
+ }
+ while (mGridKeys.size() > mMaxKeyCount) {
+ mGridKeys.removeLast();
+ }
+ int index = 0;
+ for (final GridKey gridKey : mGridKeys) {
+ final int keyX = getKeyX(index);
+ final int keyY = getKeyY(index);
+ gridKey.updateCorrdinates(keyX, keyY);
+ index++;
+ }
+ }
+ }
+
+ private void saveRecentKeys() {
+ final ArrayList<Object> keys = CollectionUtils.newArrayList();
+ for (final Key key : mGridKeys) {
+ if (key.getOutputText() != null) {
+ keys.add(key.getOutputText());
+ } else {
+ keys.add(key.getCode());
+ }
+ }
+ final String jsonStr = StringUtils.listToJsonStr(keys);
+ Settings.writeEmojiRecentKeys(mPrefs, jsonStr);
+ }
+
+ private static Key getKey(final Collection<DynamicGridKeyboard> keyboards, final Object o) {
+ for (final DynamicGridKeyboard kbd : keyboards) {
+ if (o instanceof Integer) {
+ final int code = (Integer) o;
+ final Key key = kbd.getKey(code);
+ if (key != null) {
+ return key;
+ }
+ } else if (o instanceof String) {
+ final String outputText = (String) o;
+ final Key key = kbd.getKeyFromOutputText(outputText);
+ if (key != null) {
+ return key;
+ }
+ } else {
+ Log.w(TAG, "Invalid object: " + o);
+ }
+ }
+ return null;
+ }
+
+ public void loadRecentKeys(Collection<DynamicGridKeyboard> keyboards) {
+ final String str = Settings.readEmojiRecentKeys(mPrefs);
+ final List<Object> keys = StringUtils.jsonStrToList(str);
+ for (final Object o : keys) {
+ addKeyLast(getKey(keyboards, o));
+ }
+ }
+
+ private int getKeyX(final int index) {
+ final int column = index % mColumnsNum;
+ return column * mHorizontalStep + mLeftPadding;
+ }
+
+ private int getKeyY(final int index) {
+ final int row = index / mColumnsNum;
+ return row * mVerticalStep + mTopPadding;
+ }
+
+ @Override
+ public Key[] getKeys() {
+ synchronized (mGridKeys) {
+ if (mCachedGridKeys != null) {
+ return mCachedGridKeys;
+ }
+ mCachedGridKeys = mGridKeys.toArray(new Key[mGridKeys.size()]);
+ return mCachedGridKeys;
+ }
+ }
+
+ @Override
+ public Key[] getNearestKeys(final int x, final int y) {
+ // TODO: Calculate the nearest key index in mGridKeys from x and y.
+ return getKeys();
+ }
+
+ static final class GridKey extends Key {
+ private int mCurrentX;
+ private int mCurrentY;
+
+ public GridKey(final Key originalKey) {
+ super(originalKey);
+ }
+
+ public void updateCorrdinates(final int x, final int y) {
+ mCurrentX = x;
+ mCurrentY = y;
+ getHitBox().set(x, y, x + getWidth(), y + getHeight());
+ }
+
+ @Override
+ public int getX() {
+ return mCurrentX;
+ }
+
+ @Override
+ public int getY() {
+ return mCurrentY;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof Key)) return false;
+ final Key key = (Key)o;
+ if (getCode() != key.getCode()) return false;
+ if (!TextUtils.equals(getLabel(), key.getLabel())) return false;
+ return TextUtils.equals(getOutputText(), key.getOutputText());
+ }
+
+ @Override
+ public String toString() {
+ return "GridKey: " + super.toString();
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java
index f65056948..e6a674334 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java
@@ -24,7 +24,7 @@ public abstract class KeyStyle {
public abstract String[] getStringArray(TypedArray a, int index);
public abstract String getString(TypedArray a, int index);
public abstract int getInt(TypedArray a, int index, int defaultValue);
- public abstract int getFlag(TypedArray a, int index);
+ public abstract int getFlags(TypedArray a, int index);
protected KeyStyle(final KeyboardTextsSet textsSet) {
mTextsSet = textsSet;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
index 6aab3e7b3..05d855e31 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
@@ -66,7 +66,7 @@ public final class KeyStylesSet {
}
@Override
- public int getFlag(final TypedArray a, final int index) {
+ public int getFlags(final TypedArray a, final int index) {
return a.getInt(index, 0);
}
}
@@ -123,14 +123,12 @@ public final class KeyStylesSet {
}
@Override
- public int getFlag(final TypedArray a, final int index) {
- int flags = a.getInt(index, 0);
- final Object value = mStyleAttributes.get(index);
- if (value != null) {
- flags |= (Integer)value;
- }
- final KeyStyle parentStyle = mStyles.get(mParentStyleName);
- return flags | parentStyle.getFlag(a, index);
+ public int getFlags(final TypedArray a, final int index) {
+ final int parentFlags = mStyles.get(mParentStyleName).getFlags(a, index);
+ final Integer value = (Integer)mStyleAttributes.get(index);
+ final int styleFlags = (value != null) ? value : 0;
+ final int flags = a.getInt(index, 0);
+ return flags | styleFlags | parentFlags;
}
public void readKeyAttributes(final TypedArray keyAttr) {
@@ -142,13 +140,13 @@ public final class KeyStylesSet {
readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
- readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
+ readFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
readString(keyAttr, R.styleable.Keyboard_Key_keyIcon);
readString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
readString(keyAttr, R.styleable.Keyboard_Key_keyIconPreview);
readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
- readFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
+ readFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
}
private void readString(final TypedArray a, final int index) {
@@ -163,10 +161,11 @@ public final class KeyStylesSet {
}
}
- private void readFlag(final TypedArray a, final int index) {
+ private void readFlags(final TypedArray a, final int index) {
if (a.hasValue(index)) {
final Integer value = (Integer)mStyleAttributes.get(index);
- mStyleAttributes.put(index, a.getInt(index, 0) | (value != null ? value : 0));
+ final int styleFlags = value != null ? value : 0;
+ mStyleAttributes.put(index, a.getInt(index, 0) | styleFlags);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index b34d7c45f..22f7a83fc 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -29,6 +29,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.RunInLocale;
@@ -113,6 +114,7 @@ import java.util.Locale;
* </pre>
*/
+// TODO: Write unit tests for this class.
public class KeyboardBuilder<KP extends KeyboardParams> {
private static final String BUILDER_TAG = "Keyboard.Builder";
private static final boolean DEBUG = false;
@@ -120,6 +122,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
// Keyboard XML Tags
private static final String TAG_KEYBOARD = "Keyboard";
private static final String TAG_ROW = "Row";
+ private static final String TAG_GRID_ROWS = "GridRows";
private static final String TAG_KEY = "Key";
private static final String TAG_SPACER = "Spacer";
private static final String TAG_INCLUDE = "include";
@@ -218,20 +221,18 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
parseKeyboardAttributes(parser);
startKeyboard();
parseKeyboardContent(parser, false);
- break;
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD);
+ return;
}
+ throw new XmlParseUtils.IllegalStartTag(parser, tag, TAG_KEYBOARD);
}
}
}
private void parseKeyboardAttributes(final XmlPullParser parser) {
+ final AttributeSet attr = Xml.asAttributeSet(parser);
final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
- Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
- R.style.Keyboard);
- final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
+ attr, R.styleable.Keyboard, R.attr.keyboardStyle, R.style.Keyboard);
+ final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
try {
final KeyboardParams params = mParams;
final int height = params.mId.mHeight;
@@ -314,6 +315,9 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
startRow(row);
}
parseRowContent(parser, row, skip);
+ } else if (TAG_GRID_ROWS.equals(tag)) {
+ if (DEBUG) startTag("<%s>%s", TAG_GRID_ROWS, skip ? " skipped" : "");
+ parseGridRows(parser, skip);
} else if (TAG_INCLUDE.equals(tag)) {
parseIncludeKeyboardContent(parser, skip);
} else if (TAG_SWITCH.equals(tag)) {
@@ -328,31 +332,30 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
if (DEBUG) endTag("</%s>", tag);
if (TAG_KEYBOARD.equals(tag)) {
endKeyboard();
- break;
- } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
- || TAG_MERGE.equals(tag)) {
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_ROW);
+ return;
+ }
+ if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag) || TAG_MERGE.equals(tag)) {
+ return;
}
+ throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_ROW);
}
}
}
private KeyboardRow parseRowAttributes(final XmlPullParser parser)
throws XmlPullParserException {
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
+ final AttributeSet attr = Xml.asAttributeSet(parser);
+ final TypedArray keyboardAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard);
try {
- if (a.hasValue(R.styleable.Keyboard_horizontalGap)) {
+ if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap)) {
throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "horizontalGap");
}
- if (a.hasValue(R.styleable.Keyboard_verticalGap)) {
+ if (keyboardAttr.hasValue(R.styleable.Keyboard_verticalGap)) {
throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "verticalGap");
}
return new KeyboardRow(mResources, mParams, parser, mCurrentY);
} finally {
- a.recycle();
+ keyboardAttr.recycle();
}
}
@@ -382,34 +385,97 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
if (!skip) {
endRow(row);
}
- break;
- } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
- || TAG_MERGE.equals(tag)) {
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_ROW);
+ return;
+ }
+ if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag) || TAG_MERGE.equals(tag)) {
+ return;
}
+ throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_ROW);
}
}
}
- private void parseKey(final XmlPullParser parser, final KeyboardRow row, final boolean skip)
+ private void parseGridRows(final XmlPullParser parser, final boolean skip)
throws XmlPullParserException, IOException {
if (skip) {
- XmlParseUtils.checkEndTag(TAG_KEY, parser);
+ XmlParseUtils.checkEndTag(TAG_GRID_ROWS, parser);
if (DEBUG) {
- startEndTag("<%s /> skipped", TAG_KEY);
+ startEndTag("<%s /> skipped", TAG_GRID_ROWS);
}
- } else {
- final Key key = new Key(mResources, mParams, row, parser);
- if (DEBUG) {
- startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY,
- (key.isEnabled() ? "" : " disabled"), key,
- Arrays.toString(key.mMoreKeys));
+ return;
+ }
+ final KeyboardRow gridRows = new KeyboardRow(mResources, mParams, parser, mCurrentY);
+ final TypedArray gridRowAttr = mResources.obtainAttributes(
+ Xml.asAttributeSet(parser), R.styleable.Keyboard_GridRows);
+ final int codesArrayId = gridRowAttr.getResourceId(
+ R.styleable.Keyboard_GridRows_codesArray, 0);
+ final int textsArrayId = gridRowAttr.getResourceId(
+ R.styleable.Keyboard_GridRows_textsArray, 0);
+ gridRowAttr.recycle();
+ if (codesArrayId == 0 && textsArrayId == 0) {
+ throw new XmlParseUtils.ParseException(
+ "Missing codesArray or textsArray attributes", parser);
+ }
+ if (codesArrayId != 0 && textsArrayId != 0) {
+ throw new XmlParseUtils.ParseException(
+ "Both codesArray and textsArray attributes specifed", parser);
+ }
+ final String[] array = mResources.getStringArray(
+ codesArrayId != 0 ? codesArrayId : textsArrayId);
+ final int counts = array.length;
+ final float keyWidth = gridRows.getKeyWidth(null, 0.0f);
+ final int numColumns = (int)(mParams.mOccupiedWidth / keyWidth);
+ for (int index = 0; index < counts; index += numColumns) {
+ final KeyboardRow row = new KeyboardRow(mResources, mParams, parser, mCurrentY);
+ startRow(row);
+ for (int c = 0; c < numColumns; c++) {
+ final int i = index + c;
+ if (i >= counts) {
+ break;
+ }
+ final String label;
+ final int code;
+ final String outputText;
+ if (codesArrayId != 0) {
+ final String codeArraySpec = array[i];
+ label = CodesArrayParser.parseLabel(codeArraySpec);
+ code = CodesArrayParser.parseCode(codeArraySpec);
+ outputText = CodesArrayParser.parseOutputText(codeArraySpec);
+ } else {
+ final String textArraySpec = array[i];
+ // TODO: Utilize KeySpecParser or write more generic TextsArrayParser.
+ label = textArraySpec;
+ code = Constants.CODE_OUTPUT_TEXT;
+ outputText = textArraySpec + (char)Constants.CODE_SPACE;
+ }
+ final int x = (int)row.getKeyX(null);
+ final int y = row.getKeyY();
+ final Key key = new Key(mParams, label, null /* hintLabel */, 0 /* iconId */,
+ code, outputText, x, y, (int)keyWidth, (int)row.getRowHeight(),
+ row.getDefaultKeyLabelFlags(), row.getDefaultBackgroundType());
+ endKey(key);
+ row.advanceXPos(keyWidth);
}
+ endRow(row);
+ }
+
+ XmlParseUtils.checkEndTag(TAG_GRID_ROWS, parser);
+ }
+
+ private void parseKey(final XmlPullParser parser, final KeyboardRow row, final boolean skip)
+ throws XmlPullParserException, IOException {
+ if (skip) {
XmlParseUtils.checkEndTag(TAG_KEY, parser);
- endKey(key);
+ if (DEBUG) startEndTag("<%s /> skipped", TAG_KEY);
+ return;
}
+ final Key key = new Key(mResources, mParams, row, parser);
+ if (DEBUG) {
+ startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY, (key.isEnabled() ? "" : " disabled"),
+ key, Arrays.toString(key.getMoreKeys()));
+ }
+ XmlParseUtils.checkEndTag(TAG_KEY, parser);
+ endKey(key);
}
private void parseSpacer(final XmlPullParser parser, final KeyboardRow row, final boolean skip)
@@ -417,12 +483,12 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
if (skip) {
XmlParseUtils.checkEndTag(TAG_SPACER, parser);
if (DEBUG) startEndTag("<%s /> skipped", TAG_SPACER);
- } else {
- final Key.Spacer spacer = new Key.Spacer(mResources, mParams, row, parser);
- if (DEBUG) startEndTag("<%s />", TAG_SPACER);
- XmlParseUtils.checkEndTag(TAG_SPACER, parser);
- endKey(spacer);
+ return;
}
+ final Key.Spacer spacer = new Key.Spacer(mResources, mParams, row, parser);
+ if (DEBUG) startEndTag("<%s />", TAG_SPACER);
+ XmlParseUtils.checkEndTag(TAG_SPACER, parser);
+ endKey(spacer);
}
private void parseIncludeKeyboardContent(final XmlPullParser parser, final boolean skip)
@@ -440,66 +506,44 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
if (skip) {
XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
if (DEBUG) startEndTag("</%s> skipped", TAG_INCLUDE);
- } else {
- final AttributeSet attr = Xml.asAttributeSet(parser);
- final TypedArray keyboardAttr = mResources.obtainAttributes(attr,
- R.styleable.Keyboard_Include);
- final TypedArray keyAttr = mResources.obtainAttributes(attr,
- R.styleable.Keyboard_Key);
- int keyboardLayout = 0;
- float savedDefaultKeyWidth = 0;
- int savedDefaultKeyLabelFlags = 0;
- int savedDefaultBackgroundType = Key.BACKGROUND_TYPE_NORMAL;
- try {
- XmlParseUtils.checkAttributeExists(keyboardAttr,
- R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout",
- TAG_INCLUDE, parser);
- keyboardLayout = keyboardAttr.getResourceId(
- R.styleable.Keyboard_Include_keyboardLayout, 0);
- if (row != null) {
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
- // Override current x coordinate.
- row.setXPos(row.getKeyX(keyAttr));
- }
- // TODO: Remove this if-clause and do the same as backgroundType below.
- savedDefaultKeyWidth = row.getDefaultKeyWidth();
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyWidth)) {
- // Override default key width.
- row.setDefaultKeyWidth(row.getKeyWidth(keyAttr));
- }
- savedDefaultKeyLabelFlags = row.getDefaultKeyLabelFlags();
- // Bitwise-or default keyLabelFlag if exists.
- row.setDefaultKeyLabelFlags(keyAttr.getInt(
- R.styleable.Keyboard_Key_keyLabelFlags, 0)
- | savedDefaultKeyLabelFlags);
- savedDefaultBackgroundType = row.getDefaultBackgroundType();
- // Override default backgroundType if exists.
- row.setDefaultBackgroundType(keyAttr.getInt(
- R.styleable.Keyboard_Key_backgroundType,
- savedDefaultBackgroundType));
- }
- } finally {
- keyboardAttr.recycle();
- keyAttr.recycle();
+ return;
+ }
+ final AttributeSet attr = Xml.asAttributeSet(parser);
+ final TypedArray keyboardAttr = mResources.obtainAttributes(
+ attr, R.styleable.Keyboard_Include);
+ final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
+ int keyboardLayout = 0;
+ try {
+ XmlParseUtils.checkAttributeExists(
+ keyboardAttr, R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout",
+ TAG_INCLUDE, parser);
+ keyboardLayout = keyboardAttr.getResourceId(
+ R.styleable.Keyboard_Include_keyboardLayout, 0);
+ if (row != null) {
+ // Override current x coordinate.
+ row.setXPos(row.getKeyX(keyAttr));
+ // Push current Row attributes and update with new attributes.
+ row.pushRowAttributes(keyAttr);
}
+ } finally {
+ keyboardAttr.recycle();
+ keyAttr.recycle();
+ }
- XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
- if (DEBUG) {
- startEndTag("<%s keyboardLayout=%s />",TAG_INCLUDE,
- mResources.getResourceEntryName(keyboardLayout));
- }
- final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout);
- try {
- parseMerge(parserForInclude, row, skip);
- } finally {
- if (row != null) {
- // Restore default keyWidth, keyLabelFlags, and backgroundType.
- row.setDefaultKeyWidth(savedDefaultKeyWidth);
- row.setDefaultKeyLabelFlags(savedDefaultKeyLabelFlags);
- row.setDefaultBackgroundType(savedDefaultBackgroundType);
- }
- parserForInclude.close();
+ XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
+ if (DEBUG) {
+ startEndTag("<%s keyboardLayout=%s />",TAG_INCLUDE,
+ mResources.getResourceEntryName(keyboardLayout));
+ }
+ final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout);
+ try {
+ parseMerge(parserForInclude, row, skip);
+ } finally {
+ if (row != null) {
+ // Restore Row attributes.
+ row.popRowAttributes();
}
+ parserForInclude.close();
}
}
@@ -516,11 +560,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
} else {
parseRowContent(parser, row, skip);
}
- break;
- } else {
- throw new XmlParseUtils.ParseException(
- "Included keyboard layout must have <merge> root element", parser);
+ return;
}
+ throw new XmlParseUtils.ParseException(
+ "Included keyboard layout must have <merge> root element", parser);
}
}
}
@@ -554,10 +597,9 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
final String tag = parser.getName();
if (TAG_SWITCH.equals(tag)) {
if (DEBUG) endTag("</%s>", TAG_SWITCH);
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_SWITCH);
+ return;
}
+ throw new XmlParseUtils.IllegalEndTag(parser, tag, TAG_SWITCH);
}
}
}
@@ -580,86 +622,92 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
if (id == null) {
return true;
}
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Case);
+ final AttributeSet attr = Xml.asAttributeSet(parser);
+ final TypedArray caseAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Case);
try {
- final boolean keyboardLayoutSetElementMatched = matchTypedValue(a,
+ final boolean keyboardLayoutSetMatched = matchString(caseAttr,
+ R.styleable.Keyboard_Case_keyboardLayoutSet,
+ SubtypeLocaleUtils.getKeyboardLayoutSetName(id.mSubtype));
+ final boolean keyboardLayoutSetElementMatched = matchTypedValue(caseAttr,
R.styleable.Keyboard_Case_keyboardLayoutSetElement, id.mElementId,
KeyboardId.elementIdToName(id.mElementId));
- final boolean modeMatched = matchTypedValue(a,
+ final boolean modeMatched = matchTypedValue(caseAttr,
R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
- final boolean navigateNextMatched = matchBoolean(a,
+ final boolean navigateNextMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_navigateNext, id.navigateNext());
- final boolean navigatePreviousMatched = matchBoolean(a,
+ final boolean navigatePreviousMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_navigatePrevious, id.navigatePrevious());
- final boolean passwordInputMatched = matchBoolean(a,
+ final boolean passwordInputMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
- final boolean clobberSettingsKeyMatched = matchBoolean(a,
+ final boolean clobberSettingsKeyMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
- final boolean shortcutKeyEnabledMatched = matchBoolean(a,
+ final boolean shortcutKeyEnabledMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
- final boolean shortcutKeyOnSymbolsMatched = matchBoolean(a,
+ final boolean shortcutKeyOnSymbolsMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_shortcutKeyOnSymbols, id.mShortcutKeyOnSymbols);
- final boolean hasShortcutKeyMatched = matchBoolean(a,
+ final boolean hasShortcutKeyMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
- final boolean languageSwitchKeyEnabledMatched = matchBoolean(a,
+ final boolean languageSwitchKeyEnabledMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
id.mLanguageSwitchKeyEnabled);
- final boolean isMultiLineMatched = matchBoolean(a,
+ final boolean isMultiLineMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
- final boolean imeActionMatched = matchInteger(a,
+ final boolean imeActionMatched = matchInteger(caseAttr,
R.styleable.Keyboard_Case_imeAction, id.imeAction());
- final boolean localeCodeMatched = matchString(a,
+ final boolean localeCodeMatched = matchString(caseAttr,
R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
- final boolean languageCodeMatched = matchString(a,
+ final boolean languageCodeMatched = matchString(caseAttr,
R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
- final boolean countryCodeMatched = matchString(a,
+ final boolean countryCodeMatched = matchString(caseAttr,
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
- final boolean selected = keyboardLayoutSetElementMatched && modeMatched
- && navigateNextMatched && navigatePreviousMatched && passwordInputMatched
- && clobberSettingsKeyMatched && shortcutKeyEnabledMatched
- && shortcutKeyOnSymbolsMatched && hasShortcutKeyMatched
- && languageSwitchKeyEnabledMatched && isMultiLineMatched && imeActionMatched
- && localeCodeMatched && languageCodeMatched && countryCodeMatched;
+ final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
+ && modeMatched && navigateNextMatched && navigatePreviousMatched
+ && passwordInputMatched && clobberSettingsKeyMatched
+ && shortcutKeyEnabledMatched && shortcutKeyOnSymbolsMatched
+ && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched
+ && isMultiLineMatched && imeActionMatched && localeCodeMatched
+ && languageCodeMatched && countryCodeMatched;
if (DEBUG) {
- startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
- textAttr(a.getString(
+ startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
+ textAttr(caseAttr.getString(
+ R.styleable.Keyboard_Case_keyboardLayoutSet), "keyboardLayoutSet"),
+ textAttr(caseAttr.getString(
R.styleable.Keyboard_Case_keyboardLayoutSetElement),
"keyboardLayoutSetElement"),
- textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_imeAction),
+ textAttr(caseAttr.getString(R.styleable.Keyboard_Case_mode), "mode"),
+ textAttr(caseAttr.getString(R.styleable.Keyboard_Case_imeAction),
"imeAction"),
- booleanAttr(a, R.styleable.Keyboard_Case_navigateNext,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_navigateNext,
"navigateNext"),
- booleanAttr(a, R.styleable.Keyboard_Case_navigatePrevious,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_navigatePrevious,
"navigatePrevious"),
- booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_clobberSettingsKey,
"clobberSettingsKey"),
- booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_passwordInput,
"passwordInput"),
- booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyEnabled,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_shortcutKeyEnabled,
"shortcutKeyEnabled"),
- booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyOnSymbols,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_shortcutKeyOnSymbols,
"shortcutKeyOnSymbols"),
- booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_hasShortcutKey,
"hasShortcutKey"),
- booleanAttr(a, R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
"languageSwitchKeyEnabled"),
- booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine,
+ booleanAttr(caseAttr, R.styleable.Keyboard_Case_isMultiLine,
"isMultiLine"),
- textAttr(a.getString(R.styleable.Keyboard_Case_localeCode),
+ textAttr(caseAttr.getString(R.styleable.Keyboard_Case_localeCode),
"localeCode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_languageCode),
+ textAttr(caseAttr.getString(R.styleable.Keyboard_Case_languageCode),
"languageCode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_countryCode),
+ textAttr(caseAttr.getString(R.styleable.Keyboard_Case_countryCode),
"countryCode"),
selected ? "" : " skipped");
}
return selected;
} finally {
- a.recycle();
+ caseAttr.recycle();
}
}
@@ -692,7 +740,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
}
if (ResourceUtils.isIntegerValue(v)) {
return intValue == a.getInt(index, 0);
- } else if (ResourceUtils.isStringValue(v)) {
+ }
+ if (ResourceUtils.isStringValue(v)) {
return StringUtils.containsInArray(strValue, a.getString(index).split("\\|"));
}
return false;
@@ -711,10 +760,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
private void parseKeyStyle(final XmlPullParser parser, final boolean skip)
throws XmlPullParserException, IOException {
- TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_KeyStyle);
- TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
+ final AttributeSet attr = Xml.asAttributeSet(parser);
+ final TypedArray keyStyleAttr = mResources.obtainAttributes(
+ attr, R.styleable.Keyboard_KeyStyle);
+ final TypedArray keyAttrs = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key);
try {
if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName)) {
throw new XmlParseUtils.ParseException("<" + TAG_KEY_STYLE
@@ -756,7 +805,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
mRightEdgeKey = null;
}
addEdgeSpace(mParams.mRightPadding, row);
- mCurrentY += row.mRowHeight;
+ mCurrentY += row.getRowHeight();
mCurrentRow = null;
mTopEdge = false;
}
@@ -774,7 +823,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
}
private void endKeyboard() {
- // nothing to do here.
+ // {@link #parseGridRows(XmlPullParser,boolean)} may populate keyboard rows higher than
+ // previously expected.
+ final int actualHeight = mCurrentY - mParams.mVerticalGap + mParams.mBottomPadding;
+ mParams.mOccupiedHeight = Math.max(mParams.mOccupiedHeight, actualHeight);
}
private void addEdgeSpace(final float width, final KeyboardRow row) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index a57b83ac0..d32bb7581 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -85,7 +85,7 @@ public class KeyboardParams {
public void onAddKey(final Key newKey) {
final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
final boolean isSpacer = key.isSpacer();
- if (isSpacer && key.mWidth == 0) {
+ if (isSpacer && key.getWidth() == 0) {
// Ignore zero width {@link Spacer}.
return;
}
@@ -94,7 +94,7 @@ public class KeyboardParams {
return;
}
updateHistogram(key);
- if (key.mCode == Constants.CODE_SHIFT) {
+ if (key.getCode() == Constants.CODE_SHIFT) {
mShiftKeys.add(key);
}
if (key.altCodeWhileTyping()) {
@@ -125,14 +125,14 @@ public class KeyboardParams {
}
private void updateHistogram(final Key key) {
- final int height = key.mHeight + mVerticalGap;
+ final int height = key.getHeight() + mVerticalGap;
final int heightCount = updateHistogramCounter(mHeightHistogram, height);
if (heightCount > mMaxHeightCount) {
mMaxHeightCount = heightCount;
mMostCommonKeyHeight = height;
}
- final int width = key.mWidth + mHorizontalGap;
+ final int width = key.getWidth() + mHorizontalGap;
final int widthCount = updateHistogramCounter(mWidthHistogram, width);
if (widthCount > mMaxWidthCount) {
mMaxWidthCount = widthCount;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
index 5fe84a704..0f9497c27 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
@@ -23,10 +23,13 @@ import android.util.Xml;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
import org.xmlpull.v1.XmlPullParser;
+import java.util.ArrayDeque;
+
/**
* Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
* Some of the key size defaults can be overridden per row from what the {@link Keyboard}
@@ -38,64 +41,100 @@ public final class KeyboardRow {
private static final int KEYWIDTH_FILL_RIGHT = -1;
private final KeyboardParams mParams;
- /** Default width of a key in this row. */
- private float mDefaultKeyWidth;
- /** Default height of a key in this row. */
- public final int mRowHeight;
- /** Default keyLabelFlags in this row. */
- private int mDefaultKeyLabelFlags;
- /** Default backgroundType for this row */
- private int mDefaultBackgroundType;
+ /** The height of this row. */
+ private final int mRowHeight;
+
+ private final ArrayDeque<RowAttributes> mRowAttributesStack = CollectionUtils.newArrayDeque();
+
+ private static class RowAttributes {
+ /** Default width of a key in this row. */
+ public final float mDefaultKeyWidth;
+ /** Default keyLabelFlags in this row. */
+ public final int mDefaultKeyLabelFlags;
+ /** Default backgroundType for this row */
+ public final int mDefaultBackgroundType;
+
+ /**
+ * Parse and create key attributes. This constructor is used to parse Row tag.
+ *
+ * @param keyAttr an attributes array of Row tag.
+ * @param defaultKeyWidth a default key width.
+ * @param keyboardWidth the keyboard width that is required to calculate keyWidth attribute.
+ */
+ public RowAttributes(final TypedArray keyAttr, final float defaultKeyWidth,
+ final int keyboardWidth) {
+ mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+ keyboardWidth, keyboardWidth, defaultKeyWidth);
+ mDefaultKeyLabelFlags = keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0);
+ mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
+ Key.BACKGROUND_TYPE_NORMAL);
+ }
+
+ /**
+ * Parse and update key attributes using default attributes. This constructor is used
+ * to parse include tag.
+ *
+ * @param keyAttr an attributes array of include tag.
+ * @param defaultRowAttr default Row attributes.
+ * @param keyboardWidth the keyboard width that is required to calculate keyWidth attribute.
+ */
+ public RowAttributes(final TypedArray keyAttr, final RowAttributes defaultRowAttr,
+ final int keyboardWidth) {
+ mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+ keyboardWidth, keyboardWidth, defaultRowAttr.mDefaultKeyWidth);
+ mDefaultKeyLabelFlags = keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0)
+ | defaultRowAttr.mDefaultKeyLabelFlags;
+ mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
+ defaultRowAttr.mDefaultBackgroundType);
+ }
+ }
private final int mCurrentY;
// Will be updated by {@link Key}'s constructor.
private float mCurrentX;
- public KeyboardRow(final Resources res, final KeyboardParams params, final XmlPullParser parser,
- final int y) {
+ public KeyboardRow(final Resources res, final KeyboardParams params,
+ final XmlPullParser parser, final int y) {
mParams = params;
final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard);
mRowHeight = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_rowHeight,
- params.mBaseHeight, params.mDefaultRowHeight);
+ R.styleable.Keyboard_rowHeight, params.mBaseHeight, params.mDefaultRowHeight);
keyboardAttr.recycle();
final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard_Key);
- mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
- params.mBaseWidth, params.mBaseWidth, params.mDefaultKeyWidth);
- mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
- Key.BACKGROUND_TYPE_NORMAL);
+ mRowAttributesStack.push(new RowAttributes(
+ keyAttr, params.mDefaultKeyWidth, params.mBaseWidth));
keyAttr.recycle();
- // TODO: Initialize this with <Row> attribute as backgroundType is done.
- mDefaultKeyLabelFlags = 0;
mCurrentY = y;
mCurrentX = 0.0f;
}
- public float getDefaultKeyWidth() {
- return mDefaultKeyWidth;
+ public int getRowHeight() {
+ return mRowHeight;
}
- public void setDefaultKeyWidth(final float defaultKeyWidth) {
- mDefaultKeyWidth = defaultKeyWidth;
+ public void pushRowAttributes(final TypedArray keyAttr) {
+ final RowAttributes newAttributes = new RowAttributes(
+ keyAttr, mRowAttributesStack.peek(), mParams.mBaseWidth);
+ mRowAttributesStack.push(newAttributes);
}
- public int getDefaultKeyLabelFlags() {
- return mDefaultKeyLabelFlags;
+ public void popRowAttributes() {
+ mRowAttributesStack.pop();
}
- public void setDefaultKeyLabelFlags(final int keyLabelFlags) {
- mDefaultKeyLabelFlags = keyLabelFlags;
+ public float getDefaultKeyWidth() {
+ return mRowAttributesStack.peek().mDefaultKeyWidth;
}
- public int getDefaultBackgroundType() {
- return mDefaultBackgroundType;
+ public int getDefaultKeyLabelFlags() {
+ return mRowAttributesStack.peek().mDefaultKeyLabelFlags;
}
- public void setDefaultBackgroundType(final int backgroundType) {
- mDefaultBackgroundType = backgroundType;
+ public int getDefaultBackgroundType() {
+ return mRowAttributesStack.peek().mDefaultBackgroundType;
}
public void setXPos(final float keyXPos) {
@@ -111,29 +150,27 @@ public final class KeyboardRow {
}
public float getKeyX(final TypedArray keyAttr) {
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
- final float keyXPos = keyAttr.getFraction(R.styleable.Keyboard_Key_keyXPos,
- mParams.mBaseWidth, mParams.mBaseWidth, 0);
- if (keyXPos < 0) {
- // If keyXPos is negative, the actual x-coordinate will be
- // keyboardWidth + keyXPos.
- // keyXPos shouldn't be less than mCurrentX because drawable area for this
- // key starts at mCurrentX. Or, this key will overlaps the adjacent key on
- // its left hand side.
- final int keyboardRightEdge = mParams.mOccupiedWidth - mParams.mRightPadding;
- return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
- } else {
- return keyXPos + mParams.mLeftPadding;
- }
+ if (keyAttr == null || !keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
+ return mCurrentX;
}
- return mCurrentX;
- }
-
- public float getKeyWidth(final TypedArray keyAttr) {
- return getKeyWidth(keyAttr, mCurrentX);
+ final float keyXPos = keyAttr.getFraction(R.styleable.Keyboard_Key_keyXPos,
+ mParams.mBaseWidth, mParams.mBaseWidth, 0);
+ if (keyXPos >= 0) {
+ return keyXPos + mParams.mLeftPadding;
+ }
+ // If keyXPos is negative, the actual x-coordinate will be
+ // keyboardWidth + keyXPos.
+ // keyXPos shouldn't be less than mCurrentX because drawable area for this
+ // key starts at mCurrentX. Or, this key will overlaps the adjacent key on
+ // its left hand side.
+ final int keyboardRightEdge = mParams.mOccupiedWidth - mParams.mRightPadding;
+ return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
}
public float getKeyWidth(final TypedArray keyAttr, final float keyXPos) {
+ if (keyAttr == null) {
+ return getDefaultKeyWidth();
+ }
final int widthType = ResourceUtils.getEnumValue(keyAttr,
R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
switch (widthType) {
@@ -144,7 +181,7 @@ public final class KeyboardRow {
return keyboardRightEdge - keyXPos;
default: // KEYWIDTH_NOT_ENUM
return keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
- mParams.mBaseWidth, mParams.mBaseWidth, mDefaultKeyWidth);
+ mParams.mBaseWidth, mParams.mBaseWidth, getDefaultKeyWidth());
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 164910dd4..b3491d807 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -45,6 +45,7 @@ public final class KeyboardState {
public void setAlphabetAutomaticShiftedKeyboard();
public void setAlphabetShiftLockedKeyboard();
public void setAlphabetShiftLockShiftedKeyboard();
+ public void setEmojiKeyboard();
public void setSymbolsKeyboard();
public void setSymbolsShiftedKeyboard();
@@ -74,7 +75,10 @@ public final class KeyboardState {
private static final int SWITCH_STATE_MOMENTARY_ALPHA_SHIFT = 5;
private int mSwitchState = SWITCH_STATE_ALPHA;
+ // TODO: Consolidate these two mode booleans into one integer to distinguish between alphabet,
+ // symbols, and emoji mode.
private boolean mIsAlphabetMode;
+ private boolean mIsEmojiMode;
private AlphabetShiftState mAlphabetShiftState = new AlphabetShiftState();
private boolean mIsSymbolShifted;
private boolean mPrevMainKeyboardWasShiftLocked;
@@ -91,6 +95,7 @@ public final class KeyboardState {
public boolean mIsValid;
public boolean mIsAlphabetMode;
public boolean mIsAlphabetShiftLocked;
+ public boolean mIsEmojiMode;
public int mShiftMode;
@Override
@@ -99,6 +104,8 @@ public final class KeyboardState {
if (mIsAlphabetMode) {
if (mIsAlphabetShiftLocked) return "ALPHABET_SHIFT_LOCKED";
return "ALPHABET_" + shiftModeToString(mShiftMode);
+ } else if (mIsEmojiMode) {
+ return "EMOJI";
} else {
return "SYMBOLS_" + shiftModeToString(mShiftMode);
}
@@ -131,6 +138,7 @@ public final class KeyboardState {
public void onSaveKeyboardState() {
final SavedKeyboardState state = mSavedKeyboardState;
state.mIsAlphabetMode = mIsAlphabetMode;
+ state.mIsEmojiMode = mIsEmojiMode;
if (mIsAlphabetMode) {
state.mIsAlphabetShiftLocked = mAlphabetShiftState.isShiftLocked();
state.mShiftMode = mAlphabetShiftState.isAutomaticShifted() ? AUTOMATIC_SHIFT
@@ -152,6 +160,8 @@ public final class KeyboardState {
}
if (!state.mIsValid || state.mIsAlphabetMode) {
setAlphabetKeyboard();
+ } else if (state.mIsEmojiMode) {
+ setEmojiKeyboard();
} else {
if (state.mShiftMode == MANUAL_SHIFT) {
setSymbolsShiftedKeyboard();
@@ -280,6 +290,7 @@ public final class KeyboardState {
mSwitchActions.setAlphabetKeyboard();
mIsAlphabetMode = true;
+ mIsEmojiMode = false;
mIsSymbolShifted = false;
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
mSwitchState = SWITCH_STATE_ALPHA;
@@ -310,6 +321,15 @@ public final class KeyboardState {
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
}
+ private void setEmojiKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setEmojiKeyboard");
+ }
+ mIsAlphabetMode = false;
+ mIsEmojiMode = true;
+ mSwitchActions.setEmojiKeyboard();
+ }
+
public void onPressKey(final int code, final boolean isSinglePointer, final int autoCaps) {
if (DEBUG_EVENT) {
Log.d(TAG, "onPressKey: code=" + Constants.printableCode(code)
@@ -460,7 +480,8 @@ public final class KeyboardState {
} else {
if (mAlphabetShiftState.isShiftLocked()) {
// Shift key is pressed while shift locked state, we will treat this state as
- // shift lock shifted state and mark as if shift key pressed while normal state.
+ // shift lock shifted state and mark as if shift key pressed while normal
+ // state.
setShifted(SHIFT_LOCK_SHIFTED);
mShiftKeyState.onPress();
} else if (mAlphabetShiftState.isAutomaticShifted()) {
@@ -587,7 +608,8 @@ public final class KeyboardState {
break;
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
if (code == Constants.CODE_SHIFT) {
- // Detected only the shift key has been pressed on symbol layout, and then released.
+ // Detected only the shift key has been pressed on symbol layout, and then
+ // released.
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
}
break;
@@ -610,6 +632,8 @@ public final class KeyboardState {
// If the code is a letter, update keyboard shift state.
if (Constants.isLetterCode(code)) {
updateAlphabetShiftState(autoCaps, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
+ } else if (code == Constants.CODE_EMOJI) {
+ setEmojiKeyboard();
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index b55e19d52..67553fb75 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -27,18 +27,18 @@ import java.util.HashMap;
/**
* !!!!! DO NOT EDIT THIS FILE !!!!!
*
- * This file is generated by tools/maketext. The base template file is
- * tools/maketext/res/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.tmpl
+ * This file is generated by tools/make-keyboard-text. The base template file is
+ * tools/make-keyboard-text/res/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.tmpl
*
* This file must be updated when any text resources in keyboard layout files have been changed.
* These text resources are referred as "!text/<resource_name>" in keyboard XML definitions,
* and should be defined in
- * tools/maketext/res/values-<locale>/donottranslate-more-keys.xml
+ * tools/make-keyboard-text/res/values-<locale>/donottranslate-more-keys.xml
*
* To update this file, please run the following commands.
* $ cd $ANDROID_BUILD_TOP
- * $ mmm packages/inputmethods/LatinIME/tools/maketext
- * $ maketext -java packages/inputmethods/LatinIME/java/src
+ * $ mmm packages/inputmethods/LatinIME/tools/make-keyboard-text
+ * $ make-keyboard-text -java packages/inputmethods/LatinIME/java/src
*
* The updated source file will be generated to the following path (this file).
* packages/inputmethods/LatinIME/java/src/com/android/inputmethod/keyboard/internal/
@@ -153,8 +153,8 @@ public final class KeyboardTextsSet {
/* 48 */ "single_angle_quotes",
/* 49 */ "double_angle_quotes",
/* 50 */ "more_keys_for_currency_dollar",
- /* 51 */ "keylabel_for_currency_generic",
- /* 52 */ "more_keys_for_currency_generic",
+ /* 51 */ "keylabel_for_currency",
+ /* 52 */ "more_keys_for_currency",
/* 53 */ "more_keys_for_punctuation",
/* 54 */ "more_keys_for_star",
/* 55 */ "more_keys_for_bullet",
@@ -233,25 +233,24 @@ public final class KeyboardTextsSet {
/* 128 */ "label_to_phone_symbols_key",
/* 129 */ "label_time_am",
/* 130 */ "label_time_pm",
- /* 131 */ "label_to_symbol_key_pcqwerty",
- /* 132 */ "keylabel_for_popular_domain",
- /* 133 */ "more_keys_for_popular_domain",
- /* 134 */ "more_keys_for_smiley",
- /* 135 */ "single_laqm_raqm",
- /* 136 */ "single_laqm_raqm_rtl",
- /* 137 */ "single_raqm_laqm",
- /* 138 */ "double_laqm_raqm",
- /* 139 */ "double_laqm_raqm_rtl",
- /* 140 */ "double_raqm_laqm",
- /* 141 */ "single_lqm_rqm",
- /* 142 */ "single_9qm_lqm",
- /* 143 */ "single_9qm_rqm",
- /* 144 */ "double_lqm_rqm",
- /* 145 */ "double_9qm_lqm",
- /* 146 */ "double_9qm_rqm",
- /* 147 */ "more_keys_for_single_quote",
- /* 148 */ "more_keys_for_double_quote",
- /* 149 */ "more_keys_for_tablet_double_quote",
+ /* 131 */ "keylabel_for_popular_domain",
+ /* 132 */ "more_keys_for_popular_domain",
+ /* 133 */ "more_keys_for_smiley",
+ /* 134 */ "single_laqm_raqm",
+ /* 135 */ "single_laqm_raqm_rtl",
+ /* 136 */ "single_raqm_laqm",
+ /* 137 */ "double_laqm_raqm",
+ /* 138 */ "double_laqm_raqm_rtl",
+ /* 139 */ "double_raqm_laqm",
+ /* 140 */ "single_lqm_rqm",
+ /* 141 */ "single_9qm_lqm",
+ /* 142 */ "single_9qm_rqm",
+ /* 143 */ "double_lqm_rqm",
+ /* 144 */ "double_9qm_lqm",
+ /* 145 */ "double_9qm_rqm",
+ /* 146 */ "more_keys_for_single_quote",
+ /* 147 */ "more_keys_for_double_quote",
+ /* 148 */ "more_keys_for_tablet_double_quote",
};
private static final String EMPTY = "";
@@ -278,7 +277,7 @@ public final class KeyboardTextsSet {
/* 50 */ "\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
/* 51 */ "$",
/* 52 */ "$,\u00A2,\u20AC,\u00A3,\u00A5,\u20B1",
- /* 53 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\\,,?,@,&,\\%,+,;,/,(,)",
+ /* 53 */ "!fixedColumnOrder!3,!,\\,,?,:,;,@",
// U+2020: "†" DAGGER
// U+2021: "‡" DOUBLE DAGGER
// U+2605: "★" BLACK STAR
@@ -361,10 +360,11 @@ public final class KeyboardTextsSet {
// U+2030: "‰" PER MILLE SIGN
/* 103 */ "\u2030",
/* 104 */ ",",
- /* 105 */ "!",
- /* 106 */ "!",
- /* 107 */ "?",
- /* 108 */ "?",
+ /* 105~ */
+ EMPTY, EMPTY, EMPTY,
+ /* ~107 */
+ // U+2026: "…" HORIZONTAL ELLIPSIS
+ /* 108 */ "\u2026",
/* 109 */ "\'",
/* 110 */ "\"",
/* 111 */ "\"",
@@ -383,7 +383,7 @@ public final class KeyboardTextsSet {
// Label for "switch to more symbol" modifier key. Must be short to fit on key!
/* 124 */ "= \\ <",
// Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key!
- /* 125 */ "~ \\ {",
+ /* 125 */ "~ [ <",
// Label for "Tab" key. Must be short to fit on key!
/* 126 */ "Tab",
// Label for "switch to phone numeric" key. Must be short to fit on key!
@@ -396,12 +396,10 @@ public final class KeyboardTextsSet {
/* 129 */ "AM",
// Key label for "post meridiem"
/* 130 */ "PM",
- // Label for "switch to symbols" key on PC QWERTY layout
- /* 131 */ "Sym",
- /* 132 */ ".com",
+ /* 131 */ ".com",
// popular web domains for the locale - most popular, displayed on the keyboard
- /* 133 */ "!hasLabels!,.net,.org,.gov,.edu",
- /* 134 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ",
+ /* 132 */ "!hasLabels!,.net,.org,.gov,.edu",
+ /* 133 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ",
// U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
// U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
@@ -423,24 +421,24 @@ public final class KeyboardTextsSet {
// The following each quotation mark pair consist of
// <opening quotation mark>, <closing quotation mark>
// and is named after (single|double)_<opening quotation mark>_<closing quotation mark>.
- /* 135 */ "\u2039,\u203A",
- /* 136 */ "\u2039|\u203A,\u203A|\u2039",
- /* 137 */ "\u203A,\u2039",
- /* 138 */ "\u00AB,\u00BB",
- /* 139 */ "\u00AB|\u00BB,\u00BB|\u00AB",
- /* 140 */ "\u00BB,\u00AB",
+ /* 134 */ "\u2039,\u203A",
+ /* 135 */ "\u2039|\u203A,\u203A|\u2039",
+ /* 136 */ "\u203A,\u2039",
+ /* 137 */ "\u00AB,\u00BB",
+ /* 138 */ "\u00AB|\u00BB,\u00BB|\u00AB",
+ /* 139 */ "\u00BB,\u00AB",
// The following each quotation mark triplet consists of
// <another quotation mark>, <opening quotation mark>, <closing quotation mark>
// and is named after (single|double)_<opening quotation mark>_<closing quotation mark>.
- /* 141 */ "\u201A,\u2018,\u2019",
- /* 142 */ "\u2019,\u201A,\u2018",
- /* 143 */ "\u2018,\u201A,\u2019",
- /* 144 */ "\u201E,\u201C,\u201D",
- /* 145 */ "\u201D,\u201E,\u201C",
- /* 146 */ "\u201C,\u201E,\u201D",
- /* 147 */ "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes",
- /* 148 */ "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes",
- /* 149 */ "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes",
+ /* 140 */ "\u201A,\u2018,\u2019",
+ /* 141 */ "\u2019,\u201A,\u2018",
+ /* 142 */ "\u2018,\u201A,\u2019",
+ /* 143 */ "\u201E,\u201C,\u201D",
+ /* 144 */ "\u201D,\u201E,\u201C",
+ /* 145 */ "\u201C,\u201E,\u201D",
+ /* 146 */ "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes",
+ /* 147 */ "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes",
+ /* 148 */ "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes",
};
/* Language af: Afrikaans */
@@ -519,7 +517,7 @@ public final class KeyboardTextsSet {
// U+061F: "؟" ARABIC QUESTION MARK
// U+060C: "،" ARABIC COMMA
// U+061B: "؛" ARABIC SEMICOLON
- /* 53 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(,)",
+ /* 53 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(|),)|(",
// U+2605: "★" BLACK STAR
// U+066D: "٭" ARABIC FIVE POINTED STAR
/* 54 */ "\u2605,\u066D",
@@ -785,7 +783,7 @@ public final class KeyboardTextsSet {
null, null, null, null, null, null, null, null,
/* ~52 */
// U+00B7: "·" MIDDLE DOT
- /* 53 */ "!fixedColumnOrder!9,\u00B7,\",\',#,-,:,!,\\,,?,@,&,\\%,+,;,/,(,)",
+ /* 53 */ "!fixedColumnOrder!4,\u00B7,!,\\,,?,:,;,@",
/* 54~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -1257,7 +1255,7 @@ public final class KeyboardTextsSet {
/* ~52 */
// U+00A1: "¡" INVERTED EXCLAMATION MARK
// U+00BF: "¿" INVERTED QUESTION MARK
- /* 53 */ "!fixedColumnOrder!9,\u00A1,\",\',#,-,:,!,\\,,?,\u00BF,@,&,\\%,+,;,/,(,)",
+ /* 53 */ "!fixedColumnOrder!4,;,!,\\,,?,:,\u00A1,@,\u00BF",
/* 54~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -1402,13 +1400,14 @@ public final class KeyboardTextsSet {
/* 47 */ null,
/* 48 */ "!text/single_laqm_raqm_rtl",
/* 49 */ "!text/double_laqm_raqm_rtl",
- /* 50~ */
- null, null, null,
- /* ~52 */
+ /* 50 */ null,
+ // U+FDFC: "﷼" RIAL SIGN
+ /* 51 */ "\uFDFC",
+ /* 52 */ null,
// U+061F: "؟" ARABIC QUESTION MARK
// U+060C: "،" ARABIC COMMA
// U+061B: "؛" ARABIC SEMICOLON
- /* 53 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(,)",
+ /* 53 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\u060C,\u061F,@,&,\\%,+,\u061B,/,(|),)|(",
// U+2605: "★" BLACK STAR
// U+066D: "٭" ARABIC FIVE POINTED STAR
/* 54 */ "\u2605,\u066D",
@@ -1762,6 +1761,37 @@ public final class KeyboardTextsSet {
/* 49 */ "!text/double_raqm_laqm",
};
+ /* Language hy: Armenian */
+ private static final String[] LANGUAGE_hy = {
+ /* 0~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null,
+ /* ~52 */
+ // U+058A: "֊" ARMENIAN HYPHEN
+ // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+ // U+055D: "՝" ARMENIAN COMMA
+ // U+055E: "՞" ARMENIAN QUESTION MARK
+ // U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING
+ // U+055A: "՚" ARMENIAN APOSTROPHE
+ // U+055B: "՛" ARMENIAN EMPHASIS MARK
+ // U+055F: "՟" ARMENIAN ABBREVIATION MARK
+ /* 53 */ "!fixedColumnOrder!8,!,?,\\,,.,\u058A,\u055C,\u055D,\u055E,:,;,@,\u0559,\u055A,\u055B,\u055F",
+ /* 54~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null,
+ /* ~99 */
+ // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+ // U+00A1: "¡" INVERTED EXCLAMATION MARK
+ /* 100 */ "\u055C,\u00A1",
+ // U+055E: "՞" ARMENIAN QUESTION MARK
+ // U+00BF: "¿" INVERTED QUESTION MARK
+ /* 101 */ "\u055E,\u00BF",
+ };
+
/* Language is: Icelandic */
private static final String[] LANGUAGE_is = {
// U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -1899,9 +1929,11 @@ public final class KeyboardTextsSet {
/* 47 */ "\u201C,\u201D,\u201E",
/* 48 */ "!text/single_laqm_raqm_rtl",
/* 49 */ "!text/double_laqm_raqm_rtl",
- /* 50~ */
- null, null, null, null,
- /* ~53 */
+ /* 50 */ null,
+ // U+20AA: "₪" NEW SHEQEL SIGN
+ /* 51 */ "\u20AA",
+ /* 52 */ null,
+ /* 53 */ null,
// U+2605: "★" BLACK STAR
/* 54 */ "\u2605",
/* 55 */ null,
@@ -1920,6 +1952,15 @@ public final class KeyboardTextsSet {
// U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
/* 59 */ "!fixedColumnOrder!3,\u2039|\u203A,\u2264|\u2265,\u00AB|\u00BB",
/* 60 */ "!fixedColumnOrder!3,\u203A|\u2039,\u2265|\u2264,\u00BB|\u00AB",
+ /* 61~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~104 */
+ /* 105 */ "!",
+ /* 106 */ "!",
+ /* 107 */ "?",
+ /* 108 */ "?",
};
/* Language ka: Georgian */
@@ -1986,6 +2027,25 @@ public final class KeyboardTextsSet {
/* 45 */ "\u0410\u0411\u0412",
};
+ /* Language km: Khmer */
+ private static final String[] LANGUAGE_km = {
+ /* 0~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~44 */
+ // Label for "switch to alphabetic" key.
+ // U+1780: "ក" KHMER LETTER KA
+ // U+1781: "ខ" KHMER LETTER KHA
+ // U+1782: "គ" KHMER LETTER KO
+ /* 45 */ "\u1780\u1781\u1782",
+ /* 46~ */
+ null, null, null, null,
+ /* ~49 */
+ // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
+ /* 50 */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
+ };
+
/* Language ky: Kirghiz */
private static final String[] LANGUAGE_ky = {
/* 0~ */
@@ -2027,6 +2087,25 @@ public final class KeyboardTextsSet {
/* 45 */ "\u0410\u0411\u0412",
};
+ /* Language lo: Lao */
+ private static final String[] LANGUAGE_lo = {
+ /* 0~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~44 */
+ // Label for "switch to alphabetic" key.
+ // U+0E81: "ກ" LAO LETTER KO
+ // U+0E82: "ຂ" LAO LETTER KHO SUNG
+ // U+0E84: "ຄ" LAO LETTER KHO TAM
+ /* 45 */ "\u0E81\u0E82\u0E84",
+ /* 46~ */
+ null, null, null, null, null,
+ /* ~50 */
+ // U+20AD: "₭" KIP SIGN
+ /* 51 */ "\u20AD",
+ };
+
/* Language lt: Lithuanian */
private static final String[] LANGUAGE_lt = {
// U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK
@@ -2318,6 +2397,63 @@ public final class KeyboardTextsSet {
/* 47 */ "!text/double_9qm_rqm",
};
+ /* Language ne: Nepali */
+ private static final String[] LANGUAGE_ne = {
+ /* 0~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~44 */
+ // Label for "switch to alphabetic" key.
+ // U+0915: "क" DEVANAGARI LETTER KA
+ // U+0916: "ख" DEVANAGARI LETTER KHA
+ // U+0917: "ग" DEVANAGARI LETTER GA
+ /* 45 */ "\u0915\u0916\u0917",
+ /* 46~ */
+ null, null, null, null, null,
+ /* ~50 */
+ // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN
+ /* 51 */ "\u0930\u0941.",
+ /* 52~ */
+ null, null, null, null, null, null, null, null, null, null, null,
+ /* ~62 */
+ // U+0967: "१" DEVANAGARI DIGIT ONE
+ /* 63 */ "\u0967",
+ // U+0968: "२" DEVANAGARI DIGIT TWO
+ /* 64 */ "\u0968",
+ // U+0969: "३" DEVANAGARI DIGIT THREE
+ /* 65 */ "\u0969",
+ // U+096A: "४" DEVANAGARI DIGIT FOUR
+ /* 66 */ "\u096A",
+ // U+096B: "५" DEVANAGARI DIGIT FIVE
+ /* 67 */ "\u096B",
+ // U+096C: "६" DEVANAGARI DIGIT SIX
+ /* 68 */ "\u096C",
+ // U+096D: "७" DEVANAGARI DIGIT SEVEN
+ /* 69 */ "\u096D",
+ // U+096E: "८" DEVANAGARI DIGIT EIGHT
+ /* 70 */ "\u096E",
+ // U+096F: "९" DEVANAGARI DIGIT NINE
+ /* 71 */ "\u096F",
+ // U+0966: "०" DEVANAGARI DIGIT ZERO
+ /* 72 */ "\u0966",
+ // Label for "switch to symbols" key.
+ /* 73 */ "?\u0967\u0968\u0969",
+ // Label for "switch to symbols with microphone" key. This string shouldn't include the "mic"
+ // part because it'll be appended by the code.
+ /* 74 */ "\u0967\u0968\u0969",
+ /* 75 */ "1",
+ /* 76 */ "2",
+ /* 77 */ "3",
+ /* 78 */ "4",
+ /* 79 */ "5",
+ /* 80 */ "6",
+ /* 81 */ "7",
+ /* 82 */ "8",
+ /* 83 */ "9",
+ /* 84 */ "0",
+ };
+
/* Language nl: Dutch */
private static final String[] LANGUAGE_nl = {
// U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
@@ -3296,17 +3432,21 @@ public final class KeyboardTextsSet {
"hi", LANGUAGE_hi, /* Hindi */
"hr", LANGUAGE_hr, /* Croatian */
"hu", LANGUAGE_hu, /* Hungarian */
+ "hy", LANGUAGE_hy, /* Armenian */
"is", LANGUAGE_is, /* Icelandic */
"it", LANGUAGE_it, /* Italian */
"iw", LANGUAGE_iw, /* Hebrew */
"ka", LANGUAGE_ka, /* Georgian */
"kk", LANGUAGE_kk, /* Kazakh */
+ "km", LANGUAGE_km, /* Khmer */
"ky", LANGUAGE_ky, /* Kirghiz */
+ "lo", LANGUAGE_lo, /* Lao */
"lt", LANGUAGE_lt, /* Lithuanian */
"lv", LANGUAGE_lv, /* Latvian */
"mk", LANGUAGE_mk, /* Macedonian */
"mn", LANGUAGE_mn, /* Mongolian */
"nb", LANGUAGE_nb, /* Norwegian Bokmål */
+ "ne", LANGUAGE_ne, /* Nepali */
"nl", LANGUAGE_nl, /* Dutch */
"pl", LANGUAGE_pl, /* Polish */
"pt", LANGUAGE_pt, /* Portuguese */
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java
new file mode 100644
index 000000000..b8ee976e8
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.widget.ScrollView;
+import android.widget.Scroller;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.latin.R;
+
+/**
+ * This is an extended {@link KeyboardView} class that hosts a scroll keyboard.
+ * Multi-touch unsupported. No {@link PointerTracker}s. No gesture support.
+ */
+// TODO: Implement key popup preview.
+public final class ScrollKeyboardView extends KeyboardView implements
+ ScrollViewWithNotifier.ScrollListener, GestureDetector.OnGestureListener {
+ private static final boolean PAGINATION = false;
+
+ public interface OnKeyClickListener {
+ public void onKeyClick(Key key);
+ }
+
+ private static final OnKeyClickListener EMPTY_LISTENER = new OnKeyClickListener() {
+ @Override
+ public void onKeyClick(final Key key) {}
+ };
+
+ private OnKeyClickListener mListener = EMPTY_LISTENER;
+ private final KeyDetector mKeyDetector = new KeyDetector(0.0f /*keyHysteresisDistance */);
+ private final GestureDetector mGestureDetector;
+
+ private final Scroller mScroller;
+ private ScrollViewWithNotifier mScrollView;
+
+ public ScrollKeyboardView(final Context context, final AttributeSet attrs) {
+ this(context, attrs, R.attr.keyboardViewStyle);
+ }
+
+ public ScrollKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
+ super(context, attrs, defStyle);
+ mGestureDetector = new GestureDetector(context, this);
+ mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */);
+ mScroller = new Scroller(context);
+ }
+
+ public void setScrollView(final ScrollViewWithNotifier scrollView) {
+ mScrollView = scrollView;
+ scrollView.setScrollListener(this);
+ }
+
+ private final Runnable mScrollTask = new Runnable() {
+ @Override
+ public void run() {
+ final Scroller scroller = mScroller;
+ final ScrollView scrollView = mScrollView;
+ scroller.computeScrollOffset();
+ scrollView.scrollTo(0, scroller.getCurrY());
+ if (!scroller.isFinished()) {
+ scrollView.post(this);
+ }
+ }
+ };
+
+ // {@link ScrollViewWithNotified#ScrollListener} methods.
+ @Override
+ public void notifyScrollChanged(final int scrollX, final int scrollY, final int oldX,
+ final int oldY) {
+ if (PAGINATION) {
+ mScroller.forceFinished(true /* finished */);
+ mScrollView.removeCallbacks(mScrollTask);
+ final int currentTop = mScrollView.getScrollY();
+ final int pageHeight = getKeyboard().mBaseHeight;
+ final int lastPageNo = currentTop / pageHeight;
+ final int lastPageTop = lastPageNo * pageHeight;
+ final int nextPageNo = lastPageNo + 1;
+ final int nextPageTop = Math.min(nextPageNo * pageHeight, getHeight() - pageHeight);
+ final int scrollTo = (currentTop - lastPageTop) < (nextPageTop - currentTop)
+ ? lastPageTop : nextPageTop;
+ final int deltaY = scrollTo - currentTop;
+ mScroller.startScroll(0, currentTop, 0, deltaY, 300);
+ mScrollView.post(mScrollTask);
+ }
+ }
+
+ @Override
+ public void notifyOverScrolled(final int scrollX, final int scrollY, final boolean clampedX,
+ final boolean clampedY) {
+ releaseCurrentKey();
+ }
+
+ public void setOnKeyClickListener(final OnKeyClickListener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setKeyboard(final Keyboard keyboard) {
+ super.setKeyboard(keyboard);
+ mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onTouchEvent(final MotionEvent e) {
+ if (mGestureDetector.onTouchEvent(e)) {
+ return true;
+ }
+ final Key key = getKey(e);
+ if (key != null && key != mCurrentKey) {
+ releaseCurrentKey();
+ }
+ return true;
+ }
+
+ // {@link GestureDetector#OnGestureListener} methods.
+ private Key mCurrentKey;
+
+ private Key getKey(final MotionEvent e) {
+ final int index = e.getActionIndex();
+ final int x = (int)e.getX(index);
+ final int y = (int)e.getY(index);
+ return mKeyDetector.detectHitKey(x, y);
+ }
+
+ public void releaseCurrentKey() {
+ final Key currentKey = mCurrentKey;
+ if (currentKey == null) {
+ return;
+ }
+ currentKey.onReleased();
+ invalidateKey(currentKey);
+ mCurrentKey = null;
+ }
+
+ @Override
+ public boolean onDown(final MotionEvent e) {
+ final Key key = getKey(e);
+ releaseCurrentKey();
+ mCurrentKey = key;
+ if (key == null) {
+ return false;
+ }
+ // TODO: May call {@link KeyboardActionListener#onPressKey(int,int,boolean)}.
+ key.onPressed();
+ invalidateKey(key);
+ return false;
+ }
+
+ @Override
+ public void onShowPress(final MotionEvent e) {
+ // User feedback is done at {@link #onDown(MotionEvent)}.
+ }
+
+ @Override
+ public boolean onSingleTapUp(final MotionEvent e) {
+ final Key key = getKey(e);
+ releaseCurrentKey();
+ if (key == null) {
+ return false;
+ }
+ // TODO: May call {@link KeyboardActionListener#onReleaseKey(int,boolean)}.
+ key.onReleased();
+ invalidateKey(key);
+ mListener.onKeyClick(key);
+ return true;
+ }
+
+ @Override
+ public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
+ final float distanceY) {
+ releaseCurrentKey();
+ return false;
+ }
+
+ @Override
+ public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX,
+ final float velocityY) {
+ releaseCurrentKey();
+ return false;
+ }
+
+ @Override
+ public void onLongPress(final MotionEvent e) {
+ // Long press detection of {@link #mGestureDetector} is disabled and not used.
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ScrollViewWithNotifier.java b/java/src/com/android/inputmethod/keyboard/internal/ScrollViewWithNotifier.java
new file mode 100644
index 000000000..d1ccdc7b5
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/ScrollViewWithNotifier.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ScrollView;
+
+/**
+ * This is an extended {@link ScrollView} that can notify
+ * {@link ScrollView#onScrollChanged(int,int,int,int} and
+ * {@link ScrollView#onOverScrolled(int,int,int,int)} to a content view.
+ */
+public class ScrollViewWithNotifier extends ScrollView {
+ private ScrollListener mScrollListener = EMPTY_LISTER;
+
+ public interface ScrollListener {
+ public void notifyScrollChanged(int scrollX, int scrollY, int oldX, int oldY);
+ public void notifyOverScrolled(int scrollX, int scrollY, boolean clampedX,
+ boolean clampedY);
+ }
+
+ private static final ScrollListener EMPTY_LISTER = new ScrollListener() {
+ @Override
+ public void notifyScrollChanged(int scrollX, int scrollY, int oldX, int oldY) {}
+ @Override
+ public void notifyOverScrolled(int scrollX, int scrollY, boolean clampedX,
+ boolean clampedY) {}
+ };
+
+ public ScrollViewWithNotifier(final Context context, final AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onScrollChanged(final int scrollX, final int scrollY, final int oldX,
+ final int oldY) {
+ super.onScrollChanged(scrollX, scrollY, oldX, oldY);
+ mScrollListener.notifyScrollChanged(scrollX, scrollY, oldX, oldY);
+ }
+
+ @Override
+ protected void onOverScrolled(final int scrollX, final int scrollY, final boolean clampedX,
+ final boolean clampedY) {
+ super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
+ mScrollListener.notifyOverScrolled(scrollX, scrollY, clampedX, clampedY);
+ }
+
+ public void setScrollListener(final ScrollListener listener) {
+ mScrollListener = listener;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
index ebbcedc96..845a9b987 100644
--- a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
@@ -19,10 +19,11 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.util.Log;
+import com.android.inputmethod.latin.makedict.DictEncoder;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
// TODO: Quit extending Dictionary after implementing dynamic binary dictionary.
@@ -42,37 +43,28 @@ abstract public class AbstractDictionaryWriter extends Dictionary {
abstract public void addUnigramWord(final String word, final String shortcutTarget,
final int frequency, final boolean isNotAWord);
+ // TODO: Remove lastModifiedTime after making binary dictionary support forgetting curve.
abstract public void addBigramWords(final String word0, final String word1,
- final int frequency, final boolean isValid);
+ final int frequency, final boolean isValid,
+ final long lastModifiedTime);
abstract public void removeBigramWords(final String word0, final String word1);
- abstract protected void writeBinaryDictionary(final FileOutputStream out)
+ abstract protected void writeDictionary(final DictEncoder dictEncoder)
throws IOException, UnsupportedFormatException;
public void write(final String fileName) {
final String tempFileName = fileName + ".temp";
final File file = new File(mContext.getFilesDir(), fileName);
final File tempFile = new File(mContext.getFilesDir(), tempFileName);
- FileOutputStream out = null;
try {
- out = new FileOutputStream(tempFile);
- writeBinaryDictionary(out);
- out.flush();
- out.close();
+ final DictEncoder dictEncoder = new Ver3DictEncoder(tempFile);
+ writeDictionary(dictEncoder);
tempFile.renameTo(file);
} catch (IOException e) {
Log.e(TAG, "IO exception while writing file", e);
} catch (UnsupportedFormatException e) {
Log.e(TAG, "Unsupported format", e);
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (IOException e) {
- // ignore
- }
- }
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 42c57946d..54bc29559 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -57,10 +57,10 @@ public final class AudioAndHapticFeedbackManager {
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
}
- public void hapticAndAudioFeedback(final int primaryCode,
+ public void performHapticAndAudioFeedback(final int code,
final View viewToPerformHapticFeedbackOn) {
- vibrateInternal(viewToPerformHapticFeedbackOn);
- playKeyClick(primaryCode);
+ performHapticFeedback(viewToPerformHapticFeedbackOn);
+ performAudioFeedback(code);
}
public boolean hasVibrator() {
@@ -81,14 +81,14 @@ public final class AudioAndHapticFeedbackManager {
return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
}
- private void playKeyClick(final int primaryCode) {
+ public void performAudioFeedback(final int code) {
// if mAudioManager is null, we can't play a sound anyway, so return
if (mAudioManager == null) {
return;
}
if (mSoundOn) {
final int sound;
- switch (primaryCode) {
+ switch (code) {
case Constants.CODE_DELETE:
sound = AudioManager.FX_KEYPRESS_DELETE;
break;
@@ -106,7 +106,7 @@ public final class AudioAndHapticFeedbackManager {
}
}
- private void vibrateInternal(final View viewToPerformHapticFeedbackOn) {
+ public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) {
if (!mSettingsValues.mVibrateOn) {
return;
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index d181bf697..61ccfcfad 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -19,14 +19,15 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
import android.util.SparseArray;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.settings.AdditionalFeaturesSettingUtils;
import com.android.inputmethod.latin.settings.NativeSuggestOptions;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.StringUtils;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
@@ -41,14 +42,20 @@ public final class BinaryDictionary extends Dictionary {
private static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
// Must be equal to MAX_RESULTS in native/jni/src/defines.h
private static final int MAX_RESULTS = 18;
+ // Required space count for auto commit.
+ // TODO: Remove this heuristic.
+ private static final int SPACE_COUNT_FOR_AUTO_COMMIT = 3;
private long mNativeDict;
private final Locale mLocale;
+ private final long mDictSize;
+ private final String mDictFilePath;
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS];
private final int[] mSpaceIndices = new int[MAX_RESULTS];
private final int[] mOutputScores = new int[MAX_RESULTS];
private final int[] mOutputTypes = new int[MAX_RESULTS];
+ private final int[] mOutputAutoCommitFirstWordConfidence = new int[MAX_RESULTS];
private final NativeSuggestOptions mNativeSuggestOptions = new NativeSuggestOptions();
@@ -63,7 +70,7 @@ public final class BinaryDictionary extends Dictionary {
if (traverseSession == null) {
traverseSession = mDicTraverseSessions.get(traverseSessionId);
if (traverseSession == null) {
- traverseSession = new DicTraverseSession(mLocale, mNativeDict);
+ traverseSession = new DicTraverseSession(mLocale, mNativeDict, mDictSize);
mDicTraverseSessions.put(traverseSessionId, traverseSession);
}
}
@@ -86,6 +93,8 @@ public final class BinaryDictionary extends Dictionary {
final boolean isUpdatable) {
super(dictType);
mLocale = locale;
+ mDictSize = length;
+ mDictFilePath = filename;
mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance);
loadDictionary(filename, offset, length, isUpdatable);
}
@@ -96,20 +105,26 @@ public final class BinaryDictionary extends Dictionary {
private static native long openNative(String sourceDir, long dictOffset, long dictSize,
boolean isUpdatable);
+ private static native void flushNative(long dict, String filePath);
+ private static native boolean needsToRunGCNative(long dict);
+ private static native void flushWithGCNative(long dict, String filePath);
private static native void closeNative(long dict);
private static native int getProbabilityNative(long dict, int[] word);
- private static native boolean isValidBigramNative(long dict, int[] word0, int[] word1);
+ private static native int getBigramProbabilityNative(long dict, int[] word0, int[] word1);
private static native int getSuggestionsNative(long dict, long proximityInfo,
long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint,
int[] suggestOptions, int[] prevWordCodePointArray,
- int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes);
+ int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes,
+ int[] outputAutoCommitFirstWordConfidence);
private static native float calcNormalizedScoreNative(int[] before, int[] after, int score);
private static native int editDistanceNative(int[] before, int[] after);
private static native void addUnigramWordNative(long dict, int[] word, int probability);
private static native void addBigramWordsNative(long dict, int[] word0, int[] word1,
int probability);
private static native void removeBigramWordsNative(long dict, int[] word0, int[] word1);
+ private static native int calculateProbabilityNative(long dict, int unigramProbability,
+ int bigramProbability);
// TODO: Move native dict into session
private final void loadDictionary(final String path, final long startOffset,
@@ -120,15 +135,16 @@ public final class BinaryDictionary extends Dictionary {
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
- 0 /* sessionId */);
+ additionalFeaturesOptions, 0 /* sessionId */);
}
@Override
public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int sessionId) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId) {
if (!isValidDictionary()) return null;
Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE);
@@ -148,15 +164,14 @@ public final class BinaryDictionary extends Dictionary {
final InputPointers ips = composer.getInputPointers();
final int inputSize = isGesture ? ips.getPointerSize() : composerSize;
mNativeSuggestOptions.setIsGesture(isGesture);
- mNativeSuggestOptions.setAdditionalFeaturesOptions(
- AdditionalFeaturesSettingUtils.getAdditionalNativeSuggestOptions());
+ mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions);
// proximityInfo and/or prevWordForBigrams may not be null.
final int count = getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
getTraverseSession(sessionId).getSession(), ips.getXCoordinates(),
ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints,
inputSize, 0 /* commitPoint */, mNativeSuggestOptions.getOptions(),
prevWordCodePointArray, mOutputCodePoints, mOutputScores, mSpaceIndices,
- mOutputTypes);
+ mOutputTypes, mOutputAutoCommitFirstWordConfidence);
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
for (int j = 0; j < count; ++j) {
final int start = j * MAX_WORD_LENGTH;
@@ -179,7 +194,9 @@ public final class BinaryDictionary extends Dictionary {
// TODO: check that all users of the `kind' parameter are ready to accept
// flags too and pass mOutputTypes[j] instead of kind
suggestions.add(new SuggestedWordInfo(new String(mOutputCodePoints, start, len),
- score, kind, mDictType));
+ score, kind, this /* sourceDict */,
+ mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */,
+ mOutputAutoCommitFirstWordConfidence[0]));
}
}
return suggestions;
@@ -205,12 +222,12 @@ public final class BinaryDictionary extends Dictionary {
@Override
public boolean isValidWord(final String word) {
- return getFrequency(word) >= 0;
+ return getFrequency(word) != NOT_A_PROBABILITY;
}
@Override
public int getFrequency(final String word) {
- if (word == null) return -1;
+ if (word == null) return NOT_A_PROBABILITY;
int[] codePoints = StringUtils.toCodePointArray(word);
return getProbabilityNative(mNativeDict, codePoints);
}
@@ -218,10 +235,20 @@ public final class BinaryDictionary extends Dictionary {
// TODO: Add a batch process version (isValidBigramMultiple?) to avoid excessive numbers of jni
// calls when checking for changes in an entire dictionary.
public boolean isValidBigram(final String word0, final String word1) {
- if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) return false;
+ return getBigramProbability(word0, word1) != NOT_A_PROBABILITY;
+ }
+
+ public int getBigramProbability(final String word0, final String word1) {
+ if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) return NOT_A_PROBABILITY;
final int[] codePoints0 = StringUtils.toCodePointArray(word0);
final int[] codePoints1 = StringUtils.toCodePointArray(word1);
- return isValidBigramNative(mNativeDict, codePoints0, codePoints1);
+ return getBigramProbabilityNative(mNativeDict, codePoints0, codePoints1);
+ }
+
+ private void runGCIfRequired() {
+ if (needsToRunGCNative(mNativeDict)) {
+ flushWithGC();
+ }
}
// Add a unigram entry to binary dictionary in native code.
@@ -229,6 +256,7 @@ public final class BinaryDictionary extends Dictionary {
if (TextUtils.isEmpty(word)) {
return;
}
+ runGCIfRequired();
final int[] codePoints = StringUtils.toCodePointArray(word);
addUnigramWordNative(mNativeDict, codePoints, probability);
}
@@ -238,6 +266,7 @@ public final class BinaryDictionary extends Dictionary {
if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) {
return;
}
+ runGCIfRequired();
final int[] codePoints0 = StringUtils.toCodePointArray(word0);
final int[] codePoints1 = StringUtils.toCodePointArray(word1);
addBigramWordsNative(mNativeDict, codePoints0, codePoints1, probability);
@@ -248,11 +277,57 @@ public final class BinaryDictionary extends Dictionary {
if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) {
return;
}
+ runGCIfRequired();
final int[] codePoints0 = StringUtils.toCodePointArray(word0);
final int[] codePoints1 = StringUtils.toCodePointArray(word1);
removeBigramWordsNative(mNativeDict, codePoints0, codePoints1);
}
+ public void flush() {
+ if (!isValidDictionary()) return;
+ flushNative(mNativeDict, mDictFilePath);
+ closeNative(mNativeDict);
+ final File dictFile = new File(mDictFilePath);
+ mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
+ dictFile.length(), true /* isUpdatable */);
+ }
+
+ public void flushWithGC() {
+ if (!isValidDictionary()) return;
+ flushWithGCNative(mNativeDict, mDictFilePath);
+ closeNative(mNativeDict);
+ final File dictFile = new File(mDictFilePath);
+ mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
+ dictFile.length(), true /* isUpdatable */);
+ }
+
+ public boolean needsToRunGC() {
+ if (!isValidDictionary()) return false;
+ return needsToRunGCNative(mNativeDict);
+ }
+
+ @UsedForTesting
+ public int calculateProbability(final int unigramProbability, final int bigramProbability) {
+ if (!isValidDictionary()) return NOT_A_PROBABILITY;
+ return calculateProbabilityNative(mNativeDict, unigramProbability, bigramProbability);
+ }
+
+ @Override
+ public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
+ // TODO: actually use the confidence rather than use this completely broken heuristic
+ final String word = candidate.mWord;
+ final int length = word.length();
+ int remainingSpaces = SPACE_COUNT_FOR_AUTO_COMMIT;
+ for (int i = 0; i < length; ++i) {
+ // This is okay because no low-surrogate and no high-surrogate can ever match the
+ // space character, so we don't need to take care of iterating on code points.
+ if (Constants.CODE_SPACE == word.charAt(i)) {
+ if (0 >= --remainingSpaces) return true;
+ }
+ }
+ return false;
+ }
+
@Override
public void close() {
synchronized (mDicTraverseSessions) {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index fa301b5a6..181ad17ea 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -21,17 +21,17 @@ import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.util.Log;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
+import com.android.inputmethod.latin.makedict.DictDecoder;
import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.nio.BufferUnderflowException;
-import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
@@ -227,23 +227,12 @@ final public class BinaryDictionaryGetter {
// those do not include whitelist entries, the new code with an old version of the dictionary
// would lose whitelist functionality.
private static boolean hackCanUseDictionaryFile(final Locale locale, final File f) {
- FileInputStream inStream = null;
try {
// Read the version of the file
- inStream = new FileInputStream(f);
- final BinaryDictInputOutput.ByteBufferWrapper buffer =
- new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map(
- FileChannel.MapMode.READ_ONLY, 0, f.length()));
- final int magic = buffer.readInt();
- if (magic != FormatSpec.VERSION_2_MAGIC_NUMBER) {
- return false;
- }
- final int formatVersion = buffer.readInt();
- final int headerSize = buffer.readInt();
- final HashMap<String, String> options = CollectionUtils.newHashMap();
- BinaryDictInputOutput.populateOptions(buffer, headerSize, options);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(f);
+ final FileHeader header = dictDecoder.readHeader();
- final String version = options.get(VERSION_KEY);
+ final String version = header.mDictionaryOptions.mAttributes.get(VERSION_KEY);
if (null == version) {
// No version in the options : the format is unexpected
return false;
@@ -259,14 +248,8 @@ final public class BinaryDictionaryGetter {
return false;
} catch (BufferUnderflowException e) {
return false;
- } finally {
- if (inStream != null) {
- try {
- inStream.close();
- } catch (IOException e) {
- // do nothing
- }
- }
+ } catch (UnsupportedFormatException e) {
+ return false;
}
}
@@ -303,7 +286,8 @@ final public class BinaryDictionaryGetter {
}
if (!dictPackSettings.isWordListActive(wordListId)) continue;
if (canUse) {
- fileList.add(AssetFileAddress.makeFromFileName(f.getPath()));
+ final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath());
+ if (null != afa) fileList.add(afa);
} else {
Log.e(TAG, "Found a cached dictionary file but cannot read or use it");
}
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 8aec03f71..c4f96016c 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -76,6 +76,11 @@ public final class Constants {
public static final String ASCII_CAPABLE = "AsciiCapable";
/**
+ * The subtype extra value used to indicate that the subtype keyboard layout is capable
+ * for typing EMOJI characters.
+ */
+ public static final String EMOJI_CAPABLE = "EmojiCapable";
+ /**
* The subtype extra value used to indicate that the subtype require network connection
* to work.
*/
@@ -133,6 +138,9 @@ public final class Constants {
public static final int SPELL_CHECKER_COORDINATE = -3;
public static final int EXTERNAL_KEYBOARD_COORDINATE = -4;
+ // A hint on how many characters to cache from the TextView. A good value of this is given by
+ // how many characters we need to be able to almost always find the caps mode.
+ public static final int EDITOR_CONTENTS_CACHE_SIZE = 1024;
// Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
@@ -157,6 +165,7 @@ public final class Constants {
public static final int CODE_TAB = '\t';
public static final int CODE_SPACE = ' ';
public static final int CODE_PERIOD = '.';
+ public static final int CODE_ARMENIAN_PERIOD = 0x0589;
public static final int CODE_DASH = '-';
public static final int CODE_SINGLE_QUOTE = '\'';
public static final int CODE_DOUBLE_QUOTE = '"';
@@ -164,9 +173,7 @@ public final class Constants {
public static final int CODE_EXCLAMATION_MARK = '!';
public static final int CODE_SLASH = '/';
public static final int CODE_COMMERCIAL_AT = '@';
- // TODO: Check how this should work for right-to-left languages. It seems to stand
- // that for rtl languages, a closing parenthesis is a left parenthesis. Is this
- // managed by the font? Or is it a different char?
+ public static final int CODE_PLUS = '+';
public static final int CODE_CLOSING_PARENTHESIS = ')';
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
@@ -220,7 +227,10 @@ public final class Constants {
}
}
+ public static final int MAX_INT_BIT_COUNT = 32;
+
private Constants() {
// This utility class is not publicly instantiable.
}
+
}
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index c99d0e2ea..ffeb92784 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.SystemClock;
import android.provider.BaseColumns;
@@ -70,7 +71,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private final boolean mUseFirstLastBigrams;
public ContactsBinaryDictionary(final Context context, final Locale locale) {
- super(context, getFilenameWithLocale(NAME, locale.toString()), Dictionary.TYPE_CONTACTS);
+ super(context, getFilenameWithLocale(NAME, locale.toString()), Dictionary.TYPE_CONTACTS,
+ false /* isUpdatable */);
mLocale = locale;
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
registerObserver(context);
@@ -144,8 +146,10 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
cursor.close();
}
}
- } catch (IllegalStateException e) {
- Log.e(TAG, "Contacts DB is having problems");
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote Contacts process.", e);
+ } catch (final IllegalStateException e) {
+ Log.e(TAG, "Contacts DB is having problems", e);
}
}
@@ -172,14 +176,18 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private int getContactCount() {
// TODO: consider switching to a rawQuery("select count(*)...") on the database if
// performance is a bottleneck.
- final Cursor cursor = mContext.getContentResolver().query(
- Contacts.CONTENT_URI, PROJECTION_ID_ONLY, null, null, null);
- if (cursor != null) {
- try {
- return cursor.getCount();
- } finally {
- cursor.close();
+ try {
+ final Cursor cursor = mContext.getContentResolver().query(
+ Contacts.CONTENT_URI, PROJECTION_ID_ONLY, null, null, null);
+ if (cursor != null) {
+ try {
+ return cursor.getCount();
+ } finally {
+ cursor.close();
+ }
}
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote Contacts process.", e);
}
return 0;
}
@@ -208,7 +216,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
false /* isNotAWord */);
if (!TextUtils.isEmpty(prevWord)) {
if (mUseFirstLastBigrams) {
- super.setBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM);
+ super.addBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM,
+ 0 /* lastModifiedTime */);
}
}
prevWord = word;
diff --git a/java/src/com/android/inputmethod/latin/DicTraverseSession.java b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
index 45b281318..8d295adee 100644
--- a/java/src/com/android/inputmethod/latin/DicTraverseSession.java
+++ b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
@@ -25,16 +25,16 @@ public final class DicTraverseSession {
JniUtils.loadNativeLibrary();
}
- private static native long setDicTraverseSessionNative(String locale);
+ private static native long setDicTraverseSessionNative(String locale, long dictSize);
private static native void initDicTraverseSessionNative(long nativeDicTraverseSession,
long dictionary, int[] previousWord, int previousWordLength);
private static native void releaseDicTraverseSessionNative(long nativeDicTraverseSession);
private long mNativeDicTraverseSession;
- public DicTraverseSession(Locale locale, long dictionary) {
+ public DicTraverseSession(Locale locale, long dictionary, long dictSize) {
mNativeDicTraverseSession = createNativeDicTraverseSession(
- locale != null ? locale.toString() : "");
+ locale != null ? locale.toString() : "", dictSize);
initSession(dictionary);
}
@@ -51,8 +51,8 @@ public final class DicTraverseSession {
mNativeDicTraverseSession, dictionary, previousWord, previousWordLength);
}
- private final long createNativeDicTraverseSession(String locale) {
- return setDicTraverseSessionNative(locale);
+ private final long createNativeDicTraverseSession(String locale, long dictSize) {
+ return setDicTraverseSessionNative(locale, dictSize);
}
private void closeInternal() {
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 7c3e4a740..fa79f5af7 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -28,9 +28,26 @@ import java.util.ArrayList;
public abstract class Dictionary {
public static final int NOT_A_PROBABILITY = -1;
+ // The following types do not actually come from real dictionary instances, so we create
+ // corresponding instances.
public static final String TYPE_USER_TYPED = "user_typed";
+ public static final Dictionary DICTIONARY_USER_TYPED = new PhonyDictionary(TYPE_USER_TYPED);
+
public static final String TYPE_APPLICATION_DEFINED = "application_defined";
+ public static final Dictionary DICTIONARY_APPLICATION_DEFINED =
+ new PhonyDictionary(TYPE_APPLICATION_DEFINED);
+
public static final String TYPE_HARDCODED = "hardcoded"; // punctuation signs and such
+ public static final Dictionary DICTIONARY_HARDCODED =
+ new PhonyDictionary(TYPE_HARDCODED);
+
+ // Spawned by resuming suggestions. Comes from a span that was in the TextView.
+ public static final String TYPE_RESUMED = "resumed";
+ public static final Dictionary DICTIONARY_RESUMED =
+ new PhonyDictionary(TYPE_RESUMED);
+
+ // The following types of dictionary have actual functional instances. We don't need final
+ // phony dictionary instances for them.
public static final String TYPE_MAIN = "main";
public static final String TYPE_CONTACTS = "contacts";
// User dictionary, the system-managed one.
@@ -42,9 +59,7 @@ public abstract class Dictionary {
// Personalization prediction dictionary internal to LatinIME's Java code.
public static final String TYPE_PERSONALIZATION_PREDICTION_IN_JAVA =
"personalization_prediction_in_java";
- // Spawned by resuming suggestions. Comes from a span that was in the TextView.
- public static final String TYPE_RESUMED = "resumed";
- protected final String mDictType;
+ public final String mDictType;
public Dictionary(final String dictType) {
mDictType = dictType;
@@ -57,20 +72,23 @@ public abstract class Dictionary {
* @param prevWord the previous word, or null if none
* @param proximityInfo the object for key proximity. May be ignored by some implementations.
* @param blockOffensiveWords whether to block potentially offensive words
+ * @param additionalFeaturesOptions options about additional features used for the suggestion.
* @return the list of suggestions (possibly null if none)
*/
// TODO: pass more context than just the previous word, to enable better suggestions (n-gram
// and more)
abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords);
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions);
// The default implementation of this method ignores sessionId.
// Subclasses that want to use sessionId need to override this method.
public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int sessionId) {
- return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords);
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId) {
+ return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions);
}
/**
@@ -114,8 +132,43 @@ public abstract class Dictionary {
/**
* Subclasses may override to indicate that this Dictionary is not yet properly initialized.
*/
-
public boolean isInitialized() {
return true;
}
+
+ /**
+ * Whether we think this suggestion should trigger an auto-commit. prevWord is the word
+ * before the suggestion, so that we can use n-gram frequencies.
+ * @param candidate The candidate suggestion, in whole (not only the first part).
+ * @return whether we should auto-commit or not.
+ */
+ public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
+ // If we don't have support for auto-commit, or if we don't know, we return false to
+ // avoid auto-committing stuff. Implementations of the Dictionary class that know to
+ // determine whether we should auto-commit will override this.
+ return false;
+ }
+
+ /**
+ * Not a true dictionary. A placeholder used to indicate suggestions that don't come from any
+ * real dictionary.
+ */
+ private static class PhonyDictionary extends Dictionary {
+ // This class is not publicly instantiable.
+ private PhonyDictionary(final String type) {
+ super(type);
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ return null;
+ }
+
+ @Override
+ public boolean isValidWord(String word) {
+ return false;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index d05bb1e55..bf075140e 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -58,18 +58,18 @@ public final class DictionaryCollection extends Dictionary {
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries;
if (dictionaries.isEmpty()) return null;
// To avoid creating unnecessary objects, we get the list out of the first
// dictionary and add the rest to it if not null, hence the get(0)
ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer,
- prevWord, proximityInfo, blockOffensiveWords);
+ prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions);
if (null == suggestions) suggestions = CollectionUtils.newArrayList();
final int length = dictionaries.size();
for (int i = 1; i < length; ++ i) {
final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer,
- prevWord, proximityInfo, blockOffensiveWords);
+ prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions);
if (null != sugg) suggestions.addAll(sugg);
}
return suggestions;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryWriter.java b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
index 47151bf61..5a453dde5 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
@@ -20,15 +20,14 @@ import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
+import com.android.inputmethod.latin.makedict.DictEncoder;
import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.utils.CollectionUtils;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -51,7 +50,7 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
@Override
public void clear() {
final HashMap<String, String> attributes = CollectionUtils.newHashMap();
- mFusionDictionary = new FusionDictionary(new Node(),
+ mFusionDictionary = new FusionDictionary(new PtNodeArray(),
new FusionDictionary.DictionaryOptions(attributes, false, false));
}
@@ -75,7 +74,7 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
@Override
public void addBigramWords(final String word0, final String word1, final int frequency,
- final boolean isValid) {
+ final boolean isValid, final long lastModifiedTime) {
mFusionDictionary.setBigram(word0, word1, frequency);
}
@@ -85,15 +84,15 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
}
@Override
- protected void writeBinaryDictionary(final FileOutputStream out)
+ protected void writeDictionary(final DictEncoder dictEncoder)
throws IOException, UnsupportedFormatException {
- BinaryDictInputOutput.writeDictionaryBinary(out, mFusionDictionary, FORMAT_OPTIONS);
+ dictEncoder.writeDictionary(mFusionDictionary, FORMAT_OPTIONS);
}
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- boolean blockOffensiveWords) {
+ boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
// This class doesn't support suggestion.
return null;
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 3f11391ba..0774ce203 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -20,14 +20,26 @@ import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.makedict.DictEncoder;
+import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
+import com.android.inputmethod.latin.personalization.DynamicPersonalizationDictionaryWriter;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Abstract base class for an expandable dictionary that can be created and updated dynamically
@@ -45,19 +57,30 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** Whether to print debug output to log */
private static boolean DEBUG = false;
+ // TODO: Remove.
+ /** Whether to call binary dictionary dynamically updating methods. */
+ public static boolean ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE = true;
+
+ private static final int TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS = 100;
+
/**
* The maximum length of a word in this dictionary.
*/
protected static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
+ private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
+ new FormatSpec.FormatOptions(3 /* version */, true /* supportsDynamicUpdate */);
+
/**
- * A static map of locks, each of which controls access to a single binary dictionary file. They
- * ensure that only one instance can update the same dictionary at the same time. The key for
- * this map is the filename and the value is the shared dictionary controller associated with
- * that filename.
+ * A static map of time recorders, each of which records the time of accesses to a single binary
+ * dictionary file. The key for this map is the filename and the value is the shared dictionary
+ * time recorder associated with that filename.
*/
- private static final HashMap<String, DictionaryController> sSharedDictionaryControllers =
- CollectionUtils.newHashMap();
+ private static volatile ConcurrentHashMap<String, DictionaryTimeRecorder>
+ sFilenameDictionaryTimeRecorderMap = CollectionUtils.newConcurrentHashMap();
+
+ private static volatile ConcurrentHashMap<String, PrioritizedSerialExecutor>
+ sFilenameExecutorMap = CollectionUtils.newConcurrentHashMap();
/** The application context. */
protected final Context mContext;
@@ -68,21 +91,34 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
private BinaryDictionary mBinaryDictionary;
+ // TODO: Remove and handle dictionaries in native code.
/** The in-memory dictionary used to generate the binary dictionary. */
- private AbstractDictionaryWriter mDictionaryWriter;
+ protected AbstractDictionaryWriter mDictionaryWriter;
/**
* The name of this dictionary, used as the filename for storing the binary dictionary. Multiple
* dictionary instances with the same filename is supported, with access controlled by
- * DictionaryController.
+ * DictionaryTimeRecorder.
*/
private final String mFilename;
- /** Controls access to the shared binary dictionary file across multiple instances. */
- private final DictionaryController mSharedDictionaryController;
+ /** Whether to support dynamically updating the dictionary */
+ private final boolean mIsUpdatable;
- /** Controls access to the local binary dictionary for this instance. */
- private final DictionaryController mLocalDictionaryController = new DictionaryController();
+ // TODO: remove, once dynamic operations is serialized
+ /** Records access to the shared binary dictionary file across multiple instances. */
+ private final DictionaryTimeRecorder mFilenameDictionaryTimeRecorder;
+
+ // TODO: remove, once dynamic operations is serialized
+ /** Records access to the local binary dictionary for this instance. */
+ private final DictionaryTimeRecorder mPerInstanceDictionaryTimeRecorder =
+ new DictionaryTimeRecorder();
+
+ /* A extension for a binary dictionary file. */
+ public static final String DICT_FILE_EXTENSION = ".dict";
+
+ private final AtomicReference<Runnable> mUnfinishedFlushingTask =
+ new AtomicReference<Runnable>();
/**
* Abstract method for loading the unigrams and bigrams of a given dictionary in a background
@@ -98,16 +134,45 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected abstract boolean hasContentChanged();
/**
- * Gets the shared dictionary controller for the given filename.
+ * Gets the dictionary time recorder for the given filename.
*/
- private static synchronized DictionaryController getSharedDictionaryController(
+ private static DictionaryTimeRecorder getDictionaryTimeRecorder(
String filename) {
- DictionaryController controller = sSharedDictionaryControllers.get(filename);
- if (controller == null) {
- controller = new DictionaryController();
- sSharedDictionaryControllers.put(filename, controller);
+ DictionaryTimeRecorder recorder = sFilenameDictionaryTimeRecorderMap.get(filename);
+ if (recorder == null) {
+ synchronized(sFilenameDictionaryTimeRecorderMap) {
+ recorder = new DictionaryTimeRecorder();
+ sFilenameDictionaryTimeRecorderMap.put(filename, recorder);
+ }
+ }
+ return recorder;
+ }
+
+ /**
+ * Gets the executor for the given filename.
+ */
+ private static PrioritizedSerialExecutor getExecutor(final String filename) {
+ PrioritizedSerialExecutor executor = sFilenameExecutorMap.get(filename);
+ if (executor == null) {
+ synchronized(sFilenameExecutorMap) {
+ executor = new PrioritizedSerialExecutor();
+ sFilenameExecutorMap.put(filename, executor);
+ }
+ }
+ return executor;
+ }
+
+ private static AbstractDictionaryWriter getDictionaryWriter(final Context context,
+ final String dictType, final boolean isDynamicPersonalizationDictionary) {
+ if (isDynamicPersonalizationDictionary) {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ return null;
+ } else {
+ return new DynamicPersonalizationDictionaryWriter(context, dictType);
+ }
+ } else {
+ return new DictionaryWriter(context, dictType);
}
- return controller;
}
/**
@@ -117,19 +182,23 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* @param filename The filename for this binary dictionary. Multiple dictionaries with the same
* filename is supported.
* @param dictType the dictionary type, as a human-readable string
+ * @param isUpdatable whether to support dynamically updating the dictionary. Please note that
+ * dynamic dictionary has negative effects on memory space and computation time.
*/
- public ExpandableBinaryDictionary(
- final Context context, final String filename, final String dictType) {
+ public ExpandableBinaryDictionary(final Context context, final String filename,
+ final String dictType, final boolean isUpdatable) {
super(dictType);
mFilename = filename;
mContext = context;
+ mIsUpdatable = isUpdatable;
mBinaryDictionary = null;
- mSharedDictionaryController = getSharedDictionaryController(filename);
- mDictionaryWriter = new DictionaryWriter(context, dictType);
+ mFilenameDictionaryTimeRecorder = getDictionaryTimeRecorder(filename);
+ // Currently, only dynamic personalization dictionary is updatable.
+ mDictionaryWriter = getDictionaryWriter(context, dictType, isUpdatable);
}
protected static String getFilenameWithLocale(final String name, final String localeStr) {
- return name + "." + localeStr + ".dict";
+ return name + "." + localeStr + DICT_FILE_EXTENSION;
}
/**
@@ -137,17 +206,56 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
@Override
public void close() {
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mBinaryDictionary!= null) {
+ mBinaryDictionary.close();
+ mBinaryDictionary = null;
+ }
+ if (mDictionaryWriter != null) {
+ mDictionaryWriter.close();
+ }
+ }
+ });
+ }
+
+ protected void closeBinaryDictionary() {
// Ensure that no other threads are accessing the local binary dictionary.
- mLocalDictionaryController.writeLock().lock();
- try {
- if (mBinaryDictionary != null) {
- mBinaryDictionary.close();
- mBinaryDictionary = null;
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ if (mBinaryDictionary != null) {
+ mBinaryDictionary.close();
+ mBinaryDictionary = null;
+ }
}
- mDictionaryWriter.close();
- } finally {
- mLocalDictionaryController.writeLock().unlock();
- }
+ });
+ }
+
+ protected void clear() {
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE && mDictionaryWriter == null) {
+ mBinaryDictionary.close();
+ final File file = new File(mContext.getFilesDir(), mFilename);
+ final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+ new FusionDictionary.DictionaryOptions(new HashMap<String,String>(),
+ false, false));
+ final DictEncoder dictEncoder = new Ver3DictEncoder(file);
+ try {
+ dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
+ } catch (IOException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ }
+ } else {
+ mDictionaryWriter.clear();
+ }
+ }
+ });
}
/**
@@ -159,86 +267,159 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
- * Sets a word bigram in the dictionary. Used for loading a dictionary.
+ * Adds a word bigram in the dictionary. Used for loading a dictionary.
*/
- protected void setBigram(final String prevWord, final String word, final int frequency) {
- mDictionaryWriter.addBigramWords(prevWord, word, frequency, true /* isValid */);
+ protected void addBigram(final String prevWord, final String word, final int frequency,
+ final long lastModifiedTime) {
+ mDictionaryWriter.addBigramWords(prevWord, word, frequency, true /* isValid */,
+ lastModifiedTime);
}
/**
- * Dynamically adds a word unigram to the dictionary.
+ * Dynamically adds a word unigram to the dictionary. May overwrite an existing entry.
*/
protected void addWordDynamically(final String word, final String shortcutTarget,
final int frequency, final boolean isNotAWord) {
- mLocalDictionaryController.writeLock().lock();
- try {
- mDictionaryWriter.addUnigramWord(word, shortcutTarget, frequency, isNotAWord);
- } finally {
- mLocalDictionaryController.writeLock().unlock();
+ if (!mIsUpdatable) {
+ Log.w(TAG, "addWordDynamically is called for non-updatable dictionary: " + mFilename);
+ return;
}
+
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ mBinaryDictionary.addUnigramWord(word, frequency);
+ } else {
+ // TODO: Remove.
+ mDictionaryWriter.addUnigramWord(word, shortcutTarget, frequency, isNotAWord);
+ }
+ }
+ });
+ }
+
+ /**
+ * Dynamically adds a word bigram in the dictionary. May overwrite an existing entry.
+ */
+ protected void addBigramDynamically(final String word0, final String word1,
+ final int frequency, final boolean isValid) {
+ if (!mIsUpdatable) {
+ Log.w(TAG, "addBigramDynamically is called for non-updatable dictionary: "
+ + mFilename);
+ return;
+ }
+
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ mBinaryDictionary.addBigramWords(word0, word1, frequency);
+ } else {
+ // TODO: Remove.
+ mDictionaryWriter.addBigramWords(word0, word1, frequency, isValid,
+ 0 /* lastTouchedTime */);
+ }
+ }
+ });
}
/**
- * Dynamically sets a word bigram in the dictionary.
+ * Dynamically remove a word bigram in the dictionary.
*/
- protected void setBigramDynamically(final String prevWord, final String word,
- final int frequency) {
- mLocalDictionaryController.writeLock().lock();
- try {
- mDictionaryWriter.addBigramWords(prevWord, word, frequency, true /* isValid */);
- } finally {
- mLocalDictionaryController.writeLock().unlock();
+ protected void removeBigramDynamically(final String word0, final String word1) {
+ if (!mIsUpdatable) {
+ Log.w(TAG, "removeBigramDynamically is called for non-updatable dictionary: "
+ + mFilename);
+ return;
}
+
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ mBinaryDictionary.removeBigramWords(word0, word1);
+ } else {
+ // TODO: Remove.
+ mDictionaryWriter.removeBigramWords(word0, word1);
+ }
+ }
+ });
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
- asyncReloadDictionaryIfRequired();
- // Write lock because getSuggestions in native updates session status.
- if (mLocalDictionaryController.writeLock().tryLock()) {
- try {
- final ArrayList<SuggestedWordInfo> inMemDictSuggestion =
- mDictionaryWriter.getSuggestions(composer, prevWord, proximityInfo,
- blockOffensiveWords);
- if (mBinaryDictionary != null) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId) {
+ reloadDictionaryIfRequired();
+ final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
+ final AsyncResultHolder<ArrayList<SuggestedWordInfo>> holder =
+ new AsyncResultHolder<ArrayList<SuggestedWordInfo>>();
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ if (mBinaryDictionary == null) {
+ holder.set(null);
+ return;
+ }
final ArrayList<SuggestedWordInfo> binarySuggestion =
- mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
- blockOffensiveWords);
- if (inMemDictSuggestion == null) {
- return binarySuggestion;
- } else if (binarySuggestion == null) {
- return inMemDictSuggestion;
+ mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord,
+ proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
+ sessionId);
+ holder.set(binarySuggestion);
+ } else {
+ final ArrayList<SuggestedWordInfo> inMemDictSuggestion =
+ composer.isBatchMode() ? null :
+ mDictionaryWriter.getSuggestionsWithSessionId(composer,
+ prevWord, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, sessionId);
+ // TODO: Remove checking mIsUpdatable and use native suggestion.
+ if (mBinaryDictionary != null && !mIsUpdatable) {
+ final ArrayList<SuggestedWordInfo> binarySuggestion =
+ mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord,
+ proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, sessionId);
+ if (inMemDictSuggestion == null) {
+ holder.set(binarySuggestion);
+ } else if (binarySuggestion == null) {
+ holder.set(inMemDictSuggestion);
+ } else {
+ binarySuggestion.addAll(inMemDictSuggestion);
+ holder.set(binarySuggestion);
+ }
} else {
- binarySuggestion.addAll(binarySuggestion);
- return binarySuggestion;
+ holder.set(inMemDictSuggestion);
}
- } else {
- return inMemDictSuggestion;
}
- } finally {
- mLocalDictionaryController.writeLock().unlock();
}
- }
- return null;
+ });
+ return holder.get(null, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, 0 /* sessionId */);
}
@Override
public boolean isValidWord(final String word) {
- asyncReloadDictionaryIfRequired();
+ reloadDictionaryIfRequired();
return isValidWordInner(word);
}
protected boolean isValidWordInner(final String word) {
- if (mLocalDictionaryController.readLock().tryLock()) {
- try {
- return isValidWordLocked(word);
- } finally {
- mLocalDictionaryController.readLock().unlock();
+ final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ holder.set(isValidWordLocked(word));
}
- }
- return false;
+ });
+ return holder.get(false, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
}
protected boolean isValidWordLocked(final String word) {
@@ -256,8 +437,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* dictionary exists, this method will generate one.
*/
protected void loadDictionary() {
- mLocalDictionaryController.mLastUpdateRequestTime = SystemClock.uptimeMillis();
- asyncReloadDictionaryIfRequired();
+ mPerInstanceDictionaryTimeRecorder.mLastUpdateRequestTime = SystemClock.uptimeMillis();
+ reloadDictionaryIfRequired();
}
/**
@@ -267,8 +448,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private void loadBinaryDictionary() {
if (DEBUG) {
Log.d(TAG, "Loading binary dictionary: " + mFilename + " request="
- + mSharedDictionaryController.mLastUpdateRequestTime + " update="
- + mSharedDictionaryController.mLastUpdateTime);
+ + mFilenameDictionaryTimeRecorder.mLastUpdateRequestTime + " update="
+ + mFilenameDictionaryTimeRecorder.mLastUpdateTime);
}
final File file = new File(mContext.getFilesDir(), mFilename);
@@ -277,22 +458,21 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
// Build the new binary dictionary
final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0, length,
- true /* useFullEditDistance */, null, mDictType, false /* isUpdatable */);
-
- if (mBinaryDictionary != null) {
- // Ensure all threads accessing the current dictionary have finished before swapping in
- // the new one.
- final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
- mLocalDictionaryController.writeLock().lock();
- try {
+ true /* useFullEditDistance */, null, mDictType, mIsUpdatable);
+
+ // Ensure all threads accessing the current dictionary have finished before
+ // swapping in the new one.
+ // TODO: Ensure multi-thread assignment of mBinaryDictionary.
+ final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
mBinaryDictionary = newBinaryDictionary;
- } finally {
- mLocalDictionaryController.writeLock().unlock();
+ if (oldBinaryDictionary != null) {
+ oldBinaryDictionary.close();
+ }
}
- oldBinaryDictionary.close();
- } else {
- mBinaryDictionary = newBinaryDictionary;
- }
+ });
}
/**
@@ -302,19 +482,44 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
abstract protected boolean needsToReloadBeforeWriting();
/**
- * Generates and writes a new binary dictionary based on the contents of the fusion dictionary.
+ * Writes a new binary dictionary based on the contents of the fusion dictionary.
*/
- private void generateBinaryDictionary() {
+ private void writeBinaryDictionary() {
if (DEBUG) {
Log.d(TAG, "Generating binary dictionary: " + mFilename + " request="
- + mSharedDictionaryController.mLastUpdateRequestTime + " update="
- + mSharedDictionaryController.mLastUpdateTime);
+ + mFilenameDictionaryTimeRecorder.mLastUpdateRequestTime + " update="
+ + mFilenameDictionaryTimeRecorder.mLastUpdateTime);
}
if (needsToReloadBeforeWriting()) {
mDictionaryWriter.clear();
loadDictionaryAsync();
+ mDictionaryWriter.write(mFilename);
+ } else {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ if (mBinaryDictionary == null || !mBinaryDictionary.isValidDictionary()) {
+ final File file = new File(mContext.getFilesDir(), mFilename);
+ final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+ new FusionDictionary.DictionaryOptions(new HashMap<String,String>(),
+ false, false));
+ final DictEncoder dictEncoder = new Ver3DictEncoder(file);
+ try {
+ dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
+ } catch (IOException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ }
+ } else {
+ if (mBinaryDictionary.needsToRunGC()) {
+ mBinaryDictionary.flushWithGC();
+ } else {
+ mBinaryDictionary.flush();
+ }
+ }
+ } else {
+ mDictionaryWriter.write(mFilename);
+ }
}
- mDictionaryWriter.write(mFilename);
}
/**
@@ -326,83 +531,74 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
protected void setRequiresReload(final boolean requiresRebuild) {
final long time = SystemClock.uptimeMillis();
- mLocalDictionaryController.mLastUpdateRequestTime = time;
- mSharedDictionaryController.mLastUpdateRequestTime = time;
+ mPerInstanceDictionaryTimeRecorder.mLastUpdateRequestTime = time;
+ mFilenameDictionaryTimeRecorder.mLastUpdateRequestTime = time;
if (DEBUG) {
Log.d(TAG, "Reload request: " + mFilename + ": request=" + time + " update="
- + mSharedDictionaryController.mLastUpdateTime);
- }
- }
-
- /**
- * Reloads the dictionary if required. Reload will occur asynchronously in a separate thread.
- */
- void asyncReloadDictionaryIfRequired() {
- if (!isReloadRequired()) return;
- if (DEBUG) {
- Log.d(TAG, "Starting AsyncReloadDictionaryTask: " + mFilename);
+ + mFilenameDictionaryTimeRecorder.mLastUpdateTime);
}
- new AsyncReloadDictionaryTask().start();
}
/**
* Reloads the dictionary if required.
*/
- protected final void syncReloadDictionaryIfRequired() {
+ public final void reloadDictionaryIfRequired() {
if (!isReloadRequired()) return;
- syncReloadDictionaryInternal();
+ reloadDictionary();
}
/**
* Returns whether a dictionary reload is required.
*/
private boolean isReloadRequired() {
- return mBinaryDictionary == null || mLocalDictionaryController.isOutOfDate();
+ return mBinaryDictionary == null || mPerInstanceDictionaryTimeRecorder.isOutOfDate();
}
/**
* Reloads the dictionary. Access is controlled on a per dictionary file basis and supports
* concurrent calls from multiple instances that share the same dictionary file.
*/
- private final void syncReloadDictionaryInternal() {
+ private final void reloadDictionary() {
// Ensure that only one thread attempts to read or write to the shared binary dictionary
// file at the same time.
- mSharedDictionaryController.writeLock().lock();
- try {
- final long time = SystemClock.uptimeMillis();
- final boolean dictionaryFileExists = dictionaryFileExists();
- if (mSharedDictionaryController.isOutOfDate() || !dictionaryFileExists) {
- // If the shared dictionary file does not exist or is out of date, the first
- // instance that acquires the lock will generate a new one.
- if (hasContentChanged() || !dictionaryFileExists) {
- // If the source content has changed or the dictionary does not exist, rebuild
- // the binary dictionary. Empty dictionaries are supported (in the case where
- // loadDictionaryAsync() adds nothing) in order to provide a uniform framework.
- mSharedDictionaryController.mLastUpdateTime = time;
- generateBinaryDictionary();
+ getExecutor(mFilename).execute(new Runnable() {
+ @Override
+ public void run() {
+ final long time = SystemClock.uptimeMillis();
+ final boolean dictionaryFileExists = dictionaryFileExists();
+ if (mFilenameDictionaryTimeRecorder.isOutOfDate() || !dictionaryFileExists) {
+ // If the shared dictionary file does not exist or is out of date, the first
+ // instance that acquires the lock will generate a new one.
+ if (hasContentChanged() || !dictionaryFileExists) {
+ // If the source content has changed or the dictionary does not exist,
+ // rebuild the binary dictionary. Empty dictionaries are supported (in the
+ // case where loadDictionaryAsync() adds nothing) in order to provide a
+ // uniform framework.
+ mFilenameDictionaryTimeRecorder.mLastUpdateTime = time;
+ writeBinaryDictionary();
+ loadBinaryDictionary();
+ } else {
+ // If not, the reload request was unnecessary so revert
+ // LastUpdateRequestTime to LastUpdateTime.
+ mFilenameDictionaryTimeRecorder.mLastUpdateRequestTime =
+ mFilenameDictionaryTimeRecorder.mLastUpdateTime;
+ }
+ } else if (mBinaryDictionary == null ||
+ mPerInstanceDictionaryTimeRecorder.mLastUpdateTime
+ < mFilenameDictionaryTimeRecorder.mLastUpdateTime) {
+ // Otherwise, if the local dictionary is older than the shared dictionary, load
+ // the shared dictionary.
loadBinaryDictionary();
- } else {
- // If not, the reload request was unnecessary so revert LastUpdateRequestTime
- // to LastUpdateTime.
- mSharedDictionaryController.mLastUpdateRequestTime =
- mSharedDictionaryController.mLastUpdateTime;
}
- } else if (mBinaryDictionary == null || mLocalDictionaryController.mLastUpdateTime
- < mSharedDictionaryController.mLastUpdateTime) {
- // Otherwise, if the local dictionary is older than the shared dictionary, load the
- // shared dictionary.
- loadBinaryDictionary();
- }
- if (mBinaryDictionary != null && !mBinaryDictionary.isValidDictionary()) {
- // Binary dictionary is not valid. Regenerate the dictionary file.
- mSharedDictionaryController.mLastUpdateTime = time;
- generateBinaryDictionary();
- loadBinaryDictionary();
+ if (mBinaryDictionary != null && !mBinaryDictionary.isValidDictionary()) {
+ // Binary dictionary is not valid. Regenerate the dictionary file.
+ mFilenameDictionaryTimeRecorder.mLastUpdateTime = time;
+ writeBinaryDictionary();
+ loadBinaryDictionary();
+ }
+ mPerInstanceDictionaryTimeRecorder.mLastUpdateTime = time;
}
- mLocalDictionaryController.mLastUpdateTime = time;
- } finally {
- mSharedDictionaryController.writeLock().unlock();
- }
+ });
}
// TODO: cache the file's existence so that we avoid doing a disk access each time.
@@ -412,21 +608,38 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
- * Thread class for asynchronously reloading and rewriting the binary dictionary.
+ * Load the dictionary to memory.
*/
- private class AsyncReloadDictionaryTask extends Thread {
- @Override
- public void run() {
- syncReloadDictionaryInternal();
- }
+ protected void asyncLoadDictionaryToMemory() {
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ if (!ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ loadDictionaryAsync();
+ }
+ }
+ });
+ }
+
+ /**
+ * Generate binary dictionary using DictionaryWriter.
+ */
+ protected void asyncFlashAllBinaryDictionary() {
+ final Runnable newTask = new Runnable() {
+ @Override
+ public void run() {
+ writeBinaryDictionary();
+ }
+ };
+ final Runnable oldTask = mUnfinishedFlushingTask.getAndSet(newTask);
+ getExecutor(mFilename).replaceAndExecute(oldTask, newTask);
}
/**
- * Lock for controlling access to a given binary dictionary and for tracking whether the
- * dictionary is out of date. Can be shared across multiple dictionary instances that access the
- * same filename.
+ * Time recorder for tracking whether the dictionary is out of date.
+ * Can be shared across multiple dictionary instances that access the same filename.
*/
- private static class DictionaryController extends ReentrantReadWriteLock {
+ private static class DictionaryTimeRecorder {
private volatile long mLastUpdateTime = 0;
private volatile long mLastUpdateRequestTime = 0;
@@ -434,4 +647,75 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return (mLastUpdateRequestTime > mLastUpdateTime);
}
}
+
+ /**
+ * Dynamically adds a word unigram to the dictionary for testing with blocking-lock.
+ */
+ @UsedForTesting
+ protected void addWordDynamicallyForTests(final String word, final String shortcutTarget,
+ final int frequency, final boolean isNotAWord) {
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ addWordDynamically(word, shortcutTarget, frequency, isNotAWord);
+ }
+ });
+ }
+
+ /**
+ * Dynamically adds a word bigram in the dictionary for testing with blocking-lock.
+ */
+ @UsedForTesting
+ protected void addBigramDynamicallyForTests(final String word0, final String word1,
+ final int frequency, final boolean isValid) {
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ addBigramDynamically(word0, word1, frequency, isValid);
+ }
+ });
+ }
+
+ /**
+ * Dynamically remove a word bigram in the dictionary for testing with blocking-lock.
+ */
+ @UsedForTesting
+ protected void removeBigramDynamicallyForTests(final String word0, final String word1) {
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ removeBigramDynamically(word0, word1);
+ }
+ });
+ }
+
+ // TODO: Implement native binary methods once the dynamic dictionary implementation is done.
+ @UsedForTesting
+ public boolean isInDictionaryForTests(final String word) {
+ final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
+ getExecutor(mFilename).executePrioritized(new Runnable() {
+ @Override
+ public void run() {
+ if (mDictType == Dictionary.TYPE_USER_HISTORY) {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ holder.set(mBinaryDictionary.isValidWord(word));
+ } else {
+ holder.set(((DynamicPersonalizationDictionaryWriter) mDictionaryWriter)
+ .isInDictionaryForTests(word));
+ }
+ }
+ }
+ });
+ return holder.get(false, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
+ }
+
+ @UsedForTesting
+ public void shutdownExecutorForTests() {
+ getExecutor(mFilename).shutdown();
+ }
+
+ @UsedForTesting
+ public boolean isTerminatedForTests() {
+ return getExecutor(mFilename).isTerminated();
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index bd2d70365..d491f988a 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -16,10 +16,10 @@
package com.android.inputmethod.latin;
-import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -29,9 +29,10 @@ import java.util.ArrayList;
import java.util.LinkedList;
/**
- * Base class for an in-memory dictionary that can grow dynamically and can
+ * Class for an in-memory dictionary that can grow dynamically and can
* be searched for suggestions and valid words.
*/
+// TODO: Remove after binary dictionary supports dynamic update.
public class ExpandableDictionary extends Dictionary {
private static final String TAG = ExpandableDictionary.class.getSimpleName();
/**
@@ -39,23 +40,11 @@ public class ExpandableDictionary extends Dictionary {
*/
private static final int FULL_WORD_SCORE_MULTIPLIER = 2;
- // 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[Constants.DICTIONARY_MAX_WORD_LENGTH];
private int mMaxDepth;
private int mInputLength;
- private boolean mRequiresReload;
-
- private boolean mUpdatingDictionary;
-
- // Use this lock before touching mUpdatingDictionary & mRequiresDownload
- private Object mUpdatingLock = new Object();
-
private static final class Node {
- Node() {}
char mCode;
int mFrequency;
boolean mTerminal;
@@ -157,46 +146,12 @@ public class ExpandableDictionary extends Dictionary {
private int[][] mCodes;
- public ExpandableDictionary(final Context context, final String dictType) {
+ public ExpandableDictionary(final String dictType) {
super(dictType);
- mContext = context;
clearDictionary();
mCodes = new int[Constants.DICTIONARY_MAX_WORD_LENGTH][];
}
- public void loadDictionary() {
- synchronized (mUpdatingLock) {
- startDictionaryLoadingTaskLocked();
- }
- }
-
- public void startDictionaryLoadingTaskLocked() {
- if (!mUpdatingDictionary) {
- mUpdatingDictionary = true;
- mRequiresReload = false;
- new LoadDictionaryTask().start();
- }
- }
-
- public void setRequiresReload(final boolean reload) {
- synchronized (mUpdatingLock) {
- mRequiresReload = reload;
- }
- }
-
- public boolean getRequiresReload() {
- return mRequiresReload;
- }
-
- /** Override to load your dictionary here, on a background thread. */
- public void loadDictionaryAsync() {
- // empty base implementation
- }
-
- public Context getContext() {
- return mContext;
- }
-
public int getMaxWordLength() {
return Constants.DICTIONARY_MAX_WORD_LENGTH;
}
@@ -231,7 +186,7 @@ public class ExpandableDictionary extends Dictionary {
childNode.mShortcutOnly = isShortcutOnly;
children.add(childNode);
}
- if (wordLength == depth + 1 && shortcutTarget != null) {
+ if (wordLength == depth + 1) {
// Terminate this word
childNode.mTerminal = true;
if (isShortcutOnly) {
@@ -255,8 +210,7 @@ public class ExpandableDictionary extends Dictionary {
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
- if (reloadDictionaryIfRequired()) return null;
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
if (composer.size() > 1) {
if (composer.size() >= Constants.DICTIONARY_MAX_WORD_LENGTH) {
return null;
@@ -272,17 +226,7 @@ public class ExpandableDictionary extends Dictionary {
}
}
- // This reloads the dictionary if required, and returns whether it's currently updating its
- // contents or not.
- private boolean reloadDictionaryIfRequired() {
- synchronized (mUpdatingLock) {
- // If we need to update, start off a background task
- if (mRequiresReload) startDictionaryLoadingTaskLocked();
- return mUpdatingDictionary;
- }
- }
-
- protected ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes,
+ private ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes,
final String prevWordForBigrams, final ProximityInfo proximityInfo) {
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
mInputLength = codes.size();
@@ -312,11 +256,6 @@ public class ExpandableDictionary extends Dictionary {
@Override
public synchronized boolean isValidWord(final String word) {
- synchronized (mUpdatingLock) {
- // If we need to update, start off a background task
- if (mRequiresReload) startDictionaryLoadingTaskLocked();
- if (mUpdatingDictionary) return false;
- }
final Node node = searchNode(mRoots, word, 0, word.length());
// If node is null, we didn't find the word, so it's not valid.
// If node.mShortcutOnly is true, then it exists as a shortcut but not as a word,
@@ -326,10 +265,10 @@ public class ExpandableDictionary extends Dictionary {
return (node == null) ? false : !node.mShortcutOnly;
}
- protected boolean removeBigram(final String word1, final String word2) {
+ public boolean removeBigram(final String word0, final String word1) {
// Refer to addOrSetBigram() about word1.toLowerCase()
- final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
- final Node secondWord = searchWord(mRoots, word2, 0, null);
+ final Node firstWord = searchWord(mRoots, word0.toLowerCase(), 0, null);
+ final Node secondWord = searchWord(mRoots, word1, 0, null);
LinkedList<NextWord> bigrams = firstWord.mNGrams;
NextWord bigramNode = null;
if (bigrams == null || bigrams.size() == 0) {
@@ -351,16 +290,17 @@ public class ExpandableDictionary extends Dictionary {
/**
* Returns the word's frequency or -1 if not found
*/
- protected int getWordFrequency(final String word) {
+ @UsedForTesting
+ public int getWordFrequency(final String word) {
// Case-sensitive search
final Node node = searchNode(mRoots, word, 0, word.length());
return (node == null) ? -1 : node.mFrequency;
}
- protected NextWord getBigramWord(final String word1, final String word2) {
- // Refer to addOrSetBigram() about word1.toLowerCase()
- final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
- final Node secondWord = searchWord(mRoots, word2, 0, null);
+ public NextWord getBigramWord(final String word0, final String word1) {
+ // Refer to addOrSetBigram() about word0.toLowerCase()
+ final Node firstWord = searchWord(mRoots, word0.toLowerCase(), 0, null);
+ final Node secondWord = searchWord(mRoots, word1, 0, null);
LinkedList<NextWord> bigrams = firstWord.mNGrams;
if (bigrams == null || bigrams.size() == 0) {
return null;
@@ -403,7 +343,9 @@ public class ExpandableDictionary extends Dictionary {
// the respective size of the typed word and the suggestion if it matters sometime
// in the future.
suggestions.add(new SuggestedWordInfo(new String(word, 0, depth + 1), finalFreq,
- SuggestedWordInfo.KIND_CORRECTION, mDictType));
+ SuggestedWordInfo.KIND_CORRECTION, this /* sourceDict */,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
if (suggestions.size() >= Suggest.MAX_SUGGESTIONS) return false;
}
if (null != node.mShortcutTargets) {
@@ -411,7 +353,9 @@ public class ExpandableDictionary extends Dictionary {
for (int shortcutIndex = 0; shortcutIndex < length; ++shortcutIndex) {
final char[] shortcut = node.mShortcutTargets.get(shortcutIndex);
suggestions.add(new SuggestedWordInfo(new String(shortcut, 0, shortcut.length),
- finalFreq, SuggestedWordInfo.KIND_SHORTCUT, mDictType));
+ finalFreq, SuggestedWordInfo.KIND_SHORTCUT, this /* sourceDict */,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
if (suggestions.size() > Suggest.MAX_SUGGESTIONS) return false;
}
}
@@ -438,7 +382,7 @@ public class ExpandableDictionary extends Dictionary {
* @param suggestions the list in which to add suggestions
*/
// TODO: Share this routine with the native code for BinaryDictionary
- protected void getWordsRec(final NodeArray roots, final WordComposer codes, final char[] word,
+ private void getWordsRec(final NodeArray roots, final WordComposer codes, final char[] word,
final int depth, final boolean completion, final int snr, final int inputIndex,
final int skipPos, final ArrayList<SuggestedWordInfo> suggestions) {
final int count = roots.mLength;
@@ -531,37 +475,41 @@ public class ExpandableDictionary extends Dictionary {
}
}
- public int setBigramAndGetFrequency(final String word1, final String word2,
+ public int setBigramAndGetFrequency(final String word0, final String word1,
final int frequency) {
- return setBigramAndGetFrequency(word1, word2, frequency, null /* unused */);
+ return setBigramAndGetFrequency(word0, word1, frequency, null /* unused */);
}
- public int setBigramAndGetFrequency(final String word1, final String word2,
+ public int setBigramAndGetFrequency(final String word0, final String word1,
final ForgettingCurveParams fcp) {
- return setBigramAndGetFrequency(word1, word2, 0 /* unused */, fcp);
+ return setBigramAndGetFrequency(word0, word1, 0 /* unused */, fcp);
}
/**
* Adds bigrams to the in-memory trie structure that is being used to retrieve any word
- * @param word1 the first word of this bigram
- * @param word2 the second word of this bigram
+ * @param word0 the first word of this bigram
+ * @param word1 the second word of this bigram
* @param frequency frequency for this bigram
* @param fcp an instance of ForgettingCurveParams to use for decay policy
* @return returns the final bigram frequency
*/
- private int setBigramAndGetFrequency(final String word1, final String word2,
+ private int setBigramAndGetFrequency(final String word0, final String word1,
final int frequency, final ForgettingCurveParams fcp) {
+ if (TextUtils.isEmpty(word0)) {
+ Log.e(TAG, "Invalid bigram previous word: " + word0);
+ return frequency;
+ }
// We don't want results to be different according to case of the looked up left hand side
// word. We do want however to return the correct case for the right hand side.
// So we want to squash the case of the left hand side, and preserve that of the right
// hand side word.
- final String word1Lower = word1.toLowerCase();
- if (TextUtils.isEmpty(word1Lower) || TextUtils.isEmpty(word2)) {
- Log.e(TAG, "Invalid bigram pair: " + word1 + ", " + word1Lower + ", " + word2);
+ final String word0Lower = word0.toLowerCase();
+ if (TextUtils.isEmpty(word0Lower) || TextUtils.isEmpty(word1)) {
+ Log.e(TAG, "Invalid bigram pair: " + word0 + ", " + word0Lower + ", " + word1);
return frequency;
}
- final Node firstWord = searchWord(mRoots, word1Lower, 0, null);
- final Node secondWord = searchWord(mRoots, word2, 0, null);
+ final Node firstWord = searchWord(mRoots, word0Lower, 0, null);
+ final Node secondWord = searchWord(mRoots, word1, 0, null);
LinkedList<NextWord> bigrams = firstWord.mNGrams;
if (bigrams == null || bigrams.size() == 0) {
firstWord.mNGrams = CollectionUtils.newLinkedList();
@@ -657,7 +605,9 @@ public class ExpandableDictionary extends Dictionary {
if (freq >= 0 && node == null) {
suggestions.add(new SuggestedWordInfo(new String(mLookedUpString, index,
Constants.DICTIONARY_MAX_WORD_LENGTH - index),
- freq, SuggestedWordInfo.KIND_CORRECTION, mDictType));
+ freq, SuggestedWordInfo.KIND_CORRECTION, this /* sourceDict */,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
}
}
}
@@ -695,21 +645,10 @@ public class ExpandableDictionary extends Dictionary {
return null;
}
- protected void clearDictionary() {
+ public void clearDictionary() {
mRoots = new NodeArray();
}
- private final class LoadDictionaryTask extends Thread {
- LoadDictionaryTask() {}
- @Override
- public void run() {
- loadDictionaryAsync();
- synchronized (mUpdatingLock) {
- mUpdatingDictionary = false;
- }
- }
- }
-
private static char toLowerCase(final char c) {
char baseChar = c;
if (c < BASE_CHARS.length) {
diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java
index e96a46e12..2e638aaf3 100644
--- a/java/src/com/android/inputmethod/latin/InputPointers.java
+++ b/java/src/com/android/inputmethod/latin/InputPointers.java
@@ -105,6 +105,17 @@ public final class InputPointers {
mTimes.append(times, startPos, length);
}
+ /**
+ * Shift to the left by elementCount, discarding elementCount pointers at the start.
+ * @param elementCount how many elements to shift.
+ */
+ public void shift(final int elementCount) {
+ mXCoordinates.shift(elementCount);
+ mYCoordinates.shift(elementCount);
+ mPointerIds.shift(elementCount);
+ mTimes.shift(elementCount);
+ }
+
public void reset() {
final int defaultCapacity = mDefaultCapacity;
mXCoordinates.reset(defaultCapacity);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 5c5b7b7c0..270dc4c06 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -46,6 +46,7 @@ import android.text.InputType;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
import android.util.Log;
+import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.view.KeyCharacterMap;
@@ -73,9 +74,12 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.latin.personalization.PersonalizationDictionaryHelper;
+import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
+import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister;
+import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.PersonalizationPredictionDictionary;
import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
import com.android.inputmethod.latin.settings.Settings;
@@ -83,6 +87,7 @@ import com.android.inputmethod.latin.settings.SettingsActivity;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
import com.android.inputmethod.latin.utils.ApplicationUtils;
+import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -91,11 +96,11 @@ import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
-import com.android.inputmethod.latin.utils.PositionalInfoForUserDictPendingAddition;
import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
import com.android.inputmethod.latin.utils.TextRange;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils;
import com.android.inputmethod.research.ResearchLogger;
import java.io.FileDescriptor;
@@ -123,6 +128,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int PENDING_IMS_CALLBACK_DURATION = 800;
+ private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2;
+
+ // TODO: Set this value appropriately.
+ private static final int GET_SUGGESTED_WORDS_TIMEOUT = 200;
+
/**
* The name of the scheme used by the Package Manager to warn of a new package installation,
* replacement or removal.
@@ -171,11 +181,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private UserBinaryDictionary mUserDictionary;
private UserHistoryPredictionDictionary mUserHistoryPredictionDictionary;
private PersonalizationPredictionDictionary mPersonalizationPredictionDictionary;
+ private PersonalizationDictionary mPersonalizationDictionary;
private boolean mIsUserDictionaryAvailable;
private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
- private PositionalInfoForUserDictPendingAddition
- mPositionalInfoForUserDictPendingAddition = null;
private final WordComposer mWordComposer = new WordComposer();
private final RichInputConnection mConnection = new RichInputConnection(this);
private final RecapitalizeStatus mRecapitalizeStatus = new RecapitalizeStatus();
@@ -190,7 +199,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mExpectingUpdateSelection;
private int mDeleteCount;
private long mLastKeyTime;
- private TreeSet<Long> mCurrentlyPressedHardwareKeys = CollectionUtils.newTreeSet();
+ private final TreeSet<Long> mCurrentlyPressedHardwareKeys = CollectionUtils.newTreeSet();
+ // Personalization debugging params
+ private boolean mUseOnlyPersonalizationDictionaryForDebug = false;
+ private boolean mBoostPersonalizationDictionaryForDebug = false;
// Member variables for remembering the current device orientation.
private int mDisplayOrientation;
@@ -211,6 +223,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private final boolean mIsHardwareAcceleratedDrawingEnabled;
public final UIHandler mHandler = new UIHandler(this);
+ private InputUpdater mInputUpdater;
public static final class UIHandler extends StaticInnerHandlerWrapper<LatinIME> {
private static final int MSG_UPDATE_SHIFT_STATE = 0;
@@ -219,8 +232,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 3;
private static final int MSG_RESUME_SUGGESTIONS = 4;
private static final int MSG_REOPEN_DICTIONARIES = 5;
+ private static final int MSG_ON_END_BATCH_INPUT = 6;
+ private static final int MSG_RESET_CACHES = 7;
+ private static final int ARG1_NOT_GESTURE_INPUT = 0;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
+ private static final int ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT = 2;
+ private static final int ARG2_WITHOUT_TYPED_WORD = 0;
+ private static final int ARG2_WITH_TYPED_WORD = 1;
private int mDelayUpdateSuggestions;
private int mDelayUpdateShiftState;
@@ -253,8 +272,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
switcher.updateShiftState();
break;
case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
- latinIme.showGesturePreviewAndSuggestionStrip((SuggestedWords)msg.obj,
- msg.arg1 == ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT);
+ if (msg.arg1 == ARG1_NOT_GESTURE_INPUT) {
+ if (msg.arg2 == ARG2_WITH_TYPED_WORD) {
+ final Pair<SuggestedWords, String> p =
+ (Pair<SuggestedWords, String>) msg.obj;
+ latinIme.showSuggestionStripWithTypedWord(p.first, p.second);
+ } else {
+ latinIme.showSuggestionStrip((SuggestedWords) msg.obj);
+ }
+ } else {
+ latinIme.showGesturePreviewAndSuggestionStrip((SuggestedWords) msg.obj,
+ msg.arg1 == ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT);
+ }
break;
case MSG_RESUME_SUGGESTIONS:
latinIme.restartSuggestionsOnWordTouchedByCursor();
@@ -266,6 +295,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// get any suggestions. Wait one frame.
postUpdateSuggestionStrip();
break;
+ case MSG_ON_END_BATCH_INPUT:
+ latinIme.onEndBatchInputAsyncInternal((SuggestedWords) msg.obj);
+ break;
+ case MSG_RESET_CACHES:
+ latinIme.retryResetCaches(msg.arg1 == 1 /* tryResumeSuggestions */,
+ msg.arg2 /* remainingTries */);
+ break;
}
}
@@ -282,6 +318,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS), mDelayUpdateSuggestions);
}
+ public void postResetCaches(final boolean tryResumeSuggestions, final int remainingTries) {
+ removeMessages(MSG_RESET_CACHES);
+ sendMessage(obtainMessage(MSG_RESET_CACHES, tryResumeSuggestions ? 1 : 0,
+ remainingTries, null));
+ }
+
public void cancelUpdateSuggestionStrip() {
removeMessages(MSG_UPDATE_SUGGESTION_STRIP);
}
@@ -307,9 +349,29 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final boolean dismissGestureFloatingPreviewText) {
removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
final int arg1 = dismissGestureFloatingPreviewText
- ? ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT : 0;
- obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, arg1, 0, suggestedWords)
- .sendToTarget();
+ ? ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT
+ : ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT;
+ obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, arg1,
+ ARG2_WITHOUT_TYPED_WORD, suggestedWords).sendToTarget();
+ }
+
+ public void showSuggestionStrip(final SuggestedWords suggestedWords) {
+ removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
+ obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP,
+ ARG1_NOT_GESTURE_INPUT, ARG2_WITHOUT_TYPED_WORD, suggestedWords).sendToTarget();
+ }
+
+ // TODO: Remove this method.
+ public void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
+ final String typedWord) {
+ removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
+ obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, ARG1_NOT_GESTURE_INPUT,
+ ARG2_WITH_TYPED_WORD,
+ new Pair<SuggestedWords, String>(suggestedWords, typedWord)).sendToTarget();
+ }
+
+ public void onEndBatchInput(final SuggestedWords suggestedWords) {
+ obtainMessage(MSG_ON_END_BATCH_INPUT, suggestedWords).sendToTarget();
}
public void startDoubleSpacePeriodTimer() {
@@ -472,6 +534,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
KeyboardSwitcher.init(this);
AudioAndHapticFeedbackManager.init(this);
AccessibilityUtils.init(this);
+ PersonalizationDictionarySessionRegister.init(this);
super.onCreate();
@@ -503,6 +566,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final IntentFilter newDictFilter = new IntentFilter();
newDictFilter.addAction(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION);
registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
+
+ mInputUpdater = new InputUpdater(this);
}
// Has to be package-visible for unit tests
@@ -558,10 +623,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- mUserHistoryPredictionDictionary = PersonalizationDictionaryHelper
+ mUserHistoryPredictionDictionary = PersonalizationHelper
.getUserHistoryPredictionDictionary(this, localeStr, prefs);
newSuggest.setUserHistoryPredictionDictionary(mUserHistoryPredictionDictionary);
- mPersonalizationPredictionDictionary = PersonalizationDictionaryHelper
+ mPersonalizationDictionary = PersonalizationHelper
+ .getPersonalizationDictionary(this, localeStr, prefs);
+ newSuggest.setPersonalizationDictionary(mPersonalizationDictionary);
+ mPersonalizationPredictionDictionary = PersonalizationHelper
.getPersonalizationPredictionDictionary(this, localeStr, prefs);
newSuggest.setPersonalizationPredictionDictionary(mPersonalizationPredictionDictionary);
@@ -633,8 +701,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ResearchLogger.getInstance().onDestroy();
}
unregisterReceiver(mDictionaryPackInstallReceiver);
+ PersonalizationDictionarySessionRegister.onDestroy(this);
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
+ if (mInputUpdater != null) {
+ mInputUpdater.onDestroy();
+ mInputUpdater = null;
+ }
super.onDestroy();
}
@@ -652,6 +725,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mOptionsDialog.dismiss();
}
}
+ PersonalizationDictionarySessionRegister.onConfigurationChanged(this, conf);
super.onConfigurationChanged(conf);
}
@@ -789,7 +863,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// span, so we should reset our state unconditionally, even if restarting is true.
mEnteredText = null;
resetComposingState(true /* alsoResetLastComposedWord */);
- if (isDifferentTextField) mHandler.postResumeSuggestions();
mDeleteCount = 0;
mSpaceState = SPACE_STATE_NONE;
mRecapitalizeStatus.deactivate();
@@ -808,8 +881,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mSuggestedWords = SuggestedWords.EMPTY;
- mConnection.resetCachesUponCursorMove(editorInfo.initialSelStart,
- false /* shouldFinishComposition */);
+ // Sometimes, while rotating, for some reason the framework tells the app we are not
+ // connected to it and that means we can't refresh the cache. In this case, schedule a
+ // refresh later.
+ if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(editorInfo.initialSelStart,
+ false /* shouldFinishComposition */)) {
+ // We try resetting the caches up to 5 times before giving up.
+ mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
+ } else {
+ if (isDifferentTextField) mHandler.postResumeSuggestions();
+ }
if (isDifferentTextField) {
mainKeyboardView.closing();
@@ -836,6 +917,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mLastSelectionStart = editorInfo.initialSelStart;
mLastSelectionEnd = editorInfo.initialSelEnd;
+ // In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
+ // so we try using some heuristics to find out about these and fix them.
+ tryFixLyingCursorPosition();
mHandler.cancelUpdateSuggestionStrip();
mHandler.cancelDoubleSpacePeriodTimer();
@@ -850,22 +934,64 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
currentSettingsValues.mGestureTrailEnabled,
currentSettingsValues.mGestureFloatingPreviewTextEnabled);
- // If we have a user dictionary addition in progress, we should check now if we should
- // replace the previously committed string with the word that has actually been added
- // to the user dictionary.
- if (null != mPositionalInfoForUserDictPendingAddition
- && mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
- mConnection, editorInfo, mLastSelectionEnd, currentLocale)) {
- mPositionalInfoForUserDictPendingAddition = null;
- }
- // If tryReplaceWithActualWord returns false, we don't know what word was
- // added to the user dictionary yet, so we keep the data and defer processing. The word will
- // be replaced when the user dictionary reports back with the actual word, which ends
- // up calling #onWordAddedToUserDictionary() in this class.
+ initPersonalizationDebugSettings(currentSettingsValues);
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
+ /**
+ * Try to get the text from the editor to expose lies the framework may have been
+ * telling us. Concretely, when the device rotates, the frameworks tells us about where the
+ * cursor used to be initially in the editor at the time it first received the focus; this
+ * may be completely different from the place it is upon rotation. Since we don't have any
+ * means to get the real value, try at least to ask the text view for some characters and
+ * detect the most damaging cases: when the cursor position is declared to be much smaller
+ * than it really is.
+ */
+ private void tryFixLyingCursorPosition() {
+ final CharSequence textBeforeCursor =
+ mConnection.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
+ if (null == textBeforeCursor) {
+ mLastSelectionStart = mLastSelectionEnd = NOT_A_CURSOR_POSITION;
+ } else {
+ final int textLength = textBeforeCursor.length();
+ if (textLength > mLastSelectionStart
+ || (textLength < Constants.EDITOR_CONTENTS_CACHE_SIZE
+ && mLastSelectionStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
+ mLastSelectionStart = textLength;
+ // We can't figure out the value of mLastSelectionEnd :(
+ // But at least if it's smaller than mLastSelectionStart something is wrong
+ if (mLastSelectionStart > mLastSelectionEnd) {
+ mLastSelectionEnd = mLastSelectionStart;
+ }
+ }
+ }
+ }
+
+ // Initialization of personalization debug settings. This must be called inside
+ // onStartInputView.
+ private void initPersonalizationDebugSettings(SettingsValues currentSettingsValues) {
+ if (mUseOnlyPersonalizationDictionaryForDebug
+ != currentSettingsValues.mUseOnlyPersonalizationDictionaryForDebug) {
+ // Only for debug
+ initSuggest();
+ mUseOnlyPersonalizationDictionaryForDebug =
+ currentSettingsValues.mUseOnlyPersonalizationDictionaryForDebug;
+ }
+
+ if (mBoostPersonalizationDictionaryForDebug !=
+ currentSettingsValues.mBoostPersonalizationDictionaryForDebug) {
+ // Only for debug
+ mBoostPersonalizationDictionaryForDebug =
+ currentSettingsValues.mBoostPersonalizationDictionaryForDebug;
+ if (mBoostPersonalizationDictionaryForDebug) {
+ UserHistoryForgettingCurveUtils.boostMaxFreqForDebug();
+ } else {
+ UserHistoryForgettingCurveUtils.resetMaxFreqForDebug();
+ }
+ }
+ }
+
// Callback for the TargetPackageInfoGetterTask
@Override
public void onTargetPackageInfoKnown(final PackageInfo info) {
@@ -996,7 +1122,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// argument as true. But in all cases where we don't reset the entire input state,
// we still want to tell the rich input connection about the new cursor position so
// that it can update its caches.
- mConnection.resetCachesUponCursorMove(newSelStart,
+ mConnection.resetCachesUponCursorMoveAndReturnSuccess(newSelStart,
false /* shouldFinishComposition */);
}
@@ -1135,11 +1261,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return currentHeight;
}
- final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
- if (mainKeyboardView == null) {
+ final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
+ if (visibleKeyboardView == null) {
return 0;
}
- final int keyboardHeight = mainKeyboardView.getHeight();
+ // TODO: !!!!!!!!!!!!!!!!!!!! Handle different backing view heights between the main !!!
+ // keyboard and the emoji keyboard. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ final int keyboardHeight = visibleKeyboardView.getHeight();
final int suggestionsHeight = mSuggestionStripView.getHeight();
final int displayHeight = getResources().getDisplayMetrics().heightPixels;
final Rect rect = new Rect();
@@ -1157,8 +1285,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onComputeInsets(final InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
- final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
- if (mainKeyboardView == null || mSuggestionStripView == null) {
+ final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
+ if (visibleKeyboardView == null || mSuggestionStripView == null) {
return;
}
final int adjustedBackingHeight = getAdjustedBackingViewHeight();
@@ -1173,13 +1301,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
int visibleTopY = extraHeight;
// Need to set touchable region only if input view is being shown
- if (mainKeyboardView.isShown()) {
- if (mSuggestionStripView.getVisibility() == View.VISIBLE) {
+ if (visibleKeyboardView.isShown()) {
+ // Note that the height of Emoji layout is the same as the height of the main keyboard
+ // and the suggestion strip
+ if (mKeyboardSwitcher.isShowingEmojiKeyboard()
+ || mSuggestionStripView.getVisibility() == View.VISIBLE) {
visibleTopY -= suggestionsHeight;
}
- final int touchY = mainKeyboardView.isShowingMoreKeysPanel() ? 0 : visibleTopY;
- final int touchWidth = mainKeyboardView.getWidth();
- final int touchHeight = mainKeyboardView.getHeight() + extraHeight
+ final int touchY = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
+ final int touchWidth = visibleKeyboardView.getWidth();
+ final int touchHeight = visibleKeyboardView.getHeight() + extraHeight
// Extend touchable region below the keyboard.
+ EXTENDED_TOUCHABLE_REGION_HEIGHT;
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
@@ -1227,7 +1358,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
setSuggestedWords(settingsValues.mSuggestPuncList, false);
}
- mConnection.resetCachesUponCursorMove(newCursorPosition, shouldFinishComposition);
+ mConnection.resetCachesUponCursorMoveAndReturnSuccess(newCursorPosition,
+ shouldFinishComposition);
}
private void resetComposingState(final boolean alsoResetLastComposedWord) {
@@ -1331,7 +1463,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|| codePoint == Constants.CODE_CLOSING_PARENTHESIS
|| codePoint == Constants.CODE_CLOSING_SQUARE_BRACKET
|| codePoint == Constants.CODE_CLOSING_CURLY_BRACKET
- || codePoint == Constants.CODE_CLOSING_ANGLE_BRACKET;
+ || codePoint == Constants.CODE_CLOSING_ANGLE_BRACKET
+ || codePoint == Constants.CODE_PLUS;
}
// Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
@@ -1340,7 +1473,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void addWordToUserDictionary(final String word) {
if (TextUtils.isEmpty(word)) {
// Probably never supposed to happen, but just in case.
- mPositionalInfoForUserDictPendingAddition = null;
return;
}
final String wordToEdit;
@@ -1352,26 +1484,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mUserDictionary.addWordToUserDictionary(wordToEdit);
}
- public void onWordAddedToUserDictionary(final String newSpelling) {
- // If word was added but not by us, bail out
- if (null == mPositionalInfoForUserDictPendingAddition) return;
- if (mWordComposer.isComposingWord()) {
- // We are late... give up and return
- mPositionalInfoForUserDictPendingAddition = null;
- return;
- }
- mPositionalInfoForUserDictPendingAddition.setActualWordBeingAdded(newSpelling);
- if (mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
- mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd,
- mSubtypeSwitcher.getCurrentSubtypeLocale())) {
- mPositionalInfoForUserDictPendingAddition = null;
- }
- }
-
- private static boolean isAlphabet(final int code) {
- return Character.isLetter(code);
- }
-
private void onSettingsKeyPressed() {
if (isShowingOptionDialog()) return;
showSubtypeSelectorAndSettings();
@@ -1479,7 +1591,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
case Constants.CODE_SHIFT:
// Note: Calling back to the keyboard on Shift key is handled in
- // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}.
+ // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
final Keyboard currentKeyboard = switcher.getKeyboard();
if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
// TODO: Instead of checking for alphabetic keyboard here, separate keycodes for
@@ -1493,7 +1605,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
case Constants.CODE_SWITCH_ALPHA_SYMBOL:
// Note: Calling back to the keyboard on symbol key is handled in
- // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}.
+ // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
break;
case Constants.CODE_SETTINGS:
onSettingsKeyPressed();
@@ -1511,7 +1623,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
handleLanguageSwitchKey();
break;
case Constants.CODE_EMOJI:
- // TODO: Implement emoji keyboard switch.
+ // Note: Switching emoji keyboard is being handled in
+ // {@link KeyboardState#onCodeInput(int,int)}.
break;
case Constants.CODE_ENTER:
final EditorInfo editorInfo = getCurrentInputEditorInfo();
@@ -1627,7 +1740,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onStartBatchInput() {
- BatchInputUpdater.getInstance().onStartBatchInput(this);
+ mInputUpdater.onStartBatchInput();
mHandler.cancelUpdateSuggestionStrip();
mConnection.beginBatchEdit();
final SettingsValues settingsValues = mSettings.getCurrent();
@@ -1667,46 +1780,41 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.setCapitalizedModeAtStartComposingTime(getActualCapsMode());
}
- private static final class BatchInputUpdater implements Handler.Callback {
+ private static final class InputUpdater implements Handler.Callback {
private final Handler mHandler;
- private LatinIME mLatinIme;
+ private final LatinIME mLatinIme;
private final Object mLock = new Object();
private boolean mInBatchInput; // synchronized using {@link #mLock}.
- private BatchInputUpdater() {
+ private InputUpdater(final LatinIME latinIme) {
final HandlerThread handlerThread = new HandlerThread(
- BatchInputUpdater.class.getSimpleName());
+ InputUpdater.class.getSimpleName());
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper(), this);
- }
-
- // Initialization-on-demand holder
- private static final class OnDemandInitializationHolder {
- public static final BatchInputUpdater sInstance = new BatchInputUpdater();
- }
-
- public static BatchInputUpdater getInstance() {
- return OnDemandInitializationHolder.sInstance;
+ mLatinIme = latinIme;
}
private static final int MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 1;
+ private static final int MSG_GET_SUGGESTED_WORDS = 2;
@Override
public boolean handleMessage(final Message msg) {
switch (msg.what) {
- case MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
- updateBatchInput((InputPointers)msg.obj);
- break;
+ case MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
+ updateBatchInput((InputPointers)msg.obj);
+ break;
+ case MSG_GET_SUGGESTED_WORDS:
+ mLatinIme.getSuggestedWords(msg.arg1, (OnGetSuggestedWordsCallback) msg.obj);
+ break;
}
return true;
}
// Run in the UI thread.
- public void onStartBatchInput(final LatinIME latinIme) {
+ public void onStartBatchInput() {
synchronized (mLock) {
mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
mInBatchInput = true;
- mLatinIme = latinIme;
mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
SuggestedWords.EMPTY, false /* dismissGestureFloatingPreviewText */);
}
@@ -1719,9 +1827,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Batch input has ended or canceled while the message was being delivered.
return;
}
- final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers);
- mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
- suggestedWords, false /* dismissGestureFloatingPreviewText */);
+
+ getSuggestedWordsGestureLocked(batchPointers, new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
+ mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
+ suggestedWords, false /* dismissGestureFloatingPreviewText */);
+ }
+ });
}
}
@@ -1744,35 +1857,57 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// Run in the UI thread.
- public SuggestedWords onEndBatchInput(final InputPointers batchPointers) {
- synchronized (mLock) {
- mInBatchInput = false;
- final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers);
- mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
- suggestedWords, true /* dismissGestureFloatingPreviewText */);
- return suggestedWords;
+ public void onEndBatchInput(final InputPointers batchPointers) {
+ synchronized(mLock) {
+ getSuggestedWordsGestureLocked(batchPointers, new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
+ mInBatchInput = false;
+ mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(suggestedWords,
+ true /* dismissGestureFloatingPreviewText */);
+ mLatinIme.mHandler.onEndBatchInput(suggestedWords);
+ }
+ });
}
}
// {@link LatinIME#getSuggestedWords(int)} method calls with same session id have to
// be synchronized.
- private SuggestedWords getSuggestedWordsGestureLocked(final InputPointers batchPointers) {
+ private void getSuggestedWordsGestureLocked(final InputPointers batchPointers,
+ final OnGetSuggestedWordsCallback callback) {
mLatinIme.mWordComposer.setBatchInputPointers(batchPointers);
- final SuggestedWords suggestedWords =
- mLatinIme.getSuggestedWordsOrOlderSuggestions(Suggest.SESSION_GESTURE);
- final int suggestionCount = suggestedWords.size();
- if (suggestionCount <= 1) {
- final String mostProbableSuggestion = (suggestionCount == 0) ? null
- : suggestedWords.getWord(0);
- return mLatinIme.getOlderSuggestions(mostProbableSuggestion);
- }
- return suggestedWords;
+ mLatinIme.getSuggestedWordsOrOlderSuggestionsAsync(Suggest.SESSION_GESTURE,
+ new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(SuggestedWords suggestedWords) {
+ final int suggestionCount = suggestedWords.size();
+ if (suggestionCount <= 1) {
+ final String mostProbableSuggestion = (suggestionCount == 0) ? null
+ : suggestedWords.getWord(0);
+ callback.onGetSuggestedWords(
+ mLatinIme.getOlderSuggestions(mostProbableSuggestion));
+ }
+ callback.onGetSuggestedWords(suggestedWords);
+ }
+ });
+ }
+
+ public void getSuggestedWords(final int sessionId,
+ final OnGetSuggestedWordsCallback callback) {
+ mHandler.obtainMessage(MSG_GET_SUGGESTED_WORDS, sessionId, 0, callback).sendToTarget();
+ }
+
+ private void onDestroy() {
+ mHandler.removeMessages(MSG_GET_SUGGESTED_WORDS);
+ mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
+ mHandler.getLooper().quit();
}
}
+ // This method must run in UI Thread.
private void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
final boolean dismissGestureFloatingPreviewText) {
- showSuggestionStrip(suggestedWords, null);
+ showSuggestionStrip(suggestedWords);
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
mainKeyboardView.showGestureFloatingPreviewText(suggestedWords);
if (dismissGestureFloatingPreviewText) {
@@ -1782,24 +1917,48 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onUpdateBatchInput(final InputPointers batchPointers) {
- BatchInputUpdater.getInstance().onUpdateBatchInput(batchPointers);
+ if (mSettings.getCurrent().mPhraseGestureEnabled) {
+ final SuggestedWordInfo candidate = mSuggestedWords.getAutoCommitCandidate();
+ if (null != candidate) {
+ if (candidate.mSourceDict.shouldAutoCommit(candidate)) {
+ final String[] commitParts = candidate.mWord.split(" ", 2);
+ batchPointers.shift(candidate.mIndexOfTouchPointOfSecondWord);
+ promotePhantomSpace();
+ mConnection.commitText(commitParts[0], 0);
+ mSpaceState = SPACE_STATE_PHANTOM;
+ mKeyboardSwitcher.updateShiftState();
+ mWordComposer.setCapitalizedModeAtStartComposingTime(getActualCapsMode());
+ }
+ }
+ }
+ mInputUpdater.onUpdateBatchInput(batchPointers);
}
- @Override
- public void onEndBatchInput(final InputPointers batchPointers) {
- final SuggestedWords suggestedWords = BatchInputUpdater.getInstance().onEndBatchInput(
- batchPointers);
+ // This method must run in UI Thread.
+ public void onEndBatchInputAsyncInternal(final SuggestedWords suggestedWords) {
final String batchInputText = suggestedWords.isEmpty()
? null : suggestedWords.getWord(0);
if (TextUtils.isEmpty(batchInputText)) {
return;
}
- mWordComposer.setBatchInputWord(batchInputText);
mConnection.beginBatchEdit();
if (SPACE_STATE_PHANTOM == mSpaceState) {
promotePhantomSpace();
}
- mConnection.setComposingText(batchInputText, 1);
+ if (mSettings.getCurrent().mPhraseGestureEnabled) {
+ // Find the last space
+ final int indexOfLastSpace = batchInputText.lastIndexOf(Constants.CODE_SPACE) + 1;
+ if (0 != indexOfLastSpace) {
+ mConnection.commitText(batchInputText.substring(0, indexOfLastSpace), 1);
+ showSuggestionStrip(suggestedWords.getSuggestedWordsForLastWordOfPhraseGesture());
+ }
+ final String lastWord = batchInputText.substring(indexOfLastSpace);
+ mWordComposer.setBatchInputWord(lastWord);
+ mConnection.setComposingText(lastWord, 1);
+ } else {
+ mWordComposer.setBatchInputWord(batchInputText);
+ mConnection.setComposingText(batchInputText, 1);
+ }
mExpectingUpdateSelection = true;
mConnection.endBatchEdit();
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -1810,6 +1969,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mKeyboardSwitcher.updateShiftState();
}
+ @Override
+ public void onEndBatchInput(final InputPointers batchPointers) {
+ mInputUpdater.onEndBatchInput(batchPointers);
+ }
+
private String specificTldProcessingOnTextInput(final String text) {
if (text.length() <= 1 || text.charAt(0) != Constants.CODE_PERIOD
|| !Character.isLetter(text.charAt(1))) {
@@ -1845,7 +2009,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onCancelBatchInput() {
- BatchInputUpdater.getInstance().onCancelBatchInput();
+ mInputUpdater.onCancelBatchInput();
}
private void handleBackspace(final int spaceState) {
@@ -1861,23 +2025,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// When we exit this if-clause, mWordComposer.isComposingWord() will return false.
}
if (mWordComposer.isComposingWord()) {
- final int length = mWordComposer.size();
- if (length > 0) {
- if (mWordComposer.isBatchMode()) {
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- final String word = mWordComposer.getTypedWord();
- ResearchLogger.latinIME_handleBackspace_batch(word, 1);
- }
- final String rejectedSuggestion = mWordComposer.getTypedWord();
- mWordComposer.reset();
- mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
- } else {
- mWordComposer.deleteLast();
+ if (mWordComposer.isBatchMode()) {
+ if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+ final String word = mWordComposer.getTypedWord();
+ ResearchLogger.latinIME_handleBackspace_batch(word, 1);
}
- mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
- mHandler.postUpdateSuggestionStrip();
+ final String rejectedSuggestion = mWordComposer.getTypedWord();
+ mWordComposer.reset();
+ mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
} else {
- mConnection.deleteSurroundingText(1, 0);
+ mWordComposer.deleteLast();
+ }
+ mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
+ mHandler.postUpdateSuggestionStrip();
+ if (!mWordComposer.isComposingWord()) {
+ // If we just removed the last character, auto-caps mode may have changed so we
+ // need to re-evaluate.
+ mKeyboardSwitcher.updateShiftState();
}
} else {
final SettingsValues currentSettings = mSettings.getCurrent();
@@ -1892,8 +2056,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Cancel multi-character input: remove the text we just entered.
// This is triggered on backspace after a key that inputs multiple characters,
// like the smiley key or the .com key.
- final int length = mEnteredText.length();
- mConnection.deleteSurroundingText(length, 0);
+ mConnection.deleteSurroundingText(mEnteredText.length(), 0);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_handleBackspace_cancelTextInput(mEnteredText);
}
@@ -1939,6 +2102,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// This should never happen.
Log.e(TAG, "Backspace when we don't know the selection position");
}
+ final int lengthToDelete = Character.isSupplementaryCodePoint(
+ mConnection.getCodePointBeforeCursor()) ? 2 : 1;
if (mAppWorkAroundsUtils.isBeforeJellyBean()) {
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
// a hardware keyboard event on pressing enter or delete. This is bad for many
@@ -1946,22 +2111,28 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// relying on this behavior so we continue to support it for older apps.
sendDownUpKeyEventForBackwardCompatibility(KeyEvent.KEYCODE_DEL);
} else {
- mConnection.deleteSurroundingText(1, 0);
+ mConnection.deleteSurroundingText(lengthToDelete, 0);
}
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleBackspace(1, true /* shouldUncommitLogUnit */);
+ ResearchLogger.latinIME_handleBackspace(lengthToDelete,
+ true /* shouldUncommitLogUnit */);
}
if (mDeleteCount > DELETE_ACCELERATE_AT) {
- mConnection.deleteSurroundingText(1, 0);
+ final int lengthToDeleteAgain = Character.isSupplementaryCodePoint(
+ mConnection.getCodePointBeforeCursor()) ? 2 : 1;
+ mConnection.deleteSurroundingText(lengthToDeleteAgain, 0);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleBackspace(1,
+ ResearchLogger.latinIME_handleBackspace(lengthToDeleteAgain,
true /* shouldUncommitLogUnit */);
}
}
}
- if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
+ if (currentSettings.isSuggestionsRequested(mDisplayOrientation)
+ && currentSettings.mCurrentLanguageHasSpaces) {
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord();
}
+ // We just removed a character. We need to update the auto-caps state.
+ mKeyboardSwitcher.updateShiftState();
}
}
@@ -1986,6 +2157,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void handleCharacter(final int primaryCode, final int x,
final int y, final int spaceState) {
+ // TODO: refactor this method to stop flipping isComposingWord around all the time, and
+ // make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter
+ // which has the same name as other handle* methods but is not the same.
boolean isComposingWord = mWordComposer.isComposingWord();
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
@@ -2005,18 +2179,26 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
resetEntireInputState(mLastSelectionStart);
isComposingWord = false;
}
- // NOTE: isCursorTouchingWord() is a blocking IPC call, so it often takes several
- // dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
- // thread here.
- if (!isComposingWord && (isAlphabet(primaryCode)
- || currentSettings.isWordConnector(primaryCode))
+ // We want to find out whether to start composing a new word with this character. If so,
+ // we need to reset the composing state and switch isComposingWord. The order of the
+ // tests is important for good performance.
+ // We only start composing if we're not already composing.
+ if (!isComposingWord
+ // We only start composing if this is a word code point. Essentially that means it's a
+ // a letter or a word connector.
+ && currentSettings.isWordCodePoint(primaryCode)
+ // We never go into composing state if suggestions are not requested.
&& currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
- !mConnection.isCursorTouchingWord(currentSettings)) {
+ // In languages with spaces, we only start composing a word when we are not already
+ // touching a word. In languages without spaces, the above conditions are sufficient.
+ (!mConnection.isCursorTouchingWord(currentSettings)
+ || !currentSettings.mCurrentLanguageHasSpaces)) {
// Reset entirely the composing state anyway, then start composing a new word unless
- // the character is a single quote. The idea here is, single quote is not a
- // separator and it should be treated as a normal character, except in the first
- // position where it should not start composing a word.
- isComposingWord = (Constants.CODE_SINGLE_QUOTE != primaryCode);
+ // the character is a single quote or a dash. The idea here is, single quote and dash
+ // are not separators and they should be treated as normal characters, except in the
+ // first position where they should not start composing a word.
+ isComposingWord = (Constants.CODE_SINGLE_QUOTE != primaryCode
+ && Constants.CODE_DASH != primaryCode);
// Here we don't need to reset the last composed word. It will be reset
// when we commit this one, if we ever do; if on the other hand we backspace
// it entirely and resume suggestions on the previous word, we'd like to still
@@ -2095,20 +2277,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mKeyboardSwitcher.updateShiftState();
}
- // Returns true if we did an autocorrection, false otherwise.
+ // Returns true if we do an autocorrection, false otherwise.
private boolean handleSeparator(final int primaryCode, final int x, final int y,
final int spaceState) {
boolean didAutoCorrect = false;
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ // We avoid sending spaces in languages without spaces if we were composing.
+ final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == primaryCode
+ && !currentSettings.mCurrentLanguageHasSpaces && mWordComposer.isComposingWord();
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the separator at the current cursor position.
resetEntireInputState(mLastSelectionStart);
}
- final SettingsValues currentSettings = mSettings.getCurrent();
- if (mWordComposer.isComposingWord()) {
+ if (mWordComposer.isComposingWord()) { // May have changed since we stored wasComposing
if (currentSettings.mCorrectionEnabled) {
- // TODO: maybe cache Strings in an <String> sparse array or something
- commitCurrentAutoCorrection(new String(new int[]{primaryCode}, 0, 1));
+ final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
+ : new String(new int[] { primaryCode }, 0, 1);
+ commitCurrentAutoCorrection(separator);
didAutoCorrect = true;
} else {
commitTyped(new String(new int[]{primaryCode}, 0, 1));
@@ -2125,7 +2311,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_handleSeparator(primaryCode, mWordComposer.isComposingWord());
}
- sendKeyCodePoint(primaryCode);
+
+ if (!shouldAvoidSendingCode) {
+ sendKeyCodePoint(primaryCode);
+ }
if (Constants.CODE_SPACE == primaryCode) {
if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
@@ -2255,34 +2444,60 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
- final SuggestedWords suggestedWords =
- getSuggestedWordsOrOlderSuggestions(Suggest.SESSION_TYPING);
- final String typedWord = mWordComposer.getTypedWord();
- showSuggestionStrip(suggestedWords, typedWord);
+ final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<SuggestedWords>();
+ getSuggestedWordsOrOlderSuggestionsAsync(Suggest.SESSION_TYPING,
+ new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
+ holder.set(suggestedWords);
+ }
+ }
+ );
+
+ // This line may cause the current thread to wait.
+ final SuggestedWords suggestedWords = holder.get(null, GET_SUGGESTED_WORDS_TIMEOUT);
+ if (suggestedWords != null) {
+ showSuggestionStrip(suggestedWords);
+ }
}
- private SuggestedWords getSuggestedWords(final int sessionId) {
+ private void getSuggestedWords(final int sessionId,
+ final OnGetSuggestedWordsCallback callback) {
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
final Suggest suggest = mSuggest;
if (keyboard == null || suggest == null) {
- return SuggestedWords.EMPTY;
+ callback.onGetSuggestedWords(SuggestedWords.EMPTY);
+ return;
}
// Get the word on which we should search the bigrams. If we are composing a word, it's
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
// should just skip whitespace if any, so 1.
- // TODO: this is slow (2-way IPC) - we should probably cache this instead.
final SettingsValues currentSettings = mSettings.getCurrent();
- final String prevWord =
- mConnection.getNthPreviousWord(currentSettings.mWordSeparators,
- mWordComposer.isComposingWord() ? 2 : 1);
- return suggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
- currentSettings.mBlockPotentiallyOffensive,
- currentSettings.mCorrectionEnabled, sessionId);
+ final int[] additionalFeaturesOptions = currentSettings.mAdditionalFeaturesSettingValues;
+ final String prevWord;
+ if (currentSettings.mCurrentLanguageHasSpaces) {
+ // If we are typing in a language with spaces we can just look up the previous
+ // word from textview.
+ prevWord = mConnection.getNthPreviousWord(currentSettings.mWordSeparators,
+ mWordComposer.isComposingWord() ? 2 : 1);
+ } else {
+ prevWord = LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? null
+ : mLastComposedWord.mCommittedWord;
+ }
+ suggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
+ currentSettings.mBlockPotentiallyOffensive, currentSettings.mCorrectionEnabled,
+ additionalFeaturesOptions, sessionId, callback);
}
- private SuggestedWords getSuggestedWordsOrOlderSuggestions(final int sessionId) {
- return maybeRetrieveOlderSuggestions(mWordComposer.getTypedWord(),
- getSuggestedWords(sessionId));
+ private void getSuggestedWordsOrOlderSuggestionsAsync(final int sessionId,
+ final OnGetSuggestedWordsCallback callback) {
+ mInputUpdater.getSuggestedWords(sessionId, new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(SuggestedWords suggestedWords) {
+ callback.onGetSuggestedWords(maybeRetrieveOlderSuggestions(
+ mWordComposer.getTypedWord(), suggestedWords));
+ }
+ });
}
private SuggestedWords maybeRetrieveOlderSuggestions(final String typedWord,
@@ -2322,25 +2537,42 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
false /* isPrediction */);
}
- private void showSuggestionStrip(final SuggestedWords suggestedWords, final String typedWord) {
- if (suggestedWords.isEmpty()) {
- clearSuggestionStrip();
- return;
- }
+ private void setAutoCorrection(final SuggestedWords suggestedWords, final String typedWord) {
+ if (suggestedWords.isEmpty()) return;
final String autoCorrection;
if (suggestedWords.mWillAutoCorrect) {
- autoCorrection = suggestedWords.getWord(1);
+ autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
} else {
+ // We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD)
+ // because it may differ from mWordComposer.mTypedWord.
autoCorrection = typedWord;
}
mWordComposer.setAutoCorrection(autoCorrection);
- final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
- setSuggestedWords(suggestedWords, isAutoCorrection);
- setAutoCorrectionIndicator(isAutoCorrection);
- setSuggestionStripShown(isSuggestionsStripVisible());
}
- private void commitCurrentAutoCorrection(final String separatorString) {
+ private void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
+ final String typedWord) {
+ if (suggestedWords.isEmpty()) {
+ clearSuggestionStrip();
+ return;
+ }
+ setAutoCorrection(suggestedWords, typedWord);
+ final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
+ setSuggestedWords(suggestedWords, isAutoCorrection);
+ setAutoCorrectionIndicator(isAutoCorrection);
+ setSuggestionStripShown(isSuggestionsStripVisible());
+ }
+
+ private void showSuggestionStrip(final SuggestedWords suggestedWords) {
+ if (suggestedWords.isEmpty()) {
+ clearSuggestionStrip();
+ return;
+ }
+ showSuggestionStripWithTypedWord(suggestedWords,
+ suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD));
+ }
+
+ private void commitCurrentAutoCorrection(final String separator) {
// Complete any pending suggestions query first
if (mHandler.hasPendingUpdateSuggestions()) {
updateSuggestionStrip();
@@ -2356,16 +2588,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
if (mSettings.isInternal()) {
LatinImeLoggerUtils.onAutoCorrection(
- typedWord, autoCorrection, separatorString, mWordComposer);
+ typedWord, autoCorrection, separator, mWordComposer);
}
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
final SuggestedWords suggestedWords = mSuggestedWords;
ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection,
- separatorString, mWordComposer.isBatchMode(), suggestedWords);
+ separator, mWordComposer.isBatchMode(), suggestedWords);
}
mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
- separatorString);
+ separator);
if (!typedWord.equals(autoCorrection)) {
// This will make the correction flash for a short while as a visual clue
// to the user that auto-correction happened. It has no other effect; in particular
@@ -2440,7 +2672,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion,
mWordComposer.isBatchMode(), suggestionInfo.mScore, suggestionInfo.mKind,
- suggestionInfo.mSourceDict);
+ suggestionInfo.mSourceDict.mDictType);
}
mConnection.endBatchEdit();
// Don't allow cancellation of manual pick
@@ -2535,6 +2767,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return prevWord;
}
+ private boolean isResumableWord(final String word, final SettingsValues settings) {
+ final int firstCodePoint = word.codePointAt(0);
+ return settings.isWordCodePoint(firstCodePoint)
+ && Constants.CODE_SINGLE_QUOTE != firstCodePoint
+ && Constants.CODE_DASH != firstCodePoint;
+ }
+
/**
* Check if the cursor is touching a word. If so, restart suggestions on this word, else
* do nothing.
@@ -2544,6 +2783,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// recorrection. This is a temporary, stopgap measure that will be removed later.
// TODO: remove this.
if (mAppWorkAroundsUtils.isBrokenByRecorrection()) return;
+ // A simple way to test for support from the TextView.
+ if (!isSuggestionsStripVisible()) return;
+ // Recorrection is not supported in languages without spaces because we don't know
+ // how to segment them yet.
+ if (!mSettings.getCurrent().mCurrentLanguageHasSpaces) return;
// If the cursor is not touching a word, or if there is a selection, return right away.
if (mLastSelectionStart != mLastSelectionEnd) return;
// If we don't know the cursor location, return.
@@ -2553,12 +2797,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final TextRange range = mConnection.getWordRangeAtCursor(currentSettings.mWordSeparators,
0 /* additionalPrecedingWordsCount */);
if (null == range) return; // Happens if we don't have an input connection at all
+ if (range.length() <= 0) return; // Race condition. No text to resume on, so bail out.
// If for some strange reason (editor bug or so) we measure the text before the cursor as
// longer than what the entire text is supposed to be, the safe thing to do is bail out.
final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor();
if (numberOfCharsInWordBeforeCursor > mLastSelectionStart) return;
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
final String typedWord = range.mWord.toString();
+ if (!isResumableWord(typedWord, currentSettings)) return;
int i = 0;
for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) {
for (final String s : span.getSuggestions()) {
@@ -2566,51 +2812,69 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (!TextUtils.equals(s, typedWord)) {
suggestions.add(new SuggestedWordInfo(s,
SuggestionStripView.MAX_SUGGESTIONS - i,
- SuggestedWordInfo.KIND_RESUMED, Dictionary.TYPE_RESUMED));
+ SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE
+ /* autoCommitFirstWordConfidence */));
}
}
}
mWordComposer.setComposingWord(typedWord, mKeyboardSwitcher.getKeyboard());
- // TODO: this is in chars but the callee expects code points!
- mWordComposer.setCursorPositionWithinWord(numberOfCharsInWordBeforeCursor);
+ mWordComposer.setCursorPositionWithinWord(
+ typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor));
mConnection.setComposingRegion(
mLastSelectionStart - numberOfCharsInWordBeforeCursor,
mLastSelectionEnd + range.getNumberOfCharsInWordAfterCursor());
- final SuggestedWords suggestedWords;
if (suggestions.isEmpty()) {
// We come here if there weren't any suggestion spans on this word. We will try to
// compute suggestions for it instead.
- final SuggestedWords suggestedWordsIncludingTypedWord =
- getSuggestedWords(Suggest.SESSION_TYPING);
- if (suggestedWordsIncludingTypedWord.size() > 1) {
- // We were able to compute new suggestions for this word.
- // Remove the typed word, since we don't want to display it in this case.
- // The #getSuggestedWordsExcludingTypedWord() method sets willAutoCorrect to false.
- suggestedWords =
- suggestedWordsIncludingTypedWord.getSuggestedWordsExcludingTypedWord();
- } else {
- // No saved suggestions, and we were unable to compute any good one either.
- // Rather than displaying an empty suggestion strip, we'll display the original
- // word alone in the middle.
- // Since there is only one word, willAutoCorrect is false.
- suggestedWords = suggestedWordsIncludingTypedWord;
- }
+ mInputUpdater.getSuggestedWords(Suggest.SESSION_TYPING,
+ new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(
+ final SuggestedWords suggestedWordsIncludingTypedWord) {
+ final SuggestedWords suggestedWords;
+ if (suggestedWordsIncludingTypedWord.size() > 1) {
+ // We were able to compute new suggestions for this word.
+ // Remove the typed word, since we don't want to display it in this case.
+ // The #getSuggestedWordsExcludingTypedWord() method sets willAutoCorrect to
+ // false.
+ suggestedWords = suggestedWordsIncludingTypedWord
+ .getSuggestedWordsExcludingTypedWord();
+ } else {
+ // No saved suggestions, and we were unable to compute any good one either.
+ // Rather than displaying an empty suggestion strip, we'll display the
+ // original word alone in the middle.
+ // Since there is only one word, willAutoCorrect is false.
+ suggestedWords = suggestedWordsIncludingTypedWord;
+ }
+ // We need to pass typedWord because mWordComposer.mTypedWord may differ from
+ // typedWord.
+ unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords,
+ typedWord);
+ }});
} else {
// We found suggestion spans in the word. We'll create the SuggestedWords out of
// them, and make willAutoCorrect false.
- suggestedWords = new SuggestedWords(suggestions,
+ final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
true /* typedWordValid */, false /* willAutoCorrect */,
false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
false /* isPrediction */);
+ // We need to pass typedWord because mWordComposer.mTypedWord may differ from typedWord.
+ unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords, typedWord);
}
+ }
+ public void unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(
+ final SuggestedWords suggestedWords, final String typedWord) {
// Note that it's very important here that suggestedWords.mWillAutoCorrect is false.
- // We never want to auto-correct on a resumed suggestion. Please refer to the three
- // places above where suggestedWords is affected. We also need to reset
- // mIsAutoCorrectionIndicatorOn to avoid showSuggestionStrip touching the text to adapt it.
- // TODO: remove mIsAutoCorrectionIndicator on (see comment on definition)
+ // We never want to auto-correct on a resumed suggestion. Please refer to the three places
+ // above in restartSuggestionsOnWordTouchedByCursor() where suggestedWords is affected.
+ // We also need to unset mIsAutoCorrectionIndicatorOn to avoid showSuggestionStrip touching
+ // the text to adapt it.
+ // TODO: remove mIsAutoCorrectionIndicatorOn (see comment on definition)
mIsAutoCorrectionIndicatorOn = false;
- showSuggestionStrip(suggestedWords, typedWord);
+ mHandler.showSuggestionStripWithTypedWord(suggestedWords, typedWord);
}
/**
@@ -2640,6 +2904,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateSuggestionStrip();
}
+ /**
+ * Retry resetting caches in the rich input connection.
+ *
+ * When the editor can't be accessed we can't reset the caches, so we schedule a retry.
+ * This method handles the retry, and re-schedules a new retry if we still can't access.
+ * We only retry up to 5 times before giving up.
+ *
+ * @param tryResumeSuggestions Whether we should resume suggestions or not.
+ * @param remainingTries How many times we may try again before giving up.
+ */
+ private void retryResetCaches(final boolean tryResumeSuggestions, final int remainingTries) {
+ if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(mLastSelectionStart, false)) {
+ if (0 < remainingTries) {
+ mHandler.postResetCaches(tryResumeSuggestions, remainingTries - 1);
+ }
+ return;
+ }
+ tryFixLyingCursorPosition();
+ if (tryResumeSuggestions) mHandler.postResumeSuggestions();
+ }
+
private void revertCommit() {
final String previousWord = mLastComposedWord.mPrevWord;
final String originallyTypedWord = mLastComposedWord.mTypedWord;
@@ -2666,7 +2951,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
mUserHistoryPredictionDictionary.cancelAddingUserHistory(previousWord, committedWord);
}
- mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
+ final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
+ if (mSettings.getCurrent().mCurrentLanguageHasSpaces) {
+ // For languages with spaces, we revert to the typed string, but the cursor is still
+ // after the separator so we don't resume suggestions. If the user wants to correct
+ // the word, they have to press backspace again.
+ mConnection.commitText(stringToCommit, 1);
+ } else {
+ // For languages without spaces, we revert the typed string but the cursor is flush
+ // with the typed word, so we need to resume suggestions right away.
+ mWordComposer.setComposingWord(stringToCommit, mKeyboardSwitcher.getKeyboard());
+ mConnection.setComposingText(stringToCommit, 1);
+ }
if (mSettings.isInternal()) {
LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
@@ -2684,7 +2980,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// This essentially inserts a space, and that's it.
public void promotePhantomSpace() {
- if (mSettings.getCurrent().shouldInsertSpacesAutomatically()
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ if (currentSettings.shouldInsertSpacesAutomatically()
+ && currentSettings.mCurrentLanguageHasSpaces
&& !mConnection.textBeforeCursorLooksLikeURL()) {
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_promotePhantomSpace();
@@ -2710,30 +3008,43 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void hapticAndAudioFeedback(final int code, final boolean isRepeatKey) {
+ private void hapticAndAudioFeedback(final int code, final int repeatCount) {
final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (keyboardView != null && keyboardView.isInSlidingKeyInput()) {
// No need to feedback while sliding input.
return;
}
- if (isRepeatKey && code == Constants.CODE_DELETE && !mConnection.canDeleteCharacters()) {
- // No need to feedback when repeating delete key will have no effect.
- return;
+ if (repeatCount > 0) {
+ if (code == Constants.CODE_DELETE && !mConnection.canDeleteCharacters()) {
+ // No need to feedback when repeat delete key will have no effect.
+ return;
+ }
+ // TODO: Use event time that the last feedback has been generated instead of relying on
+ // a repeat count to thin out feedback.
+ if (repeatCount % PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT == 0) {
+ return;
+ }
+ }
+ final AudioAndHapticFeedbackManager feedbackManager =
+ AudioAndHapticFeedbackManager.getInstance();
+ if (repeatCount == 0) {
+ // TODO: Reconsider how to perform haptic feedback when repeating key.
+ feedbackManager.performHapticFeedback(keyboardView);
}
- AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(code, keyboardView);
+ feedbackManager.performAudioFeedback(code);
}
// Callback of the {@link KeyboardActionListener}. This is called when a key is depressed;
// release matching call is {@link #onReleaseKey(int,boolean)} below.
@Override
- public void onPressKey(final int primaryCode, final boolean isRepeatKey,
+ public void onPressKey(final int primaryCode, final int repeatCount,
final boolean isSinglePointer) {
mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer);
- hapticAndAudioFeedback(primaryCode, isRepeatKey);
+ hapticAndAudioFeedback(primaryCode, repeatCount);
}
// Callback of the {@link KeyboardActionListener}. This is called when a key is released;
- // press matching call is {@link #onPressKey(int,boolean,boolean)} above.
+ // press matching call is {@link #onPressKey(int,int,boolean)} above.
@Override
public void onReleaseKey(final int primaryCode, final boolean withSliding) {
mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding);
@@ -2749,17 +3060,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
}
}
-
- if (Constants.CODE_DELETE == primaryCode) {
- // This is a stopgap solution to avoid leaving a high surrogate alone in a text view.
- // In the future, we need to deprecate deteleSurroundingText() and have a surrogate
- // pair-friendly way of deleting characters in InputConnection.
- // TODO: use getCodePointBeforeCursor instead to improve performance
- final CharSequence lastChar = mConnection.getTextBeforeCursor(1, 0);
- if (!TextUtils.isEmpty(lastChar) && Character.isHighSurrogate(lastChar.charAt(0))) {
- mConnection.deleteSurroundingText(1, 0);
- }
- }
}
// Hooks for hardware keyboard
@@ -2895,6 +3195,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mSuggest.hasMainDictionary();
}
+ // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
+ @UsedForTesting
+ /* package for test */ void replaceMainDictionaryForTest(final Locale locale) {
+ mSuggest.resetMainDict(this, locale, null);
+ }
+
public void debugDumpStateAndCrashWithException(final String context) {
final StringBuilder s = new StringBuilder(mAppWorkAroundsUtils.toString());
s.append("\nAttributes : ").append(mSettings.getCurrent().mInputAttributes)
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 35920f8cb..925381b50 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -73,9 +73,6 @@ public final class RichInputConnection {
* This contains the currently composing text, as LatinIME thinks the TextView is seeing it.
*/
private final StringBuilder mComposingText = new StringBuilder();
- // A hint on how many characters to cache from the TextView. A good value of this is given by
- // how many characters we need to be able to almost always find the caps mode.
- private static final int DEFAULT_TEXT_CACHE_SIZE = 100;
private final InputMethodService mParent;
InputConnection mIC;
@@ -93,7 +90,8 @@ public final class RichInputConnection {
r.token = 1;
r.flags = 0;
final ExtractedText et = mIC.getExtractedText(r, 0);
- final CharSequence beforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0);
+ final CharSequence beforeCursor = getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
+ 0);
final StringBuilder internal = new StringBuilder().append(mCommittedTextBeforeComposingText)
.append(mComposingText);
if (null == et || null == beforeCursor) return;
@@ -142,19 +140,56 @@ public final class RichInputConnection {
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
- public void resetCachesUponCursorMove(final int newCursorPosition,
+ /**
+ * Reset the cached text and retrieve it again from the editor.
+ *
+ * This should be called when the cursor moved. It's possible that we can't connect to
+ * the application when doing this; notably, this happens sometimes during rotation, probably
+ * because of a race condition in the framework. In this case, we just can't retrieve the
+ * data, so we empty the cache and note that we don't know the new cursor position, and we
+ * return false so that the caller knows about this and can retry later.
+ *
+ * @param newCursorPosition The new position of the cursor, as received from the system.
+ * @param shouldFinishComposition Whether we should finish the composition in progress.
+ * @return true if we were able to connect to the editor successfully, false otherwise. When
+ * this method returns false, the caches could not be correctly refreshed so they were only
+ * reset: the caller should try again later to return to normal operation.
+ */
+ public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newCursorPosition,
final boolean shouldFinishComposition) {
mExpectedCursorPosition = newCursorPosition;
mComposingText.setLength(0);
mCommittedTextBeforeComposingText.setLength(0);
- final CharSequence textBeforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0);
- if (null != textBeforeCursor) mCommittedTextBeforeComposingText.append(textBeforeCursor);
+ mIC = mParent.getCurrentInputConnection();
+ // Call upon the inputconnection directly since our own method is using the cache, and
+ // we want to refresh it.
+ final CharSequence textBeforeCursor = null == mIC ? null :
+ mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
+ if (null == textBeforeCursor) {
+ // For some reason the app thinks we are not connected to it. This looks like a
+ // framework bug... Fall back to ground state and return false.
+ mExpectedCursorPosition = INVALID_CURSOR_POSITION;
+ Log.e(TAG, "Unable to connect to the editor to retrieve text... will retry later");
+ return false;
+ }
+ mCommittedTextBeforeComposingText.append(textBeforeCursor);
+ final int lengthOfTextBeforeCursor = textBeforeCursor.length();
+ if (lengthOfTextBeforeCursor > newCursorPosition
+ || (lengthOfTextBeforeCursor < Constants.EDITOR_CONTENTS_CACHE_SIZE
+ && newCursorPosition < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
+ // newCursorPosition may be lying -- when rotating the device (probably a framework
+ // bug). If we have less chars than we asked for, then we know how many chars we have,
+ // and if we got more than newCursorPosition says, then we know it was lying. In both
+ // cases the length is more reliable
+ mExpectedCursorPosition = lengthOfTextBeforeCursor;
+ }
if (null != mIC && shouldFinishComposition) {
mIC.finishComposingText();
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.richInputConnection_finishComposingText();
}
}
+ return true;
}
private void checkBatchEdit() {
@@ -169,7 +204,6 @@ public final class RichInputConnection {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(mComposingText);
- mExpectedCursorPosition += mComposingText.length();
mComposingText.setLength(0);
if (null != mIC) {
mIC.finishComposingText();
@@ -234,8 +268,11 @@ public final class RichInputConnection {
// getCapsMode should be updated to be able to return a "not enough info" result so that
// we can get more context only when needed.
if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedCursorPosition) {
- mCommittedTextBeforeComposingText.append(
- getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
+ final CharSequence textBeforeCursor = getTextBeforeCursor(
+ Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
+ if (!TextUtils.isEmpty(textBeforeCursor)) {
+ mCommittedTextBeforeComposingText.append(textBeforeCursor);
+ }
}
// This never calls InputConnection#getCapsMode - in fact, it's a static method that
// never blocks or initiates IPC.
@@ -363,7 +400,7 @@ public final class RichInputConnection {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
final CharSequence textBeforeCursor =
- getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE + (end - start), 0);
+ getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE + (end - start), 0);
mCommittedTextBeforeComposingText.setLength(0);
if (!TextUtils.isEmpty(textBeforeCursor)) {
final int indexOfStartOfComposingText =
@@ -405,7 +442,8 @@ public final class RichInputConnection {
}
mExpectedCursorPosition = start;
mCommittedTextBeforeComposingText.setLength(0);
- mCommittedTextBeforeComposingText.append(getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
+ mCommittedTextBeforeComposingText.append(
+ getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0));
}
public void commitCorrection(final CorrectionInfo correctionInfo) {
@@ -524,9 +562,9 @@ public final class RichInputConnection {
if (mIC == null || sep == null) {
return null;
}
- final CharSequence before = mIC.getTextBeforeCursor(1000,
+ final CharSequence before = mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
InputConnection.GET_TEXT_WITH_STYLES);
- final CharSequence after = mIC.getTextAfterCursor(1000,
+ final CharSequence after = mIC.getTextAfterCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
InputConnection.GET_TEXT_WITH_STYLES);
if (before == null || after == null) {
return null;
@@ -569,8 +607,11 @@ public final class RichInputConnection {
}
}
- return new TextRange(TextUtils.concat(before, after), startIndexInBefore,
- before.length() + endIndexInAfter, before.length());
+ // We don't use TextUtils#concat because it copies all spans without respect to their
+ // nature. If the text includes a PARAGRAPH span and it has been split, then
+ // TextUtils#concat will crash when it tries to concat both sides of it.
+ return new TextRange(StringUtils.concatWithNonParagraphSuggestionSpansOnly(before, after),
+ startIndexInBefore, before.length() + endIndexInAfter, before.length());
}
public boolean isCursorTouchingWord(final SettingsValues settingsValues) {
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index be03d4ae5..cd9c89f04 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -53,12 +53,25 @@ public final class SubtypeSwitcher {
private InputMethodInfo mShortcutInputMethodInfo;
private InputMethodSubtype mShortcutSubtype;
private InputMethodSubtype mNoLanguageSubtype;
+ private InputMethodSubtype mEmojiSubtype;
private boolean mIsNetworkConnected;
// Dummy no language QWERTY subtype. See {@link R.xml.method}.
private static final InputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE = new InputMethodSubtype(
- R.string.subtype_no_language_qwerty, R.drawable.ic_subtype_keyboard, "zz", "keyboard",
- "KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable",
+ R.string.subtype_no_language_qwerty, R.drawable.ic_ime_switcher_dark,
+ SubtypeLocaleUtils.NO_LANGUAGE, "keyboard", "KeyboardLayoutSet="
+ + SubtypeLocaleUtils.QWERTY
+ + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+ + ",EnabledWhenDefaultIsNotAsciiCapable,"
+ + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
+ false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
+ // Caveat: We probably should remove this when we add an Emoji subtype in {@link R.xml.method}.
+ // Dummy Emoji subtype. See {@link R.xml.method}.
+ private static final InputMethodSubtype DUMMY_EMOJI_SUBTYPE = new InputMethodSubtype(
+ R.string.subtype_emoji, R.drawable.ic_ime_switcher_dark,
+ SubtypeLocaleUtils.NO_LANGUAGE, "keyboard", "KeyboardLayoutSet="
+ + SubtypeLocaleUtils.EMOJI + ","
+ + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
static final class NeedsToDisplayLanguage {
@@ -271,4 +284,17 @@ public final class SubtypeSwitcher {
+ DUMMY_NO_LANGUAGE_SUBTYPE);
return DUMMY_NO_LANGUAGE_SUBTYPE;
}
+
+ public InputMethodSubtype getEmojiSubtype() {
+ if (mEmojiSubtype == null) {
+ mEmojiSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.EMOJI);
+ }
+ if (mEmojiSubtype != null) {
+ return mEmojiSubtype;
+ }
+ Log.w(TAG, "Can't find Emoji subtype");
+ Log.w(TAG, "No input method subtype found; return dummy subtype: " + DUMMY_EMOJI_SUBTYPE);
+ return DUMMY_EMOJI_SUBTYPE;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index c2fdcb552..6c18c948f 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -24,6 +24,7 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationPredictionDictionary;
import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
import com.android.inputmethod.latin.settings.Settings;
@@ -47,8 +48,9 @@ public final class Suggest {
// Session id for
// {@link #getSuggestedWords(WordComposer,String,ProximityInfo,boolean,int)}.
+ // We are sharing the same ID between typing and gesture to save RAM footprint.
public static final int SESSION_TYPING = 0;
- public static final int SESSION_GESTURE = 1;
+ public static final int SESSION_GESTURE = 0;
// TODO: rename this to CORRECTION_OFF
public static final int CORRECTION_NONE = 0;
@@ -107,7 +109,7 @@ public final class Suggest {
}
private void addOrReplaceDictionaryInternal(final String key, final Dictionary dict) {
- if (mOnlyDictionarySetForDebug != null && mOnlyDictionarySetForDebug.contains(key)) {
+ if (mOnlyDictionarySetForDebug != null && !mOnlyDictionarySetForDebug.contains(key)) {
Log.w(TAG, "Ignore add " + key + " dictionary for debug.");
return;
}
@@ -200,28 +202,41 @@ public final class Suggest {
personalizationPredictionDictionary);
}
+ public void setPersonalizationDictionary(
+ final PersonalizationDictionary personalizationDictionary) {
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION,
+ personalizationDictionary);
+ }
+
public void setAutoCorrectionThreshold(float threshold) {
mAutoCorrectionThreshold = threshold;
}
- public SuggestedWords getSuggestedWords(final WordComposer wordComposer,
+ public interface OnGetSuggestedWordsCallback {
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords);
+ }
+
+ public void getSuggestedWords(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
- final int sessionId) {
+ final int[] additionalFeaturesOptions, final int sessionId,
+ final OnGetSuggestedWordsCallback callback) {
LatinImeLogger.onStartSuggestion(prevWordForBigram);
if (wordComposer.isBatchMode()) {
- return getSuggestedWordsForBatchInput(
- wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, sessionId);
+ getSuggestedWordsForBatchInput(wordComposer, prevWordForBigram, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, sessionId, callback);
} else {
- return getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo,
- blockOffensiveWords, isCorrectionEnabled);
+ getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo,
+ blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions, callback);
}
}
- // Retrieves suggestions for the typing input.
- private SuggestedWords getSuggestedWordsForTypingInput(final WordComposer wordComposer,
+ // Retrieves suggestions for the typing input
+ // and calls the callback function with the suggestions.
+ private void getSuggestedWordsForTypingInput(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final boolean isCorrectionEnabled) {
+ final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
+ final int[] additionalFeaturesOptions, final OnGetSuggestedWordsCallback callback) {
final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
MAX_SUGGESTIONS);
@@ -244,8 +259,9 @@ public final class Suggest {
for (final String key : mDictionaries.keySet()) {
final Dictionary dictionary = mDictionaries.get(key);
- suggestionsSet.addAll(dictionary.getSuggestions(
- wordComposerForLookup, prevWordForBigram, proximityInfo, blockOffensiveWords));
+ suggestionsSet.addAll(dictionary.getSuggestions(wordComposerForLookup,
+ prevWordForBigram, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions));
}
final String whitelistedWord;
@@ -303,13 +319,16 @@ public final class Suggest {
for (int i = 0; i < suggestionsCount; ++i) {
final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(), wordInfo.mSourceDict);
+ LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(),
+ wordInfo.mSourceDict.mDictType);
}
if (!TextUtils.isEmpty(typedWord)) {
suggestionsContainer.add(0, new SuggestedWordInfo(typedWord,
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
- Dictionary.TYPE_USER_TYPED));
+ Dictionary.DICTIONARY_USER_TYPED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
}
SuggestedWordInfo.removeDups(suggestionsContainer);
@@ -320,7 +339,7 @@ public final class Suggest {
suggestionsList = suggestionsContainer;
}
- return new SuggestedWords(suggestionsList,
+ callback.onGetSuggestedWords(new SuggestedWords(suggestionsList,
// TODO: this first argument is lying. If this is a whitelisted word which is an
// actual word, it says typedWordValid = false, which looks wrong. We should either
// rename the attribute or change the value.
@@ -328,31 +347,28 @@ public final class Suggest {
hasAutoCorrection, /* willAutoCorrect */
false /* isPunctuationSuggestions */,
false /* isObsoleteSuggestions */,
- !wordComposer.isComposingWord() /* isPrediction */);
+ !wordComposer.isComposingWord() /* isPrediction */));
}
- // Retrieves suggestions for the batch input.
- private SuggestedWords getSuggestedWordsForBatchInput(final WordComposer wordComposer,
+ // Retrieves suggestions for the batch input
+ // and calls the callback function with the suggestions.
+ private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int sessionId) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId, final OnGetSuggestedWordsCallback callback) {
final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
MAX_SUGGESTIONS);
// At second character typed, search the unigrams (scores being affected by bigrams)
for (final String key : mDictionaries.keySet()) {
- // Skip User history dictionary for lookup
- // TODO: The user history dictionary should just override getSuggestionsWithSessionId
- // to make sure it doesn't return anything and we should remove this test
- if (key.equals(Dictionary.TYPE_USER_HISTORY)) {
- continue;
- }
final Dictionary dictionary = mDictionaries.get(key);
suggestionsSet.addAll(dictionary.getSuggestionsWithSessionId(wordComposer,
- prevWordForBigram, proximityInfo, blockOffensiveWords, sessionId));
+ prevWordForBigram, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, sessionId));
}
for (SuggestedWordInfo wordInfo : suggestionsSet) {
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict);
+ LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict.mDictType);
}
final ArrayList<SuggestedWordInfo> suggestionsContainer =
@@ -387,12 +403,12 @@ public final class Suggest {
// In the batch input mode, the most relevant suggested word should act as a "typed word"
// (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false).
- return new SuggestedWords(suggestionsContainer,
+ callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer,
true /* typedWordValid */,
false /* willAutoCorrect */,
false /* isPunctuationSuggestions */,
false /* isObsoleteSuggestions */,
- false /* isPrediction */);
+ false /* isPrediction */));
}
private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo(
@@ -438,7 +454,7 @@ public final class Suggest {
private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator =
new SuggestedWordInfoComparator();
- private static SuggestedWordInfo getTransformedSuggestedWordInfo(
+ /* package for test */ static SuggestedWordInfo getTransformedSuggestedWordInfo(
final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase,
final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) {
final StringBuilder sb = new StringBuilder(wordInfo.mWord.length());
@@ -449,11 +465,17 @@ public final class Suggest {
} else {
sb.append(wordInfo.mWord);
}
- for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
+ // Appending quotes is here to help people quote words. However, it's not helpful
+ // when they type words with quotes toward the end like "it's" or "didn't", where
+ // it's more likely the user missed the last character (or didn't type it yet).
+ final int quotesToAppend = trailingSingleQuotesCount
+ - (-1 == wordInfo.mWord.indexOf(Constants.CODE_SINGLE_QUOTE) ? 0 : 1);
+ for (int i = quotesToAppend - 1; i >= 0; --i) {
sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
}
return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
- wordInfo.mSourceDict);
+ wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
}
public void close() {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 22beaefee..fed4cdbbb 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -113,7 +113,9 @@ public final class SuggestedWords {
if (null == text) continue;
final SuggestedWordInfo suggestedWordInfo = new SuggestedWordInfo(text.toString(),
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_APP_DEFINED,
- Dictionary.TYPE_APPLICATION_DEFINED);
+ Dictionary.DICTIONARY_APPLICATION_DEFINED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
result.add(suggestedWordInfo);
}
return result;
@@ -126,7 +128,9 @@ public final class SuggestedWords {
final ArrayList<SuggestedWordInfo> suggestionsList = CollectionUtils.newArrayList();
final HashSet<String> alreadySeen = CollectionUtils.newHashSet();
suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE,
- SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED));
+ SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
alreadySeen.add(typedWord.toString());
final int previousSize = previousSuggestions.size();
for (int index = 1; index < previousSize; index++) {
@@ -141,7 +145,15 @@ public final class SuggestedWords {
return suggestionsList;
}
+ public SuggestedWordInfo getAutoCommitCandidate() {
+ if (mSuggestedWordInfoList.size() <= 0) return null;
+ final SuggestedWordInfo candidate = mSuggestedWordInfoList.get(0);
+ return candidate.isEligibleForAutoCommit() ? candidate : null;
+ }
+
public static final class SuggestedWordInfo {
+ public static final int NOT_AN_INDEX = -1;
+ public static final int NOT_A_CONFIDENCE = -1;
public static final int MAX_SCORE = Integer.MAX_VALUE;
public static final int KIND_MASK_KIND = 0xFF; // Mask to get only the kind
public static final int KIND_TYPED = 0; // What user typed
@@ -166,18 +178,40 @@ public final class SuggestedWords {
public final int mScore;
public final int mKind; // one of the KIND_* constants above
public final int mCodePointCount;
- public final String mSourceDict;
+ public final Dictionary mSourceDict;
+ // For auto-commit. This keeps track of the index inside the touch coordinates array
+ // passed to native code to get suggestions for a gesture that corresponds to the first
+ // letter of the second word.
+ public final int mIndexOfTouchPointOfSecondWord;
+ // For auto-commit. This is a measure of how confident we are that we can commit the
+ // first word of this suggestion.
+ public final int mAutoCommitFirstWordConfidence;
private String mDebugString = "";
+ /**
+ * Create a new suggested word info.
+ * @param word The string to suggest.
+ * @param score A measure of how likely this suggestion is.
+ * @param kind The kind of suggestion, as one of the above KIND_* constants.
+ * @param sourceDict What instance of Dictionary produced this suggestion.
+ * @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord.
+ * @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence.
+ */
public SuggestedWordInfo(final String word, final int score, final int kind,
- final String sourceDict) {
+ final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord,
+ final int autoCommitFirstWordConfidence) {
mWord = word;
mScore = score;
mKind = kind;
mSourceDict = sourceDict;
mCodePointCount = StringUtils.codePointCount(mWord);
+ mIndexOfTouchPointOfSecondWord = indexOfTouchPointOfSecondWord;
+ mAutoCommitFirstWordConfidence = autoCommitFirstWordConfidence;
}
+ public boolean isEligibleForAutoCommit() {
+ return (KIND_CORRECTION == mKind && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord);
+ }
public void setDebugString(final String str) {
if (null == str) throw new NullPointerException("Debug info is null");
@@ -242,4 +276,24 @@ public final class SuggestedWords {
false /* willAutoCorrect */, mIsPunctuationSuggestions, mIsObsoleteSuggestions,
mIsPrediction);
}
+
+ // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
+ // last word of all suggestions, separated by a space. This is necessary because when we commit
+ // a multiple-word suggestion, the IME only retains the last word as the composing word, and
+ // we should only suggest replacements for this last word.
+ // TODO: make this work with languages without spaces.
+ public SuggestedWords getSuggestedWordsForLastWordOfPhraseGesture() {
+ final ArrayList<SuggestedWordInfo> newSuggestions = CollectionUtils.newArrayList();
+ for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
+ final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
+ final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1;
+ final String lastWord = info.mWord.substring(indexOfLastSpace);
+ newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKind,
+ info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX,
+ SuggestedWordInfo.NOT_A_CONFIDENCE));
+ }
+ return new SuggestedWords(newSuggestions, mTypedWordValid,
+ mWillAutoCorrect, mIsPunctuationSuggestions, mIsObsoleteSuggestions,
+ mIsPrediction);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
index 92f96c027..3213c92c7 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -34,14 +34,15 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB
@Override
public synchronized ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
final String prevWordForBigrams, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
- syncReloadDictionaryIfRequired();
- return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords);
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ reloadDictionaryIfRequired();
+ return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions);
}
@Override
public synchronized boolean isValidWord(final String word) {
- syncReloadDictionaryIfRequired();
+ reloadDictionaryIfRequired();
return isValidWordInner(word);
}
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
index 33fe89611..6405b5e46 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
@@ -37,14 +37,15 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic
@Override
public synchronized ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
final String prevWordForBigrams, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
- syncReloadDictionaryIfRequired();
- return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords);
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ reloadDictionaryIfRequired();
+ return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions);
}
@Override
public synchronized boolean isValidWord(final String word) {
- syncReloadDictionaryIfRequired();
+ reloadDictionaryIfRequired();
return isValidWordInner(word);
}
}
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index ed6fefae4..864a17375 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -22,10 +22,12 @@ import android.content.ContentUris;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Build;
import android.provider.UserDictionary.Words;
import android.text.TextUtils;
+import android.util.Log;
import com.android.inputmethod.compat.UserDictionaryCompatUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
@@ -39,6 +41,7 @@ import java.util.Locale;
* dictionary file to use it from native code.
*/
public class UserBinaryDictionary extends ExpandableBinaryDictionary {
+ private static final String TAG = ExpandableBinaryDictionary.class.getSimpleName();
// The user dictionary provider uses an empty string to mean "all languages".
private static final String USER_DICTIONARY_ALL_LANGUAGES = "";
@@ -75,7 +78,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
public UserBinaryDictionary(final Context context, final String locale,
final boolean alsoUseMoreRestrictiveLocales) {
- super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER);
+ super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER,
+ false /* isUpdatable */);
if (null == locale) throw new NullPointerException(); // Catch the error earlier
if (SubtypeLocaleUtils.NO_LANGUAGE.equals(locale)) {
// If we don't have a locale, insert into the "all locales" user dictionary.
@@ -102,14 +106,6 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
@Override
public void onChange(final boolean self, final Uri uri) {
setRequiresReload(true);
- // We want to report back to Latin IME in case the user just entered the word.
- // If the user changed the word in the dialog box, then we want to replace
- // what was entered in the text field.
- if (null == uri || !(context instanceof LatinIME)) return;
- final long changedRowId = ContentUris.parseId(uri);
- if (-1 == changedRowId) return; // Unknown content... Not sure why we're here
- final String changedWord = getChangedWordForUri(uri);
- ((LatinIME)context).onWordAddedToUserDictionary(changedWord);
}
};
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
@@ -117,19 +113,6 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
loadDictionary();
}
- private String getChangedWordForUri(final Uri uri) {
- final Cursor cursor = mContext.getContentResolver().query(uri,
- PROJECTION_QUERY, null, null, null);
- if (cursor == null) return null;
- try {
- if (!cursor.moveToFirst()) return null;
- final int indexWord = cursor.getColumnIndex(Words.WORD);
- return cursor.getString(indexWord);
- } finally {
- cursor.close();
- }
- }
-
@Override
public synchronized void close() {
if (mObserver != null) {
@@ -188,12 +171,19 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
} else {
requestArguments = localeElements;
}
- final Cursor cursor = mContext.getContentResolver().query(
- Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
+ Cursor cursor = null;
try {
+ cursor = mContext.getContentResolver().query(
+ Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
addWords(cursor);
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
} finally {
- if (null != cursor) cursor.close();
+ try {
+ if (null != cursor) cursor.close();
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index a09ca605c..039dadc66 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -272,8 +272,8 @@ public final class WordComposer {
final int x, y;
final Key key;
if (keyboard != null && (key = keyboard.getKey(codePoint)) != null) {
- x = key.mX + key.mWidth / 2;
- y = key.mY + key.mHeight / 2;
+ x = key.getX() + key.getWidth() / 2;
+ y = key.getY() + key.getHeight() / 2;
} else {
x = Constants.NOT_A_COORDINATE;
y = Constants.NOT_A_COORDINATE;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
new file mode 100644
index 000000000..665c7a27c
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Decodes binary files for a FusionDictionary.
+ *
+ * All the methods in this class are static.
+ *
+ * TODO: Remove calls from classes except Ver3DictDecoder
+ * TODO: Move this file to makedict/internal.
+ * TODO: Rename this class to DictDecoderUtils.
+ */
+public final class BinaryDictDecoderUtils {
+
+ private static final boolean DBG = MakedictLog.DBG;
+
+ private BinaryDictDecoderUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ private static final int MAX_JUMPS = 12;
+
+ @UsedForTesting
+ public interface DictBuffer {
+ public int readUnsignedByte();
+ public int readUnsignedShort();
+ public int readUnsignedInt24();
+ public int readInt();
+ public int position();
+ public void position(int newPosition);
+ public void put(final byte b);
+ public int limit();
+ @UsedForTesting
+ public int capacity();
+ }
+
+ public static final class ByteBufferDictBuffer implements DictBuffer {
+ private ByteBuffer mBuffer;
+
+ public ByteBufferDictBuffer(final ByteBuffer buffer) {
+ mBuffer = buffer;
+ }
+
+ @Override
+ public int readUnsignedByte() {
+ return mBuffer.get() & 0xFF;
+ }
+
+ @Override
+ public int readUnsignedShort() {
+ return mBuffer.getShort() & 0xFFFF;
+ }
+
+ @Override
+ public int readUnsignedInt24() {
+ final int retval = readUnsignedByte();
+ return (retval << 16) + readUnsignedShort();
+ }
+
+ @Override
+ public int readInt() {
+ return mBuffer.getInt();
+ }
+
+ @Override
+ public int position() {
+ return mBuffer.position();
+ }
+
+ @Override
+ public void position(int newPos) {
+ mBuffer.position(newPos);
+ }
+
+ @Override
+ public void put(final byte b) {
+ mBuffer.put(b);
+ }
+
+ @Override
+ public int limit() {
+ return mBuffer.limit();
+ }
+
+ @Override
+ public int capacity() {
+ return mBuffer.capacity();
+ }
+ }
+
+ /**
+ * A class grouping utility function for our specific character encoding.
+ */
+ static final class CharEncoding {
+ private static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20;
+ private static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF;
+
+ /**
+ * Helper method to find out whether this code fits on one byte
+ */
+ private static boolean fitsOnOneByte(final int character) {
+ return character >= MINIMAL_ONE_BYTE_CHARACTER_VALUE
+ && character <= MAXIMAL_ONE_BYTE_CHARACTER_VALUE;
+ }
+
+ /**
+ * Compute the size of a character given its character code.
+ *
+ * Char format is:
+ * 1 byte = bbbbbbbb match
+ * case 000xxxxx: xxxxx << 16 + next byte << 8 + next byte
+ * else: if 00011111 (= 0x1F) : this is the terminator. This is a relevant choice because
+ * unicode code points range from 0 to 0x10FFFF, so any 3-byte value starting with
+ * 00011111 would be outside unicode.
+ * else: iso-latin-1 code
+ * This allows for the whole unicode range to be encoded, including chars outside of
+ * the BMP. Also everything in the iso-latin-1 charset is only 1 byte, except control
+ * characters which should never happen anyway (and still work, but take 3 bytes).
+ *
+ * @param character the character code.
+ * @return the size in binary encoded-form, either 1 or 3 bytes.
+ */
+ static int getCharSize(final int character) {
+ // See char encoding in FusionDictionary.java
+ if (fitsOnOneByte(character)) return 1;
+ if (FormatSpec.INVALID_CHARACTER == character) return 1;
+ return 3;
+ }
+
+ /**
+ * Compute the byte size of a character array.
+ */
+ static int getCharArraySize(final int[] chars) {
+ int size = 0;
+ for (int character : chars) size += getCharSize(character);
+ return size;
+ }
+
+ /**
+ * Writes a char array to a byte buffer.
+ *
+ * @param codePoints the code point array to write.
+ * @param buffer the byte buffer to write to.
+ * @param index the index in buffer to write the character array to.
+ * @return the index after the last character.
+ */
+ static int writeCharArray(final int[] codePoints, final byte[] buffer, int index) {
+ for (int codePoint : codePoints) {
+ if (1 == getCharSize(codePoint)) {
+ buffer[index++] = (byte)codePoint;
+ } else {
+ buffer[index++] = (byte)(0xFF & (codePoint >> 16));
+ buffer[index++] = (byte)(0xFF & (codePoint >> 8));
+ buffer[index++] = (byte)(0xFF & codePoint);
+ }
+ }
+ return index;
+ }
+
+ /**
+ * Writes a string with our character format to a byte buffer.
+ *
+ * This will also write the terminator byte.
+ *
+ * @param buffer the byte buffer to write to.
+ * @param origin the offset to write from.
+ * @param word the string to write.
+ * @return the size written, in bytes.
+ */
+ static int writeString(final byte[] buffer, final int origin,
+ final String word) {
+ final int length = word.length();
+ int index = origin;
+ for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
+ final int codePoint = word.codePointAt(i);
+ if (1 == getCharSize(codePoint)) {
+ buffer[index++] = (byte)codePoint;
+ } else {
+ buffer[index++] = (byte)(0xFF & (codePoint >> 16));
+ buffer[index++] = (byte)(0xFF & (codePoint >> 8));
+ buffer[index++] = (byte)(0xFF & codePoint);
+ }
+ }
+ buffer[index++] = FormatSpec.PTNODE_CHARACTERS_TERMINATOR;
+ return index - origin;
+ }
+
+ /**
+ * Writes a string with our character format to a ByteArrayOutputStream.
+ *
+ * This will also write the terminator byte.
+ *
+ * @param buffer the ByteArrayOutputStream to write to.
+ * @param word the string to write.
+ */
+ static void writeString(final ByteArrayOutputStream buffer, final String word) {
+ final int length = word.length();
+ for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
+ final int codePoint = word.codePointAt(i);
+ if (1 == getCharSize(codePoint)) {
+ buffer.write((byte) codePoint);
+ } else {
+ buffer.write((byte) (0xFF & (codePoint >> 16)));
+ buffer.write((byte) (0xFF & (codePoint >> 8)));
+ buffer.write((byte) (0xFF & codePoint));
+ }
+ }
+ buffer.write(FormatSpec.PTNODE_CHARACTERS_TERMINATOR);
+ }
+
+ /**
+ * Reads a string from a DictBuffer. This is the converse of the above method.
+ */
+ static String readString(final DictBuffer dictBuffer) {
+ final StringBuilder s = new StringBuilder();
+ int character = readChar(dictBuffer);
+ while (character != FormatSpec.INVALID_CHARACTER) {
+ s.appendCodePoint(character);
+ character = readChar(dictBuffer);
+ }
+ return s.toString();
+ }
+
+ /**
+ * Reads a character from the buffer.
+ *
+ * This follows the character format documented earlier in this source file.
+ *
+ * @param dictBuffer the buffer, positioned over an encoded character.
+ * @return the character code.
+ */
+ static int readChar(final DictBuffer dictBuffer) {
+ int character = dictBuffer.readUnsignedByte();
+ if (!fitsOnOneByte(character)) {
+ if (FormatSpec.PTNODE_CHARACTERS_TERMINATOR == character) {
+ return FormatSpec.INVALID_CHARACTER;
+ }
+ character <<= 16;
+ character += dictBuffer.readUnsignedShort();
+ }
+ return character;
+ }
+ }
+
+ // Input methods: Read a binary dictionary to memory.
+ // readDictionaryBinary is the public entry point for them.
+
+ static int readSInt24(final DictBuffer dictBuffer) {
+ final int retval = dictBuffer.readUnsignedInt24();
+ final int sign = ((retval & FormatSpec.MSB24) != 0) ? -1 : 1;
+ return sign * (retval & FormatSpec.SINT24_MAX);
+ }
+
+ static int readChildrenAddress(final DictBuffer dictBuffer,
+ final int optionFlags, final FormatOptions options) {
+ if (options.mSupportsDynamicUpdate) {
+ final int address = dictBuffer.readUnsignedInt24();
+ if (address == 0) return FormatSpec.NO_CHILDREN_ADDRESS;
+ if ((address & FormatSpec.MSB24) != 0) {
+ return -(address & FormatSpec.SINT24_MAX);
+ } else {
+ return address;
+ }
+ }
+ int address;
+ switch (optionFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
+ return dictBuffer.readUnsignedByte();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES:
+ return dictBuffer.readUnsignedShort();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES:
+ return dictBuffer.readUnsignedInt24();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS:
+ default:
+ return FormatSpec.NO_CHILDREN_ADDRESS;
+ }
+ }
+
+ static int readParentAddress(final DictBuffer dictBuffer,
+ final FormatOptions formatOptions) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ final int parentAddress = dictBuffer.readUnsignedInt24();
+ final int sign = ((parentAddress & FormatSpec.MSB24) != 0) ? -1 : 1;
+ return sign * (parentAddress & FormatSpec.SINT24_MAX);
+ } else {
+ return FormatSpec.NO_PARENT_ADDRESS;
+ }
+ }
+
+ /**
+ * Reads and returns the PtNode count out of a buffer and forwards the pointer.
+ */
+ /* package */ static int readPtNodeCount(final DictBuffer dictBuffer) {
+ final int msb = dictBuffer.readUnsignedByte();
+ if (FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT >= msb) {
+ return msb;
+ } else {
+ return ((FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT & msb) << 8)
+ + dictBuffer.readUnsignedByte();
+ }
+ }
+
+ /**
+ * Finds, as a string, the word at the position passed as an argument.
+ *
+ * @param dictDecoder the dict decoder.
+ * @param headerSize the size of the header.
+ * @param pos the position to seek.
+ * @param formatOptions file format options.
+ * @return the word with its frequency, as a weighted string.
+ */
+ /* package for tests */ static WeightedString getWordAtPosition(final DictDecoder dictDecoder,
+ final int headerSize, final int pos, final FormatOptions formatOptions) {
+ final WeightedString result;
+ final int originalPos = dictDecoder.getPosition();
+ dictDecoder.setPosition(pos);
+
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ result = getWordAtPositionWithParentAddress(dictDecoder, pos, formatOptions);
+ } else {
+ result = getWordAtPositionWithoutParentAddress(dictDecoder, headerSize, pos,
+ formatOptions);
+ }
+
+ dictDecoder.setPosition(originalPos);
+ return result;
+ }
+
+ @SuppressWarnings("unused")
+ private static WeightedString getWordAtPositionWithParentAddress(final DictDecoder dictDecoder,
+ final int pos, final FormatOptions options) {
+ int currentPos = pos;
+ int frequency = Integer.MIN_VALUE;
+ final StringBuilder builder = new StringBuilder();
+ // the length of the path from the root to the leaf is limited by MAX_WORD_LENGTH
+ for (int count = 0; count < FormatSpec.MAX_WORD_LENGTH; ++count) {
+ PtNodeInfo currentInfo;
+ int loopCounter = 0;
+ do {
+ dictDecoder.setPosition(currentPos);
+ currentInfo = dictDecoder.readPtNode(currentPos, options);
+ if (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options)) {
+ currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
+ }
+ if (DBG && loopCounter++ > MAX_JUMPS) {
+ MakedictLog.d("Too many jumps - probably a bug");
+ }
+ } while (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options));
+ if (Integer.MIN_VALUE == frequency) frequency = currentInfo.mFrequency;
+ builder.insert(0,
+ new String(currentInfo.mCharacters, 0, currentInfo.mCharacters.length));
+ if (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS) break;
+ currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
+ }
+ return new WeightedString(builder.toString(), frequency);
+ }
+
+ private static WeightedString getWordAtPositionWithoutParentAddress(
+ final DictDecoder dictDecoder, final int headerSize, final int pos,
+ final FormatOptions options) {
+ dictDecoder.setPosition(headerSize);
+ final int count = dictDecoder.readPtNodeCount();
+ int groupPos = headerSize + BinaryDictIOUtils.getPtNodeCountSize(count);
+ final StringBuilder builder = new StringBuilder();
+ WeightedString result = null;
+
+ PtNodeInfo last = null;
+ for (int i = count - 1; i >= 0; --i) {
+ PtNodeInfo info = dictDecoder.readPtNode(groupPos, options);
+ groupPos = info.mEndAddress;
+ if (info.mOriginalAddress == pos) {
+ builder.append(new String(info.mCharacters, 0, info.mCharacters.length));
+ result = new WeightedString(builder.toString(), info.mFrequency);
+ break; // and return
+ }
+ if (BinaryDictIOUtils.hasChildrenAddress(info.mChildrenAddress)) {
+ if (info.mChildrenAddress > pos) {
+ if (null == last) continue;
+ builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
+ dictDecoder.setPosition(last.mChildrenAddress);
+ i = dictDecoder.readPtNodeCount();
+ groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i);
+ last = null;
+ continue;
+ }
+ last = info;
+ }
+ if (0 == i && BinaryDictIOUtils.hasChildrenAddress(last.mChildrenAddress)) {
+ builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
+ dictDecoder.setPosition(last.mChildrenAddress);
+ i = dictDecoder.readPtNodeCount();
+ groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i);
+ last = null;
+ continue;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Reads a single node array from a buffer.
+ *
+ * This methods reads the file at the current position. A node array is fully expected to start
+ * at the current position.
+ * This will recursively read other node arrays into the structure, populating the reverse
+ * maps on the fly and using them to keep track of already read nodes.
+ *
+ * @param dictDecoder the dict decoder, correctly positioned at the start of a node array.
+ * @param headerSize the size, in bytes, of the file header.
+ * @param reverseNodeArrayMap a mapping from addresses to already read node arrays.
+ * @param reversePtNodeMap a mapping from addresses to already read PtNodes.
+ * @param options file format options.
+ * @return the read node array with all his children already read.
+ */
+ private static PtNodeArray readNodeArray(final DictDecoder dictDecoder,
+ final int headerSize, final Map<Integer, PtNodeArray> reverseNodeArrayMap,
+ final Map<Integer, PtNode> reversePtNodeMap, final FormatOptions options)
+ throws IOException {
+ final ArrayList<PtNode> nodeArrayContents = new ArrayList<PtNode>();
+ final int nodeArrayOriginPos = dictDecoder.getPosition();
+
+ do { // Scan the linked-list node.
+ final int nodeArrayHeadPos = dictDecoder.getPosition();
+ final int count = dictDecoder.readPtNodeCount();
+ int groupOffsetPos = nodeArrayHeadPos + BinaryDictIOUtils.getPtNodeCountSize(count);
+ for (int i = count; i > 0; --i) { // Scan the array of PtNode.
+ PtNodeInfo info = dictDecoder.readPtNode(groupOffsetPos, options);
+ if (BinaryDictIOUtils.isMovedPtNode(info.mFlags, options)) continue;
+ ArrayList<WeightedString> shortcutTargets = info.mShortcutTargets;
+ ArrayList<WeightedString> bigrams = null;
+ if (null != info.mBigrams) {
+ bigrams = new ArrayList<WeightedString>();
+ for (PendingAttribute bigram : info.mBigrams) {
+ final WeightedString word = getWordAtPosition(dictDecoder, headerSize,
+ bigram.mAddress, options);
+ final int reconstructedFrequency =
+ BinaryDictIOUtils.reconstructBigramFrequency(word.mFrequency,
+ bigram.mFrequency);
+ bigrams.add(new WeightedString(word.mWord, reconstructedFrequency));
+ }
+ }
+ if (BinaryDictIOUtils.hasChildrenAddress(info.mChildrenAddress)) {
+ PtNodeArray children = reverseNodeArrayMap.get(info.mChildrenAddress);
+ if (null == children) {
+ final int currentPosition = dictDecoder.getPosition();
+ dictDecoder.setPosition(info.mChildrenAddress);
+ children = readNodeArray(dictDecoder, headerSize, reverseNodeArrayMap,
+ reversePtNodeMap, options);
+ dictDecoder.setPosition(currentPosition);
+ }
+ nodeArrayContents.add(
+ new PtNode(info.mCharacters, shortcutTargets, bigrams,
+ info.mFrequency,
+ 0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
+ 0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED), children));
+ } else {
+ nodeArrayContents.add(
+ new PtNode(info.mCharacters, shortcutTargets, bigrams,
+ info.mFrequency,
+ 0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
+ 0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED)));
+ }
+ groupOffsetPos = info.mEndAddress;
+ }
+
+ // reach the end of the array.
+ if (options.mSupportsDynamicUpdate) {
+ final boolean hasValidForwardLink = dictDecoder.readAndFollowForwardLink();
+ if (!hasValidForwardLink) break;
+ }
+ } while (options.mSupportsDynamicUpdate && dictDecoder.hasNextPtNodeArray());
+
+ final PtNodeArray nodeArray = new PtNodeArray(nodeArrayContents);
+ nodeArray.mCachedAddressBeforeUpdate = nodeArrayOriginPos;
+ nodeArray.mCachedAddressAfterUpdate = nodeArrayOriginPos;
+ reverseNodeArrayMap.put(nodeArray.mCachedAddressAfterUpdate, nodeArray);
+ return nodeArray;
+ }
+
+ /**
+ * Helper function to get the binary format version from the header.
+ * @throws IOException
+ */
+ private static int getFormatVersion(final DictBuffer dictBuffer)
+ throws IOException {
+ final int magic = dictBuffer.readInt();
+ if (FormatSpec.MAGIC_NUMBER == magic) return dictBuffer.readUnsignedShort();
+ return FormatSpec.NOT_A_VERSION_NUMBER;
+ }
+
+ /**
+ * Helper function to get and validate the binary format version.
+ * @throws UnsupportedFormatException
+ * @throws IOException
+ */
+ static int checkFormatVersion(final DictBuffer dictBuffer)
+ throws IOException, UnsupportedFormatException {
+ final int version = getFormatVersion(dictBuffer);
+ if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
+ || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
+ throw new UnsupportedFormatException("This file has version " + version
+ + ", but this implementation does not support versions above "
+ + FormatSpec.MAXIMUM_SUPPORTED_VERSION);
+ }
+ return version;
+ }
+
+ /**
+ * Reads a buffer and returns the memory representation of the dictionary.
+ *
+ * This high-level method takes a buffer and reads its contents, populating a
+ * FusionDictionary structure. The optional dict argument is an existing dictionary to
+ * which words from the buffer should be added. If it is null, a new dictionary is created.
+ *
+ * @param dictDecoder the dict decoder.
+ * @param dict an optional dictionary to add words to, or null.
+ * @return the created (or merged) dictionary.
+ */
+ @UsedForTesting
+ /* package */ static FusionDictionary readDictionaryBinary(final DictDecoder dictDecoder,
+ final FusionDictionary dict) throws IOException, UnsupportedFormatException {
+ // Read header
+ final FileHeader fileHeader = dictDecoder.readHeader();
+
+ Map<Integer, PtNodeArray> reverseNodeArrayMapping = new TreeMap<Integer, PtNodeArray>();
+ Map<Integer, PtNode> reversePtNodeMapping = new TreeMap<Integer, PtNode>();
+ final PtNodeArray root = readNodeArray(dictDecoder, fileHeader.mHeaderSize,
+ reverseNodeArrayMapping, reversePtNodeMapping, fileHeader.mFormatOptions);
+
+ FusionDictionary newDict = new FusionDictionary(root, fileHeader.mDictionaryOptions);
+ if (null != dict) {
+ for (final Word w : dict) {
+ if (w.mIsBlacklistEntry) {
+ newDict.addBlacklistEntry(w.mWord, w.mShortcutTargets, w.mIsNotAWord);
+ } else {
+ newDict.add(w.mWord, w.mFrequency, w.mShortcutTargets, w.mIsNotAWord);
+ }
+ }
+ for (final Word w : dict) {
+ // By construction a binary dictionary may not have bigrams pointing to
+ // words that are not also registered as unigrams so we don't have to avoid
+ // them explicitly here.
+ for (final WeightedString bigram : w.mBigrams) {
+ newDict.setBigram(w.mWord, bigram.mWord, bigram.mFrequency);
+ }
+ }
+ }
+
+ return newDict;
+ }
+
+ /**
+ * Helper method to pass a file name instead of a File object to isBinaryDictionary.
+ */
+ public static boolean isBinaryDictionary(final String filename) {
+ final File file = new File(filename);
+ return isBinaryDictionary(file);
+ }
+
+ /**
+ * Basic test to find out whether the file is a binary dictionary or not.
+ *
+ * Concretely this only tests the magic number.
+ *
+ * @param file The file to test.
+ * @return true if it's a binary dictionary, false otherwise
+ */
+ public static boolean isBinaryDictionary(final File file) {
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(file);
+ final ByteBuffer buffer = inStream.getChannel().map(
+ FileChannel.MapMode.READ_ONLY, 0, file.length());
+ final int version = getFormatVersion(new ByteBufferDictBuffer(buffer));
+ return (version >= FormatSpec.MINIMUM_SUPPORTED_VERSION
+ && version <= FormatSpec.MAXIMUM_SUPPORTED_VERSION);
+ } catch (FileNotFoundException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
new file mode 100644
index 000000000..4dba8e5cf
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -0,0 +1,936 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+/**
+ * Encodes binary files for a FusionDictionary.
+ *
+ * All the methods in this class are static.
+ *
+ * TODO: Rename this class to DictEncoderUtils.
+ */
+public class BinaryDictEncoderUtils {
+
+ private static final boolean DBG = MakedictLog.DBG;
+
+ private BinaryDictEncoderUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ // Arbitrary limit to how much passes we consider address size compression should
+ // terminate in. At the time of this writing, our largest dictionary completes
+ // compression in five passes.
+ // If the number of passes exceeds this number, makedict bails with an exception on
+ // suspicion that a bug might be causing an infinite loop.
+ private static final int MAX_PASSES = 24;
+
+ /**
+ * Compute the binary size of the character array.
+ *
+ * If only one character, this is the size of this character. If many, it's the sum of their
+ * sizes + 1 byte for the terminator.
+ *
+ * @param characters the character array
+ * @return the size of the char array, including the terminator if any
+ */
+ static int getPtNodeCharactersSize(final int[] characters) {
+ int size = CharEncoding.getCharArraySize(characters);
+ if (characters.length > 1) size += FormatSpec.PTNODE_TERMINATOR_SIZE;
+ return size;
+ }
+
+ /**
+ * Compute the binary size of the character array in a PtNode
+ *
+ * If only one character, this is the size of this character. If many, it's the sum of their
+ * sizes + 1 byte for the terminator.
+ *
+ * @param ptNode the PtNode
+ * @return the size of the char array, including the terminator if any
+ */
+ private static int getPtNodeCharactersSize(final PtNode ptNode) {
+ return getPtNodeCharactersSize(ptNode.mChars);
+ }
+
+ /**
+ * Compute the binary size of the PtNode count for a node array.
+ * @param nodeArray the nodeArray
+ * @return the size of the PtNode count, either 1 or 2 bytes.
+ */
+ private static int getPtNodeCountSize(final PtNodeArray nodeArray) {
+ return BinaryDictIOUtils.getPtNodeCountSize(nodeArray.mData.size());
+ }
+
+ /**
+ * Compute the size of a shortcut in bytes.
+ */
+ private static int getShortcutSize(final WeightedString shortcut) {
+ int size = FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
+ final String word = shortcut.mWord;
+ final int length = word.length();
+ for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
+ final int codePoint = word.codePointAt(i);
+ size += CharEncoding.getCharSize(codePoint);
+ }
+ size += FormatSpec.PTNODE_TERMINATOR_SIZE;
+ return size;
+ }
+
+ /**
+ * Compute the size of a shortcut list in bytes.
+ *
+ * This is known in advance and does not change according to position in the file
+ * like address lists do.
+ */
+ static int getShortcutListSize(final ArrayList<WeightedString> shortcutList) {
+ if (null == shortcutList || shortcutList.isEmpty()) return 0;
+ int size = FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE;
+ for (final WeightedString shortcut : shortcutList) {
+ size += getShortcutSize(shortcut);
+ }
+ return size;
+ }
+
+ /**
+ * Compute the maximum size of a PtNode, assuming 3-byte addresses for everything.
+ *
+ * @param ptNode the PtNode to compute the size of.
+ * @param options file format options.
+ * @return the maximum size of the PtNode.
+ */
+ private static int getPtNodeMaximumSize(final PtNode ptNode, final FormatOptions options) {
+ int size = getNodeHeaderSize(ptNode, options);
+ if (ptNode.isTerminal()) {
+ // If terminal, one byte for the frequency or four bytes for the terminal id.
+ if (options.mHasTerminalId) {
+ size += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+ } else {
+ size += FormatSpec.PTNODE_FREQUENCY_SIZE;
+ }
+ }
+ size += FormatSpec.PTNODE_MAX_ADDRESS_SIZE; // For children address
+ size += getShortcutListSize(ptNode.mShortcutTargets);
+ if (null != ptNode.mBigrams) {
+ size += (FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE
+ + FormatSpec.PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE)
+ * ptNode.mBigrams.size();
+ }
+ return size;
+ }
+
+ /**
+ * Compute the maximum size of each PtNode of a PtNode array, assuming 3-byte addresses for
+ * everything, and caches it in the `mCachedSize' member of the nodes; deduce the size of
+ * the containing node array, and cache it it its 'mCachedSize' member.
+ *
+ * @param ptNodeArray the node array to compute the maximum size of.
+ * @param options file format options.
+ */
+ private static void calculatePtNodeArrayMaximumSize(final PtNodeArray ptNodeArray,
+ final FormatOptions options) {
+ int size = getPtNodeCountSize(ptNodeArray);
+ for (PtNode node : ptNodeArray.mData) {
+ final int nodeSize = getPtNodeMaximumSize(node, options);
+ node.mCachedSize = nodeSize;
+ size += nodeSize;
+ }
+ if (options.mSupportsDynamicUpdate) {
+ size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
+ }
+ ptNodeArray.mCachedSize = size;
+ }
+
+ /**
+ * Compute the size of the header (flag + [parent address] + characters size) of a PtNode.
+ *
+ * @param ptNode the PtNode of which to compute the size of the header
+ * @param options file format options.
+ */
+ private static int getNodeHeaderSize(final PtNode ptNode, final FormatOptions options) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(options)) {
+ return FormatSpec.PTNODE_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
+ + getPtNodeCharactersSize(ptNode);
+ } else {
+ return FormatSpec.PTNODE_FLAGS_SIZE + getPtNodeCharactersSize(ptNode);
+ }
+ }
+
+ /**
+ * Compute the size, in bytes, that an address will occupy.
+ *
+ * This can be used either for children addresses (which are always positive) or for
+ * attribute, which may be positive or negative but
+ * store their sign bit separately.
+ *
+ * @param address the address
+ * @return the byte size.
+ */
+ static int getByteSize(final int address) {
+ assert(address <= FormatSpec.UINT24_MAX);
+ if (!BinaryDictIOUtils.hasChildrenAddress(address)) {
+ return 0;
+ } else if (Math.abs(address) <= FormatSpec.UINT8_MAX) {
+ return 1;
+ } else if (Math.abs(address) <= FormatSpec.UINT16_MAX) {
+ return 2;
+ } else {
+ return 3;
+ }
+ }
+
+ static int writeUIntToBuffer(final byte[] buffer, int position, final int value,
+ final int size) {
+ switch(size) {
+ case 4:
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ /* fall through */
+ case 3:
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ /* fall through */
+ case 2:
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ /* fall through */
+ case 1:
+ buffer[position++] = (byte) (value & 0xFF);
+ break;
+ default:
+ /* nop */
+ }
+ return position;
+ }
+
+ // End utility methods
+
+ // This method is responsible for finding a nice ordering of the nodes that favors run-time
+ // cache performance and dictionary size.
+ /* package for tests */ static ArrayList<PtNodeArray> flattenTree(
+ final PtNodeArray rootNodeArray) {
+ final int treeSize = FusionDictionary.countPtNodes(rootNodeArray);
+ MakedictLog.i("Counted nodes : " + treeSize);
+ final ArrayList<PtNodeArray> flatTree = new ArrayList<PtNodeArray>(treeSize);
+ return flattenTreeInner(flatTree, rootNodeArray);
+ }
+
+ private static ArrayList<PtNodeArray> flattenTreeInner(final ArrayList<PtNodeArray> list,
+ final PtNodeArray ptNodeArray) {
+ // Removing the node is necessary if the tails are merged, because we would then
+ // add the same node several times when we only want it once. A number of places in
+ // the code also depends on any node being only once in the list.
+ // Merging tails can only be done if there are no attributes. Searching for attributes
+ // in LatinIME code depends on a total breadth-first ordering, which merging tails
+ // breaks. If there are no attributes, it should be fine (and reduce the file size)
+ // to merge tails, and removing the node from the list would be necessary. However,
+ // we don't merge tails because breaking the breadth-first ordering would result in
+ // extreme overhead at bigram lookup time (it would make the search function O(n) instead
+ // of the current O(log(n)), where n=number of nodes in the dictionary which is pretty
+ // high).
+ // If no nodes are ever merged, we can't have the same node twice in the list, hence
+ // searching for duplicates in unnecessary. It is also very performance consuming,
+ // since `list' is an ArrayList so it's an O(n) operation that runs on all nodes, making
+ // this simple list.remove operation O(n*n) overall. On Android this overhead is very
+ // high.
+ // For future reference, the code to remove duplicate is a simple : list.remove(node);
+ list.add(ptNodeArray);
+ final ArrayList<PtNode> branches = ptNodeArray.mData;
+ final int nodeSize = branches.size();
+ for (PtNode ptNode : branches) {
+ if (null != ptNode.mChildren) flattenTreeInner(list, ptNode.mChildren);
+ }
+ return list;
+ }
+
+ /**
+ * Get the offset from a position inside a current node array to a target node array, during
+ * update.
+ *
+ * If the current node array is before the target node array, the target node array has not
+ * been updated yet, so we should return the offset from the old position of the current node
+ * array to the old position of the target node array. If on the other hand the target is
+ * before the current node array, it already has been updated, so we should return the offset
+ * from the new position in the current node array to the new position in the target node
+ * array.
+ *
+ * @param currentNodeArray node array containing the PtNode where the offset will be written
+ * @param offsetFromStartOfCurrentNodeArray offset, in bytes, from the start of currentNodeArray
+ * @param targetNodeArray the target node array to get the offset to
+ * @return the offset to the target node array
+ */
+ private static int getOffsetToTargetNodeArrayDuringUpdate(final PtNodeArray currentNodeArray,
+ final int offsetFromStartOfCurrentNodeArray, final PtNodeArray targetNodeArray) {
+ final boolean isTargetBeforeCurrent = (targetNodeArray.mCachedAddressBeforeUpdate
+ < currentNodeArray.mCachedAddressBeforeUpdate);
+ if (isTargetBeforeCurrent) {
+ return targetNodeArray.mCachedAddressAfterUpdate
+ - (currentNodeArray.mCachedAddressAfterUpdate
+ + offsetFromStartOfCurrentNodeArray);
+ } else {
+ return targetNodeArray.mCachedAddressBeforeUpdate
+ - (currentNodeArray.mCachedAddressBeforeUpdate
+ + offsetFromStartOfCurrentNodeArray);
+ }
+ }
+
+ /**
+ * Get the offset from a position inside a current node array to a target PtNode, during
+ * update.
+ *
+ * @param currentNodeArray node array containing the PtNode where the offset will be written
+ * @param offsetFromStartOfCurrentNodeArray offset, in bytes, from the start of currentNodeArray
+ * @param targetPtNode the target PtNode to get the offset to
+ * @return the offset to the target PtNode
+ */
+ // TODO: is there any way to factorize this method with the one above?
+ private static int getOffsetToTargetPtNodeDuringUpdate(final PtNodeArray currentNodeArray,
+ final int offsetFromStartOfCurrentNodeArray, final PtNode targetPtNode) {
+ final int oldOffsetBasePoint = currentNodeArray.mCachedAddressBeforeUpdate
+ + offsetFromStartOfCurrentNodeArray;
+ final boolean isTargetBeforeCurrent = (targetPtNode.mCachedAddressBeforeUpdate
+ < oldOffsetBasePoint);
+ // If the target is before the current node array, then its address has already been
+ // updated. We can use the AfterUpdate member, and compare it to our own member after
+ // update. Otherwise, the AfterUpdate member is not updated yet, so we need to use the
+ // BeforeUpdate member, and of course we have to compare this to our own address before
+ // update.
+ if (isTargetBeforeCurrent) {
+ final int newOffsetBasePoint = currentNodeArray.mCachedAddressAfterUpdate
+ + offsetFromStartOfCurrentNodeArray;
+ return targetPtNode.mCachedAddressAfterUpdate - newOffsetBasePoint;
+ } else {
+ return targetPtNode.mCachedAddressBeforeUpdate - oldOffsetBasePoint;
+ }
+ }
+
+ /**
+ * Computes the actual node array size, based on the cached addresses of the children nodes.
+ *
+ * Each node array stores its tentative address. During dictionary address computing, these
+ * are not final, but they can be used to compute the node array size (the node array size
+ * depends on the address of the children because the number of bytes necessary to store an
+ * address depends on its numeric value. The return value indicates whether the node array
+ * contents (as in, any of the addresses stored in the cache fields) have changed with
+ * respect to their previous value.
+ *
+ * @param ptNodeArray the node array to compute the size of.
+ * @param dict the dictionary in which the word/attributes are to be found.
+ * @param formatOptions file format options.
+ * @return false if none of the cached addresses inside the node array changed, true otherwise.
+ */
+ private static boolean computeActualPtNodeArraySize(final PtNodeArray ptNodeArray,
+ final FusionDictionary dict, final FormatOptions formatOptions) {
+ boolean changed = false;
+ int size = getPtNodeCountSize(ptNodeArray);
+ for (PtNode ptNode : ptNodeArray.mData) {
+ ptNode.mCachedAddressAfterUpdate = ptNodeArray.mCachedAddressAfterUpdate + size;
+ if (ptNode.mCachedAddressAfterUpdate != ptNode.mCachedAddressBeforeUpdate) {
+ changed = true;
+ }
+ int nodeSize = getNodeHeaderSize(ptNode, formatOptions);
+ if (ptNode.isTerminal()) {
+ if (formatOptions.mHasTerminalId) {
+ nodeSize += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+ } else {
+ nodeSize += FormatSpec.PTNODE_FREQUENCY_SIZE;
+ }
+ }
+ if (formatOptions.mSupportsDynamicUpdate) {
+ nodeSize += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
+ } else if (null != ptNode.mChildren) {
+ nodeSize += getByteSize(getOffsetToTargetNodeArrayDuringUpdate(ptNodeArray,
+ nodeSize + size, ptNode.mChildren));
+ }
+ nodeSize += getShortcutListSize(ptNode.mShortcutTargets);
+ if (null != ptNode.mBigrams) {
+ for (WeightedString bigram : ptNode.mBigrams) {
+ final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray,
+ nodeSize + size + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE,
+ FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord));
+ nodeSize += getByteSize(offset) + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
+ }
+ }
+ ptNode.mCachedSize = nodeSize;
+ size += nodeSize;
+ }
+ if (formatOptions.mSupportsDynamicUpdate) {
+ size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
+ }
+ if (ptNodeArray.mCachedSize != size) {
+ ptNodeArray.mCachedSize = size;
+ changed = true;
+ }
+ return changed;
+ }
+
+ /**
+ * Initializes the cached addresses of node arrays and their containing nodes from their size.
+ *
+ * @param flatNodes the list of node arrays.
+ * @param formatOptions file format options.
+ * @return the byte size of the entire stack.
+ */
+ private static int initializePtNodeArraysCachedAddresses(final ArrayList<PtNodeArray> flatNodes,
+ final FormatOptions formatOptions) {
+ int nodeArrayOffset = 0;
+ for (final PtNodeArray nodeArray : flatNodes) {
+ nodeArray.mCachedAddressBeforeUpdate = nodeArrayOffset;
+ int nodeCountSize = getPtNodeCountSize(nodeArray);
+ int nodeffset = 0;
+ for (final PtNode ptNode : nodeArray.mData) {
+ ptNode.mCachedAddressBeforeUpdate = ptNode.mCachedAddressAfterUpdate =
+ nodeCountSize + nodeArrayOffset + nodeffset;
+ nodeffset += ptNode.mCachedSize;
+ }
+ final int nodeSize = nodeCountSize + nodeffset
+ + (formatOptions.mSupportsDynamicUpdate
+ ? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
+ nodeArrayOffset += nodeArray.mCachedSize;
+ }
+ return nodeArrayOffset;
+ }
+
+ /**
+ * Updates the cached addresses of node arrays after recomputing their new positions.
+ *
+ * @param flatNodes the list of node arrays.
+ */
+ private static void updatePtNodeArraysCachedAddresses(final ArrayList<PtNodeArray> flatNodes) {
+ for (final PtNodeArray nodeArray : flatNodes) {
+ nodeArray.mCachedAddressBeforeUpdate = nodeArray.mCachedAddressAfterUpdate;
+ for (final PtNode ptNode : nodeArray.mData) {
+ ptNode.mCachedAddressBeforeUpdate = ptNode.mCachedAddressAfterUpdate;
+ }
+ }
+ }
+
+ /**
+ * Compute the cached parent addresses after all has been updated.
+ *
+ * The parent addresses are used by some binary formats at write-to-disk time. Not all formats
+ * need them. In particular, version 2 does not need them, and version 3 does.
+ *
+ * @param flatNodes the flat array of node arrays to fill in
+ */
+ private static void computeParentAddresses(final ArrayList<PtNodeArray> flatNodes) {
+ for (final PtNodeArray nodeArray : flatNodes) {
+ for (final PtNode ptNode : nodeArray.mData) {
+ if (null != ptNode.mChildren) {
+ // Assign my address to children's parent address
+ // Here BeforeUpdate and AfterUpdate addresses have the same value, so it
+ // does not matter which we use.
+ ptNode.mChildren.mCachedParentAddress = ptNode.mCachedAddressAfterUpdate
+ - ptNode.mChildren.mCachedAddressAfterUpdate;
+ }
+ }
+ }
+ }
+
+ /**
+ * Compute the addresses and sizes of an ordered list of PtNode arrays.
+ *
+ * This method takes a list of PtNode arrays and will update their cached address and size
+ * values so that they can be written into a file. It determines the smallest size each of the
+ * PtNode arrays can be given the addresses of its children and attributes, and store that into
+ * each PtNode.
+ * The order of the PtNode is given by the order of the array. This method makes no effort
+ * to find a good order; it only mechanically computes the size this order results in.
+ *
+ * @param dict the dictionary
+ * @param flatNodes the ordered list of PtNode arrays
+ * @param formatOptions file format options.
+ * @return the same array it was passed. The nodes have been updated for address and size.
+ */
+ /* package */ static ArrayList<PtNodeArray> computeAddresses(final FusionDictionary dict,
+ final ArrayList<PtNodeArray> flatNodes, final FormatOptions formatOptions) {
+ // First get the worst possible sizes and offsets
+ for (final PtNodeArray n : flatNodes) calculatePtNodeArrayMaximumSize(n, formatOptions);
+ final int offset = initializePtNodeArraysCachedAddresses(flatNodes, formatOptions);
+
+ MakedictLog.i("Compressing the array addresses. Original size : " + offset);
+ MakedictLog.i("(Recursively seen size : " + offset + ")");
+
+ int passes = 0;
+ boolean changesDone = false;
+ do {
+ changesDone = false;
+ int ptNodeArrayStartOffset = 0;
+ for (final PtNodeArray ptNodeArray : flatNodes) {
+ ptNodeArray.mCachedAddressAfterUpdate = ptNodeArrayStartOffset;
+ final int oldNodeArraySize = ptNodeArray.mCachedSize;
+ final boolean changed =
+ computeActualPtNodeArraySize(ptNodeArray, dict, formatOptions);
+ final int newNodeArraySize = ptNodeArray.mCachedSize;
+ if (oldNodeArraySize < newNodeArraySize) {
+ throw new RuntimeException("Increased size ?!");
+ }
+ ptNodeArrayStartOffset += newNodeArraySize;
+ changesDone |= changed;
+ }
+ updatePtNodeArraysCachedAddresses(flatNodes);
+ ++passes;
+ if (passes > MAX_PASSES) throw new RuntimeException("Too many passes - probably a bug");
+ } while (changesDone);
+
+ if (formatOptions.mSupportsDynamicUpdate) {
+ computeParentAddresses(flatNodes);
+ }
+ final PtNodeArray lastPtNodeArray = flatNodes.get(flatNodes.size() - 1);
+ MakedictLog.i("Compression complete in " + passes + " passes.");
+ MakedictLog.i("After address compression : "
+ + (lastPtNodeArray.mCachedAddressAfterUpdate + lastPtNodeArray.mCachedSize));
+
+ return flatNodes;
+ }
+
+ /**
+ * Sanity-checking method.
+ *
+ * This method checks a list of PtNode arrays for juxtaposition, that is, it will do
+ * nothing if each node array's cached address is actually the previous node array's address
+ * plus the previous node's size.
+ * If this is not the case, it will throw an exception.
+ *
+ * @param arrays the list of node arrays to check
+ */
+ /* package */ static void checkFlatPtNodeArrayList(final ArrayList<PtNodeArray> arrays) {
+ int offset = 0;
+ int index = 0;
+ for (final PtNodeArray ptNodeArray : arrays) {
+ // BeforeUpdate and AfterUpdate addresses are the same here, so it does not matter
+ // which we use.
+ if (ptNodeArray.mCachedAddressAfterUpdate != offset) {
+ throw new RuntimeException("Wrong address for node " + index
+ + " : expected " + offset + ", got " +
+ ptNodeArray.mCachedAddressAfterUpdate);
+ }
+ ++index;
+ offset += ptNodeArray.mCachedSize;
+ }
+ }
+
+ /**
+ * Helper method to write a children position to a file.
+ *
+ * @param buffer the buffer to write to.
+ * @param index the index in the buffer to write the address to.
+ * @param position the position to write.
+ * @return the size in bytes the address actually took.
+ */
+ /* package */ static int writeChildrenPosition(final byte[] buffer, int index,
+ final int position) {
+ switch (getByteSize(position)) {
+ case 1:
+ buffer[index++] = (byte)position;
+ return 1;
+ case 2:
+ buffer[index++] = (byte)(0xFF & (position >> 8));
+ buffer[index++] = (byte)(0xFF & position);
+ return 2;
+ case 3:
+ buffer[index++] = (byte)(0xFF & (position >> 16));
+ buffer[index++] = (byte)(0xFF & (position >> 8));
+ buffer[index++] = (byte)(0xFF & position);
+ return 3;
+ case 0:
+ return 0;
+ default:
+ throw new RuntimeException("Position " + position + " has a strange size");
+ }
+ }
+
+ /**
+ * Helper method to write a signed children position to a file.
+ *
+ * @param buffer the buffer to write to.
+ * @param index the index in the buffer to write the address to.
+ * @param position the position to write.
+ * @return the size in bytes the address actually took.
+ */
+ /* package */ static int writeSignedChildrenPosition(final byte[] buffer, int index,
+ final int position) {
+ if (!BinaryDictIOUtils.hasChildrenAddress(position)) {
+ buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
+ } else {
+ final int absPosition = Math.abs(position);
+ buffer[index++] =
+ (byte)((position < 0 ? FormatSpec.MSB8 : 0) | (0xFF & (absPosition >> 16)));
+ buffer[index++] = (byte)(0xFF & (absPosition >> 8));
+ buffer[index++] = (byte)(0xFF & absPosition);
+ }
+ return 3;
+ }
+
+ /**
+ * Makes the flag value for a PtNode.
+ *
+ * @param hasMultipleChars whether the PtNode has multiple chars.
+ * @param isTerminal whether the PtNode is terminal.
+ * @param childrenAddressSize the size of a children address.
+ * @param hasShortcuts whether the PtNode has shortcuts.
+ * @param hasBigrams whether the PtNode has bigrams.
+ * @param isNotAWord whether the PtNode is not a word.
+ * @param isBlackListEntry whether the PtNode is a blacklist entry.
+ * @param formatOptions file format options.
+ * @return the flags
+ */
+ static int makePtNodeFlags(final boolean hasMultipleChars, final boolean isTerminal,
+ final int childrenAddressSize, final boolean hasShortcuts, final boolean hasBigrams,
+ final boolean isNotAWord, final boolean isBlackListEntry,
+ final FormatOptions formatOptions) {
+ byte flags = 0;
+ if (hasMultipleChars) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
+ if (isTerminal) flags |= FormatSpec.FLAG_IS_TERMINAL;
+ if (formatOptions.mSupportsDynamicUpdate) {
+ flags |= FormatSpec.FLAG_IS_NOT_MOVED;
+ } else if (true) {
+ switch (childrenAddressSize) {
+ case 1:
+ flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE;
+ break;
+ case 2:
+ flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES;
+ break;
+ case 3:
+ flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES;
+ break;
+ case 0:
+ flags |= FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS;
+ break;
+ default:
+ throw new RuntimeException("Node with a strange address");
+ }
+ }
+ if (hasShortcuts) flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS;
+ if (hasBigrams) flags |= FormatSpec.FLAG_HAS_BIGRAMS;
+ if (isNotAWord) flags |= FormatSpec.FLAG_IS_NOT_A_WORD;
+ if (isBlackListEntry) flags |= FormatSpec.FLAG_IS_BLACKLISTED;
+ return flags;
+ }
+
+ /* package */ static byte makePtNodeFlags(final PtNode node, final int ptNodeAddress,
+ final int childrenOffset, final FormatOptions formatOptions) {
+ return (byte) makePtNodeFlags(node.mChars.length > 1, node.mFrequency >= 0,
+ getByteSize(childrenOffset),
+ node.mShortcutTargets != null && !node.mShortcutTargets.isEmpty(),
+ node.mBigrams != null, node.mIsNotAWord, node.mIsBlacklistEntry, formatOptions);
+ }
+
+ /**
+ * Makes the flag value for a bigram.
+ *
+ * @param more whether there are more bigrams after this one.
+ * @param offset the offset of the bigram.
+ * @param bigramFrequency the frequency of the bigram, 0..255.
+ * @param unigramFrequency the unigram frequency of the same word, 0..255.
+ * @param word the second bigram, for debugging purposes
+ * @return the flags
+ */
+ /* package */ static final int makeBigramFlags(final boolean more, final int offset,
+ int bigramFrequency, final int unigramFrequency, final String word) {
+ int bigramFlags = (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0)
+ + (offset < 0 ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0);
+ switch (getByteSize(offset)) {
+ case 1:
+ bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE;
+ break;
+ case 2:
+ bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES;
+ break;
+ case 3:
+ bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES;
+ break;
+ default:
+ throw new RuntimeException("Strange offset size");
+ }
+ if (unigramFrequency > bigramFrequency) {
+ MakedictLog.e("Unigram freq is superior to bigram freq for \"" + word
+ + "\". Bigram freq is " + bigramFrequency + ", unigram freq for "
+ + word + " is " + unigramFrequency);
+ bigramFrequency = unigramFrequency;
+ }
+ // We compute the difference between 255 (which means probability = 1) and the
+ // unigram score. We split this into a number of discrete steps.
+ // Now, the steps are numbered 0~15; 0 represents an increase of 1 step while 15
+ // represents an increase of 16 steps: a value of 15 will be interpreted as the median
+ // value of the 16th step. In all justice, if the bigram frequency is low enough to be
+ // rounded below the first step (which means it is less than half a step higher than the
+ // unigram frequency) then the unigram frequency itself is the best approximation of the
+ // bigram freq that we could possibly supply, hence we should *not* include this bigram
+ // in the file at all.
+ // until this is done, we'll write 0 and slightly overestimate this case.
+ // In other words, 0 means "between 0.5 step and 1.5 step", 1 means "between 1.5 step
+ // and 2.5 steps", and 15 means "between 15.5 steps and 16.5 steps". So we want to
+ // divide our range [unigramFreq..MAX_TERMINAL_FREQUENCY] in 16.5 steps to get the
+ // step size. Then we compute the start of the first step (the one where value 0 starts)
+ // by adding half-a-step to the unigramFrequency. From there, we compute the integer
+ // number of steps to the bigramFrequency. One last thing: we want our steps to include
+ // their lower bound and exclude their higher bound so we need to have the first step
+ // start at exactly 1 unit higher than floor(unigramFreq + half a step).
+ // Note : to reconstruct the score, the dictionary reader will need to divide
+ // MAX_TERMINAL_FREQUENCY - unigramFreq by 16.5 likewise to get the value of the step,
+ // and add (discretizedFrequency + 0.5 + 0.5) times this value to get the best
+ // approximation. (0.5 to get the first step start, and 0.5 to get the middle of the
+ // step pointed by the discretized frequency.
+ final float stepSize =
+ (FormatSpec.MAX_TERMINAL_FREQUENCY - unigramFrequency)
+ / (1.5f + FormatSpec.MAX_BIGRAM_FREQUENCY);
+ final float firstStepStart = 1 + unigramFrequency + (stepSize / 2.0f);
+ final int discretizedFrequency = (int)((bigramFrequency - firstStepStart) / stepSize);
+ // If the bigram freq is less than half-a-step higher than the unigram freq, we get -1
+ // here. The best approximation would be the unigram freq itself, so we should not
+ // include this bigram in the dictionary. For now, register as 0, and live with the
+ // small over-estimation that we get in this case. TODO: actually remove this bigram
+ // if discretizedFrequency < 0.
+ final int finalBigramFrequency = discretizedFrequency > 0 ? discretizedFrequency : 0;
+ bigramFlags += finalBigramFrequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY;
+ return bigramFlags;
+ }
+
+ /**
+ * Makes the 2-byte value for options flags.
+ */
+ private static final int makeOptionsValue(final FusionDictionary dictionary,
+ final FormatOptions formatOptions) {
+ final DictionaryOptions options = dictionary.mOptions;
+ final boolean hasBigrams = dictionary.hasBigrams();
+ return (options.mFrenchLigatureProcessing ? FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG : 0)
+ + (options.mGermanUmlautProcessing ? FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG : 0)
+ + (hasBigrams ? FormatSpec.CONTAINS_BIGRAMS_FLAG : 0)
+ + (formatOptions.mSupportsDynamicUpdate ? FormatSpec.SUPPORTS_DYNAMIC_UPDATE : 0);
+ }
+
+ /**
+ * Makes the flag value for a shortcut.
+ *
+ * @param more whether there are more attributes after this one.
+ * @param frequency the frequency of the attribute, 0..15
+ * @return the flags
+ */
+ static final int makeShortcutFlags(final boolean more, final int frequency) {
+ return (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0)
+ + (frequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY);
+ }
+
+ /* package */ static final int writeParentAddress(final byte[] buffer, final int index,
+ final int address, final FormatOptions formatOptions) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ if (address == FormatSpec.NO_PARENT_ADDRESS) {
+ buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
+ } else {
+ final int absAddress = Math.abs(address);
+ assert(absAddress <= FormatSpec.SINT24_MAX);
+ buffer[index] = (byte)((address < 0 ? FormatSpec.MSB8 : 0)
+ | ((absAddress >> 16) & 0xFF));
+ buffer[index + 1] = (byte)((absAddress >> 8) & 0xFF);
+ buffer[index + 2] = (byte)(absAddress & 0xFF);
+ }
+ return index + 3;
+ } else {
+ return index;
+ }
+ }
+
+ /* package */ static final int getChildrenPosition(final PtNode ptNode,
+ final FormatOptions formatOptions) {
+ int positionOfChildrenPosField = ptNode.mCachedAddressAfterUpdate
+ + getNodeHeaderSize(ptNode, formatOptions);
+ if (ptNode.isTerminal()) {
+ // A terminal node has either the terminal id or the frequency.
+ // If positionOfChildrenPosField is incorrect, we may crash when jumping to the children
+ // position.
+ if (formatOptions.mHasTerminalId) {
+ positionOfChildrenPosField += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+ } else {
+ positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
+ }
+ }
+ return null == ptNode.mChildren ? FormatSpec.NO_CHILDREN_ADDRESS
+ : ptNode.mChildren.mCachedAddressAfterUpdate - positionOfChildrenPosField;
+ }
+
+ /**
+ * Write a PtNodeArray. The PtNodeArray is expected to have its final position cached.
+ *
+ * @param dict the dictionary the node array is a part of (for relative offsets).
+ * @param dictEncoder the dictionary encoder.
+ * @param ptNodeArray the node array to write.
+ * @param formatOptions file format options.
+ */
+ @SuppressWarnings("unused")
+ /* package */ static void writePlacedPtNodeArray(final FusionDictionary dict,
+ final DictEncoder dictEncoder, final PtNodeArray ptNodeArray,
+ final FormatOptions formatOptions) {
+ // TODO: Make the code in common with BinaryDictIOUtils#writePtNode
+ dictEncoder.setPosition(ptNodeArray.mCachedAddressAfterUpdate);
+
+ final int ptNodeCount = ptNodeArray.mData.size();
+ dictEncoder.writePtNodeCount(ptNodeCount);
+ final int parentPosition =
+ (ptNodeArray.mCachedParentAddress == FormatSpec.NO_PARENT_ADDRESS)
+ ? FormatSpec.NO_PARENT_ADDRESS
+ : ptNodeArray.mCachedParentAddress + ptNodeArray.mCachedAddressAfterUpdate;
+ for (int i = 0; i < ptNodeCount; ++i) {
+ final PtNode ptNode = ptNodeArray.mData.get(i);
+ if (dictEncoder.getPosition() != ptNode.mCachedAddressAfterUpdate) {
+ throw new RuntimeException("Bug: write index is not the same as the cached address "
+ + "of the node : " + dictEncoder.getPosition() + " <> "
+ + ptNode.mCachedAddressAfterUpdate);
+ }
+ // Sanity checks.
+ if (DBG && ptNode.mFrequency > FormatSpec.MAX_TERMINAL_FREQUENCY) {
+ throw new RuntimeException("A node has a frequency > "
+ + FormatSpec.MAX_TERMINAL_FREQUENCY
+ + " : " + ptNode.mFrequency);
+ }
+ dictEncoder.writePtNode(ptNode, parentPosition, formatOptions, dict);
+ }
+ if (formatOptions.mSupportsDynamicUpdate) {
+ dictEncoder.writeForwardLinkAddress(FormatSpec.NO_FORWARD_LINK_ADDRESS);
+ }
+ if (dictEncoder.getPosition() != ptNodeArray.mCachedAddressAfterUpdate
+ + ptNodeArray.mCachedSize) {
+ throw new RuntimeException("Not the same size : written "
+ + (dictEncoder.getPosition() - ptNodeArray.mCachedAddressAfterUpdate)
+ + " bytes from a node that should have " + ptNodeArray.mCachedSize + " bytes");
+ }
+ }
+
+ /**
+ * Dumps a collection of useful statistics about a list of PtNode arrays.
+ *
+ * This prints purely informative stuff, like the total estimated file size, the
+ * number of PtNode arrays, of PtNodes, the repartition of each address size, etc
+ *
+ * @param ptNodeArrays the list of PtNode arrays.
+ */
+ /* package */ static void showStatistics(ArrayList<PtNodeArray> ptNodeArrays) {
+ int firstTerminalAddress = Integer.MAX_VALUE;
+ int lastTerminalAddress = Integer.MIN_VALUE;
+ int size = 0;
+ int ptNodes = 0;
+ int maxNodes = 0;
+ int maxRuns = 0;
+ for (final PtNodeArray ptNodeArray : ptNodeArrays) {
+ if (maxNodes < ptNodeArray.mData.size()) maxNodes = ptNodeArray.mData.size();
+ for (final PtNode ptNode : ptNodeArray.mData) {
+ ++ptNodes;
+ if (ptNode.mChars.length > maxRuns) maxRuns = ptNode.mChars.length;
+ if (ptNode.mFrequency >= 0) {
+ if (ptNodeArray.mCachedAddressAfterUpdate < firstTerminalAddress)
+ firstTerminalAddress = ptNodeArray.mCachedAddressAfterUpdate;
+ if (ptNodeArray.mCachedAddressAfterUpdate > lastTerminalAddress)
+ lastTerminalAddress = ptNodeArray.mCachedAddressAfterUpdate;
+ }
+ }
+ if (ptNodeArray.mCachedAddressAfterUpdate + ptNodeArray.mCachedSize > size) {
+ size = ptNodeArray.mCachedAddressAfterUpdate + ptNodeArray.mCachedSize;
+ }
+ }
+ final int[] ptNodeCounts = new int[maxNodes + 1];
+ final int[] runCounts = new int[maxRuns + 1];
+ for (final PtNodeArray ptNodeArray : ptNodeArrays) {
+ ++ptNodeCounts[ptNodeArray.mData.size()];
+ for (final PtNode ptNode : ptNodeArray.mData) {
+ ++runCounts[ptNode.mChars.length];
+ }
+ }
+
+ MakedictLog.i("Statistics:\n"
+ + " total file size " + size + "\n"
+ + " " + ptNodeArrays.size() + " node arrays\n"
+ + " " + ptNodes + " PtNodes (" + ((float)ptNodes / ptNodeArrays.size())
+ + " PtNodes per node)\n"
+ + " first terminal at " + firstTerminalAddress + "\n"
+ + " last terminal at " + lastTerminalAddress + "\n"
+ + " PtNode stats : max = " + maxNodes);
+ for (int i = 0; i < ptNodeCounts.length; ++i) {
+ MakedictLog.i(" " + i + " : " + ptNodeCounts[i]);
+ }
+ MakedictLog.i(" Character run stats : max = " + maxRuns);
+ for (int i = 0; i < runCounts.length; ++i) {
+ MakedictLog.i(" " + i + " : " + runCounts[i]);
+ }
+ }
+
+ /**
+ * Writes a file header to an output stream.
+ *
+ * @param destination the stream to write the file header to.
+ * @param dict the dictionary to write.
+ * @param formatOptions file format options.
+ */
+ /* package */ static void writeDictionaryHeader(final OutputStream destination,
+ final FusionDictionary dict, final FormatOptions formatOptions)
+ throws IOException, UnsupportedFormatException {
+ final int version = formatOptions.mVersion;
+ if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
+ || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
+ throw new UnsupportedFormatException("Requested file format version " + version
+ + ", but this implementation only supports versions "
+ + FormatSpec.MINIMUM_SUPPORTED_VERSION + " through "
+ + FormatSpec.MAXIMUM_SUPPORTED_VERSION);
+ }
+
+ ByteArrayOutputStream headerBuffer = new ByteArrayOutputStream(256);
+
+ // The magic number in big-endian order.
+ // Magic number for all versions.
+ headerBuffer.write((byte) (0xFF & (FormatSpec.MAGIC_NUMBER >> 24)));
+ headerBuffer.write((byte) (0xFF & (FormatSpec.MAGIC_NUMBER >> 16)));
+ headerBuffer.write((byte) (0xFF & (FormatSpec.MAGIC_NUMBER >> 8)));
+ headerBuffer.write((byte) (0xFF & FormatSpec.MAGIC_NUMBER));
+ // Dictionary version.
+ headerBuffer.write((byte) (0xFF & (version >> 8)));
+ headerBuffer.write((byte) (0xFF & version));
+
+ // Options flags
+ final int options = makeOptionsValue(dict, formatOptions);
+ headerBuffer.write((byte) (0xFF & (options >> 8)));
+ headerBuffer.write((byte) (0xFF & options));
+ final int headerSizeOffset = headerBuffer.size();
+ // Placeholder to be written later with header size.
+ for (int i = 0; i < 4; ++i) {
+ headerBuffer.write(0);
+ }
+ // Write out the options.
+ for (final String key : dict.mOptions.mAttributes.keySet()) {
+ final String value = dict.mOptions.mAttributes.get(key);
+ CharEncoding.writeString(headerBuffer, key);
+ CharEncoding.writeString(headerBuffer, value);
+ }
+ final int size = headerBuffer.size();
+ final byte[] bytes = headerBuffer.toByteArray();
+ // Write out the header size.
+ bytes[headerSizeOffset] = (byte) (0xFF & (size >> 24));
+ bytes[headerSizeOffset + 1] = (byte) (0xFF & (size >> 16));
+ bytes[headerSizeOffset + 2] = (byte) (0xFF & (size >> 8));
+ bytes[headerSizeOffset + 3] = (byte) (0xFF & (size >> 0));
+ destination.write(bytes);
+
+ headerBuffer.close();
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 167c6915c..a282f595c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -18,56 +18,52 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.CharEncoding;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
-import java.nio.channels.FileChannel;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
public final class BinaryDictIOUtils {
private static final boolean DBG = false;
- private static final int MSB24 = 0x800000;
- private static final int SINT24_MAX = 0x7FFFFF;
- private static final int MAX_JUMPS = 10000;
private BinaryDictIOUtils() {
// This utility class is not publicly instantiable.
}
private static final class Position {
- public static final int NOT_READ_GROUPCOUNT = -1;
+ public static final int NOT_READ_PTNODE_COUNT = -1;
public int mAddress;
- public int mNumOfCharGroup;
+ public int mNumOfPtNode;
public int mPosition;
public int mLength;
public Position(int address, int length) {
mAddress = address;
mLength = length;
- mNumOfCharGroup = NOT_READ_GROUPCOUNT;
+ mNumOfPtNode = NOT_READ_PTNODE_COUNT;
}
}
/**
- * Tours all node without recursive call.
+ * Retrieves all node arrays without recursive call.
*/
- private static void readUnigramsAndBigramsBinaryInner(
- final FusionDictionaryBufferInterface buffer, final int headerSize,
- final Map<Integer, String> words, final Map<Integer, Integer> frequencies,
+ private static void readUnigramsAndBigramsBinaryInner(final DictDecoder dictDecoder,
+ final int headerSize, final Map<Integer, String> words,
+ final Map<Integer, Integer> frequencies,
final Map<Integer, ArrayList<PendingAttribute>> bigrams,
final FormatOptions formatOptions) {
int[] pushedChars = new int[FormatSpec.MAX_WORD_LENGTH + 1];
@@ -82,47 +78,47 @@ public final class BinaryDictIOUtils {
Position p = stack.peek();
if (DBG) {
- MakedictLog.d("read: address=" + p.mAddress + ", numOfCharGroup=" +
- p.mNumOfCharGroup + ", position=" + p.mPosition + ", length=" + p.mLength);
+ MakedictLog.d("read: address=" + p.mAddress + ", numOfPtNode=" +
+ p.mNumOfPtNode + ", position=" + p.mPosition + ", length=" + p.mLength);
}
- if (buffer.position() != p.mAddress) buffer.position(p.mAddress);
+ if (dictDecoder.getPosition() != p.mAddress) dictDecoder.setPosition(p.mAddress);
if (index != p.mLength) index = p.mLength;
- if (p.mNumOfCharGroup == Position.NOT_READ_GROUPCOUNT) {
- p.mNumOfCharGroup = BinaryDictInputOutput.readCharGroupCount(buffer);
- p.mAddress += BinaryDictInputOutput.getGroupCountSize(p.mNumOfCharGroup);
+ if (p.mNumOfPtNode == Position.NOT_READ_PTNODE_COUNT) {
+ p.mNumOfPtNode = dictDecoder.readPtNodeCount();
+ p.mAddress += getPtNodeCountSize(p.mNumOfPtNode);
p.mPosition = 0;
}
- if (p.mNumOfCharGroup == 0) {
+ if (p.mNumOfPtNode == 0) {
stack.pop();
continue;
}
- CharGroupInfo info = BinaryDictInputOutput.readCharGroup(buffer,
- p.mAddress - headerSize, formatOptions);
+ PtNodeInfo info = dictDecoder.readPtNode(p.mAddress, formatOptions);
for (int i = 0; i < info.mCharacters.length; ++i) {
pushedChars[index++] = info.mCharacters[i];
}
p.mPosition++;
- final boolean isMovedGroup = BinaryDictInputOutput.isMovedGroup(info.mFlags,
+ final boolean isMovedPtNode = isMovedPtNode(info.mFlags,
formatOptions);
- final boolean isDeletedGroup = BinaryDictInputOutput.isDeletedGroup(info.mFlags,
+ final boolean isDeletedPtNode = isDeletedPtNode(info.mFlags,
formatOptions);
- if (!isMovedGroup && !isDeletedGroup
- && info.mFrequency != FusionDictionary.CharGroup.NOT_A_TERMINAL) {// found word
+ if (!isMovedPtNode && !isDeletedPtNode
+ && info.mFrequency != FusionDictionary.PtNode.NOT_A_TERMINAL) {// found word
words.put(info.mOriginalAddress, new String(pushedChars, 0, index));
frequencies.put(info.mOriginalAddress, info.mFrequency);
if (info.mBigrams != null) bigrams.put(info.mOriginalAddress, info.mBigrams);
}
- if (p.mPosition == p.mNumOfCharGroup) {
+ if (p.mPosition == p.mNumOfPtNode) {
if (formatOptions.mSupportsDynamicUpdate) {
- final int forwardLinkAddress = buffer.readUnsignedInt24();
- if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) {
- // the node has a forward link.
- p.mNumOfCharGroup = Position.NOT_READ_GROUPCOUNT;
- p.mAddress = forwardLinkAddress;
+ final boolean hasValidForwardLinkAddress =
+ dictDecoder.readAndFollowForwardLink();
+ if (hasValidForwardLinkAddress && dictDecoder.hasNextPtNodeArray()) {
+ // The node array has a forward link.
+ p.mNumOfPtNode = Position.NOT_READ_PTNODE_COUNT;
+ p.mAddress = dictDecoder.getPosition();
} else {
stack.pop();
}
@@ -130,12 +126,12 @@ public final class BinaryDictIOUtils {
stack.pop();
}
} else {
- // the node has more groups.
- p.mAddress = buffer.position();
+ // The Ptnode array has more PtNodes.
+ p.mAddress = dictDecoder.getPosition();
}
- if (!isMovedGroup && BinaryDictInputOutput.hasChildrenAddress(info.mChildrenAddress)) {
- Position childrenPos = new Position(info.mChildrenAddress + headerSize, index);
+ if (!isMovedPtNode && hasChildrenAddress(info.mChildrenAddress)) {
+ final Position childrenPos = new Position(info.mChildrenAddress, index);
stack.push(childrenPos);
}
}
@@ -143,61 +139,59 @@ public final class BinaryDictIOUtils {
/**
* Reads unigrams and bigrams from the binary file.
- * Doesn't make the memory representation of the dictionary.
+ * Doesn't store a full memory representation of the dictionary.
*
- * @param buffer the buffer to read.
+ * @param dictDecoder the dict decoder.
* @param words the map to store the address as a key and the word as a value.
* @param frequencies the map to store the address as a key and the frequency as a value.
* @param bigrams the map to store the address as a key and the list of address as a value.
- * @throws IOException
- * @throws UnsupportedFormatException
+ * @throws IOException if the file can't be read.
+ * @throws UnsupportedFormatException if the format of the file is not recognized.
*/
- public static void readUnigramsAndBigramsBinary(final FusionDictionaryBufferInterface buffer,
+ /* package */ static void readUnigramsAndBigramsBinary(final DictDecoder dictDecoder,
final Map<Integer, String> words, final Map<Integer, Integer> frequencies,
final Map<Integer, ArrayList<PendingAttribute>> bigrams) throws IOException,
UnsupportedFormatException {
// Read header
- final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
- readUnigramsAndBigramsBinaryInner(buffer, header.mHeaderSize, words, frequencies, bigrams,
- header.mFormatOptions);
+ final FileHeader header = dictDecoder.readHeader();
+ readUnigramsAndBigramsBinaryInner(dictDecoder, header.mHeaderSize, words,
+ frequencies, bigrams, header.mFormatOptions);
}
/**
- * Gets the address of the last CharGroup of the exact matching word in the dictionary.
+ * Gets the address of the last PtNode of the exact matching word in the dictionary.
* If no match is found, returns NOT_VALID_WORD.
*
- * @param buffer the buffer to read.
+ * @param dictDecoder the dict decoder.
* @param word the word we search for.
* @return the address of the terminal node.
- * @throws IOException
- * @throws UnsupportedFormatException
+ * @throws IOException if the file can't be read.
+ * @throws UnsupportedFormatException if the format of the file is not recognized.
*/
@UsedForTesting
- public static int getTerminalPosition(final FusionDictionaryBufferInterface buffer,
+ /* package */ static int getTerminalPosition(final DictDecoder dictDecoder,
final String word) throws IOException, UnsupportedFormatException {
if (word == null) return FormatSpec.NOT_VALID_WORD;
- if (buffer.position() != 0) buffer.position(0);
+ dictDecoder.setPosition(0);
- final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
+ final FileHeader header = dictDecoder.readHeader();
int wordPos = 0;
final int wordLen = word.codePointCount(0, word.length());
for (int depth = 0; depth < Constants.DICTIONARY_MAX_WORD_LENGTH; ++depth) {
if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD;
do {
- final int charGroupCount = BinaryDictInputOutput.readCharGroupCount(buffer);
- boolean foundNextCharGroup = false;
- for (int i = 0; i < charGroupCount; ++i) {
- final int charGroupPos = buffer.position();
- final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
- buffer.position(), header.mFormatOptions);
- final boolean isMovedGroup =
- BinaryDictInputOutput.isMovedGroup(currentInfo.mFlags,
- header.mFormatOptions);
- final boolean isDeletedGroup =
- BinaryDictInputOutput.isDeletedGroup(currentInfo.mFlags,
- header.mFormatOptions);
- if (isMovedGroup) continue;
+ final int ptNodeCount = dictDecoder.readPtNodeCount();
+ boolean foundNextPtNode = false;
+ for (int i = 0; i < ptNodeCount; ++i) {
+ final int ptNodePos = dictDecoder.getPosition();
+ final PtNodeInfo currentInfo = dictDecoder.readPtNode(ptNodePos,
+ header.mFormatOptions);
+ final boolean isMovedNode = isMovedPtNode(currentInfo.mFlags,
+ header.mFormatOptions);
+ final boolean isDeletedNode = isDeletedPtNode(currentInfo.mFlags,
+ header.mFormatOptions);
+ if (isMovedNode) continue;
boolean same = true;
for (int p = 0, j = word.offsetByCodePoints(0, wordPos);
p < currentInfo.mCharacters.length;
@@ -210,86 +204,60 @@ public final class BinaryDictIOUtils {
}
if (same) {
- // found the group matches the word.
+ // found the PtNode matches the word.
if (wordPos + currentInfo.mCharacters.length == wordLen) {
- if (currentInfo.mFrequency == CharGroup.NOT_A_TERMINAL
- || isDeletedGroup) {
+ if (currentInfo.mFrequency == PtNode.NOT_A_TERMINAL
+ || isDeletedNode) {
return FormatSpec.NOT_VALID_WORD;
} else {
- return charGroupPos;
+ return ptNodePos;
}
}
wordPos += currentInfo.mCharacters.length;
if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
return FormatSpec.NOT_VALID_WORD;
}
- foundNextCharGroup = true;
- buffer.position(currentInfo.mChildrenAddress);
+ foundNextPtNode = true;
+ dictDecoder.setPosition(currentInfo.mChildrenAddress);
break;
}
}
- // If we found the next char group, it is under the file pointer.
- // But if not, we are at the end of this node so we expect to have
+ // If we found the next PtNode, it is under the file pointer.
+ // But if not, we are at the end of this node array so we expect to have
// a forward link address that we need to consult and possibly resume
- // search on the next node in the linked list.
- if (foundNextCharGroup) break;
+ // search on the next node array in the linked list.
+ if (foundNextPtNode) break;
if (!header.mFormatOptions.mSupportsDynamicUpdate) {
return FormatSpec.NOT_VALID_WORD;
}
- final int forwardLinkAddress = buffer.readUnsignedInt24();
- if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ final boolean hasValidForwardLinkAddress =
+ dictDecoder.readAndFollowForwardLink();
+ if (!hasValidForwardLinkAddress || !dictDecoder.hasNextPtNodeArray()) {
return FormatSpec.NOT_VALID_WORD;
}
- buffer.position(forwardLinkAddress);
} while(true);
}
return FormatSpec.NOT_VALID_WORD;
}
- private static int markAsDeleted(final int flags) {
- return (flags & (~FormatSpec.MASK_GROUP_ADDRESS_TYPE)) | FormatSpec.FLAG_IS_DELETED;
- }
-
- /**
- * Delete the word from the binary file.
- *
- * @param buffer the buffer to write.
- * @param word the word we delete
- * @throws IOException
- * @throws UnsupportedFormatException
- */
- @UsedForTesting
- public static void deleteWord(final FusionDictionaryBufferInterface buffer,
- final String word) throws IOException, UnsupportedFormatException {
- buffer.position(0);
- final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
- final int wordPosition = getTerminalPosition(buffer, word);
- if (wordPosition == FormatSpec.NOT_VALID_WORD) return;
-
- buffer.position(wordPosition);
- final int flags = buffer.readUnsignedByte();
- buffer.position(wordPosition);
- buffer.put((byte)markAsDeleted(flags));
- }
-
/**
* @return the size written, in bytes. Always 3 bytes.
*/
- private static int writeSInt24ToBuffer(final FusionDictionaryBufferInterface buffer,
+ static int writeSInt24ToBuffer(final DictBuffer dictBuffer,
final int value) {
final int absValue = Math.abs(value);
- buffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
- buffer.put((byte)((absValue >> 8) & 0xFF));
- buffer.put((byte)(absValue & 0xFF));
+ dictBuffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
+ dictBuffer.put((byte)((absValue >> 8) & 0xFF));
+ dictBuffer.put((byte)(absValue & 0xFF));
return 3;
}
/**
* @return the size written, in bytes. Always 3 bytes.
*/
- private static int writeSInt24ToStream(final OutputStream destination, final int value)
+ static int writeSInt24ToStream(final OutputStream destination, final int value)
throws IOException {
final int absValue = Math.abs(value);
destination.write((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
@@ -303,7 +271,7 @@ public final class BinaryDictIOUtils {
*/
private static int writeVariableAddress(final OutputStream destination, final int value)
throws IOException {
- switch (BinaryDictInputOutput.getByteSize(value)) {
+ switch (BinaryDictEncoderUtils.getByteSize(value)) {
case 1:
destination.write((byte)value);
break;
@@ -317,111 +285,52 @@ public final class BinaryDictIOUtils {
destination.write((byte)(0xFF & value));
break;
}
- return BinaryDictInputOutput.getByteSize(value);
+ return BinaryDictEncoderUtils.getByteSize(value);
}
- /**
- * Update a parent address in a CharGroup that is referred to by groupOriginAddress.
- *
- * @param buffer the buffer to write.
- * @param groupOriginAddress the address of the group.
- * @param newParentAddress the absolute address of the parent.
- * @param formatOptions file format options.
- */
- public static void updateParentAddress(final FusionDictionaryBufferInterface buffer,
- final int groupOriginAddress, final int newParentAddress,
- final FormatOptions formatOptions) {
- final int originalPosition = buffer.position();
- buffer.position(groupOriginAddress);
- if (!formatOptions.mSupportsDynamicUpdate) {
- throw new RuntimeException("this file format does not support parent addresses");
- }
- final int flags = buffer.readUnsignedByte();
- if (BinaryDictInputOutput.isMovedGroup(flags, formatOptions)) {
- // if the group is moved, the parent address is stored in the destination group.
- // We are guaranteed to process the destination group later, so there is no need to
- // update anything here.
- buffer.position(originalPosition);
- return;
- }
- if (DBG) {
- MakedictLog.d("update parent address flags=" + flags + ", " + groupOriginAddress);
- }
- final int parentOffset = newParentAddress - groupOriginAddress;
- writeSInt24ToBuffer(buffer, parentOffset);
- buffer.position(originalPosition);
- }
-
- private static void skipCharGroup(final FusionDictionaryBufferInterface buffer,
- final FormatOptions formatOptions) {
- final int flags = buffer.readUnsignedByte();
- BinaryDictInputOutput.readParentAddress(buffer, formatOptions);
- skipString(buffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
- BinaryDictInputOutput.readChildrenAddress(buffer, flags, formatOptions);
- if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
+ static void skipPtNode(final DictBuffer dictBuffer, final FormatOptions formatOptions) {
+ final int flags = dictBuffer.readUnsignedByte();
+ BinaryDictDecoderUtils.readParentAddress(dictBuffer, formatOptions);
+ skipString(dictBuffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
+ BinaryDictDecoderUtils.readChildrenAddress(dictBuffer, flags, formatOptions);
+ if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) dictBuffer.readUnsignedByte();
if ((flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS) != 0) {
- final int shortcutsSize = buffer.readUnsignedShort();
- buffer.position(buffer.position() + shortcutsSize
- - FormatSpec.GROUP_SHORTCUT_LIST_SIZE_SIZE);
+ final int shortcutsSize = dictBuffer.readUnsignedShort();
+ dictBuffer.position(dictBuffer.position() + shortcutsSize
+ - FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE);
}
if ((flags & FormatSpec.FLAG_HAS_BIGRAMS) != 0) {
int bigramCount = 0;
- while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
- final int bigramFlags = buffer.readUnsignedByte();
- switch (bigramFlags & FormatSpec.MASK_ATTRIBUTE_ADDRESS_TYPE) {
- case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE:
- buffer.readUnsignedByte();
+ while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ final int bigramFlags = dictBuffer.readUnsignedByte();
+ switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE:
+ dictBuffer.readUnsignedByte();
break;
- case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES:
- buffer.readUnsignedShort();
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES:
+ dictBuffer.readUnsignedShort();
break;
- case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES:
- buffer.readUnsignedInt24();
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES:
+ dictBuffer.readUnsignedInt24();
break;
}
- if ((bigramFlags & FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT) == 0) break;
+ if ((bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT) == 0) break;
}
- if (bigramCount >= FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
- throw new RuntimeException("Too many bigrams in a group.");
+ if (bigramCount >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ throw new RuntimeException("Too many bigrams in a PtNode.");
}
}
}
- /**
- * Update parent addresses in a Node that is referred to by nodeOriginAddress.
- *
- * @param buffer the buffer to be modified.
- * @param nodeOriginAddress the address of a modified Node.
- * @param newParentAddress the address to be written.
- * @param formatOptions file format options.
- */
- public static void updateParentAddresses(final FusionDictionaryBufferInterface buffer,
- final int nodeOriginAddress, final int newParentAddress,
- final FormatOptions formatOptions) {
- final int originalPosition = buffer.position();
- buffer.position(nodeOriginAddress);
- do {
- final int count = BinaryDictInputOutput.readCharGroupCount(buffer);
- for (int i = 0; i < count; ++i) {
- updateParentAddress(buffer, buffer.position(), newParentAddress, formatOptions);
- skipCharGroup(buffer, formatOptions);
- }
- final int forwardLinkAddress = buffer.readUnsignedInt24();
- buffer.position(forwardLinkAddress);
- } while (formatOptions.mSupportsDynamicUpdate
- && buffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
- buffer.position(originalPosition);
- }
-
- private static void skipString(final FusionDictionaryBufferInterface buffer,
+ static void skipString(final DictBuffer dictBuffer,
final boolean hasMultipleChars) {
if (hasMultipleChars) {
- int character = CharEncoding.readChar(buffer);
+ int character = CharEncoding.readChar(dictBuffer);
while (character != FormatSpec.INVALID_CHARACTER) {
- character = CharEncoding.readChar(buffer);
+ character = CharEncoding.readChar(dictBuffer);
}
} else {
- CharEncoding.readChar(buffer);
+ CharEncoding.readChar(dictBuffer);
}
}
@@ -449,46 +358,24 @@ public final class BinaryDictIOUtils {
size += 3;
}
}
- destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
- size += FormatSpec.GROUP_TERMINATOR_SIZE;
+ destination.write((byte)FormatSpec.PTNODE_CHARACTERS_TERMINATOR);
+ size += FormatSpec.PTNODE_TERMINATOR_SIZE;
return size;
}
/**
- * Update a children address in a CharGroup that is addressed by groupOriginAddress.
- *
- * @param buffer the buffer to write.
- * @param groupOriginAddress the address of the group.
- * @param newChildrenAddress the absolute address of the child.
- * @param formatOptions file format options.
- */
- public static void updateChildrenAddress(final FusionDictionaryBufferInterface buffer,
- final int groupOriginAddress, final int newChildrenAddress,
- final FormatOptions formatOptions) {
- final int originalPosition = buffer.position();
- buffer.position(groupOriginAddress);
- final int flags = buffer.readUnsignedByte();
- final int parentAddress = BinaryDictInputOutput.readParentAddress(buffer, formatOptions);
- skipString(buffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
- if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
- final int childrenOffset = newChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS
- ? FormatSpec.NO_CHILDREN_ADDRESS : newChildrenAddress - buffer.position();
- writeSInt24ToBuffer(buffer, childrenOffset);
- buffer.position(originalPosition);
- }
-
- /**
- * Write a char group to an output stream.
- * A char group is an in-memory representation of a node in trie.
- * A char group info is an on-disk representation of a node.
+ * Write a PtNode to an output stream from a PtNodeInfo.
+ * A PtNode is an in-memory representation of a node in the patricia trie.
+ * A PtNode info is a container for low-level information about how the
+ * PtNode is stored in the binary format.
*
* @param destination the stream to write.
- * @param info the char group info to be written.
+ * @param info the PtNode info to be written.
* @return the size written, in bytes.
*/
- public static int writeCharGroup(final OutputStream destination, final CharGroupInfo info)
+ private static int writePtNode(final OutputStream destination, final PtNodeInfo info)
throws IOException {
- int size = FormatSpec.GROUP_FLAGS_SIZE;
+ int size = FormatSpec.PTNODE_FLAGS_SIZE;
destination.write((byte)info.mFlags);
final int parentOffset = info.mParentAddress == FormatSpec.NO_PARENT_ADDRESS ?
FormatSpec.NO_PARENT_ADDRESS : info.mParentAddress - info.mOriginalAddress;
@@ -503,7 +390,7 @@ public final class BinaryDictIOUtils {
}
}
if (info.mCharacters.length > 1) {
- destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
+ destination.write((byte)FormatSpec.PTNODE_CHARACTERS_TERMINATOR);
size++;
}
@@ -513,7 +400,7 @@ public final class BinaryDictIOUtils {
}
if (DBG) {
- MakedictLog.d("writeCharGroup origin=" + info.mOriginalAddress + ", size=" + size
+ MakedictLog.d("writePtNode origin=" + info.mOriginalAddress + ", size=" + size
+ ", child=" + info.mChildrenAddress + ", characters ="
+ new String(info.mCharacters, 0, info.mCharacters.length));
}
@@ -524,14 +411,14 @@ public final class BinaryDictIOUtils {
if (info.mShortcutTargets != null && info.mShortcutTargets.size() > 0) {
final int shortcutListSize =
- BinaryDictInputOutput.getShortcutListSize(info.mShortcutTargets);
+ BinaryDictEncoderUtils.getShortcutListSize(info.mShortcutTargets);
destination.write((byte)(shortcutListSize >> 8));
destination.write((byte)(shortcutListSize & 0xFF));
size += 2;
final Iterator<WeightedString> shortcutIterator = info.mShortcutTargets.iterator();
while (shortcutIterator.hasNext()) {
final WeightedString target = shortcutIterator.next();
- destination.write((byte)BinaryDictInputOutput.makeShortcutFlags(
+ destination.write((byte)BinaryDictEncoderUtils.makeShortcutFlags(
shortcutIterator.hasNext(), target.mFrequency));
size++;
size += writeString(destination, target.mWord);
@@ -540,28 +427,28 @@ public final class BinaryDictIOUtils {
if (info.mBigrams != null) {
// TODO: Consolidate this code with the code that computes the size of the bigram list
- // in BinaryDictionaryInputOutput#computeActualNodeSize
+ // in BinaryDictEncoderUtils#computeActualNodeArraySize
for (int i = 0; i < info.mBigrams.size(); ++i) {
final int bigramFrequency = info.mBigrams.get(i).mFrequency;
int bigramFlags = (i < info.mBigrams.size() - 1)
- ? FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT : 0;
+ ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0;
size++;
final int bigramOffset = info.mBigrams.get(i).mAddress - (info.mOriginalAddress
+ size);
- bigramFlags |= (bigramOffset < 0) ? FormatSpec.FLAG_ATTRIBUTE_OFFSET_NEGATIVE : 0;
- switch (BinaryDictInputOutput.getByteSize(bigramOffset)) {
+ bigramFlags |= (bigramOffset < 0) ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0;
+ switch (BinaryDictEncoderUtils.getByteSize(bigramOffset)) {
case 1:
- bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE;
+ bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE;
break;
case 2:
- bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES;
+ bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES;
break;
case 3:
- bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES;
+ bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES;
break;
}
- bigramFlags |= bigramFrequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY;
+ bigramFlags |= bigramFrequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY;
destination.write((byte)bigramFlags);
size += writeVariableAddress(destination, Math.abs(bigramOffset));
}
@@ -569,82 +456,40 @@ public final class BinaryDictIOUtils {
return size;
}
- @SuppressWarnings("unused")
- private static void updateForwardLink(final FusionDictionaryBufferInterface buffer,
- final int nodeOriginAddress, final int newNodeAddress,
- final FormatOptions formatOptions) {
- buffer.position(nodeOriginAddress);
- int jumpCount = 0;
- while (jumpCount++ < MAX_JUMPS) {
- final int count = BinaryDictInputOutput.readCharGroupCount(buffer);
- for (int i = 0; i < count; ++i) skipCharGroup(buffer, formatOptions);
- final int forwardLinkAddress = buffer.readUnsignedInt24();
- if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
- buffer.position(buffer.position() - FormatSpec.FORWARD_LINK_ADDRESS_SIZE);
- writeSInt24ToBuffer(buffer, newNodeAddress);
- return;
- }
- buffer.position(forwardLinkAddress);
- }
- if (DBG && jumpCount >= MAX_JUMPS) {
- throw new RuntimeException("too many jumps, probably a bug.");
- }
- }
-
/**
- * Helper method to move a char group to the tail of the file.
+ * Compute the size of the PtNode.
*/
- private static int moveCharGroup(final OutputStream destination,
- final FusionDictionaryBufferInterface buffer, final CharGroupInfo info,
- final int nodeOriginAddress, final int oldGroupAddress,
- final FormatOptions formatOptions) throws IOException {
- updateParentAddress(buffer, oldGroupAddress, buffer.limit() + 1, formatOptions);
- buffer.position(oldGroupAddress);
- final int currentFlags = buffer.readUnsignedByte();
- buffer.position(oldGroupAddress);
- buffer.put((byte)(FormatSpec.FLAG_IS_MOVED | (currentFlags
- & (~FormatSpec.MASK_MOVE_AND_DELETE_FLAG))));
- int size = FormatSpec.GROUP_FLAGS_SIZE;
- updateForwardLink(buffer, nodeOriginAddress, buffer.limit(), formatOptions);
- size += writeNode(destination, new CharGroupInfo[] { info });
- return size;
- }
-
- /**
- * Compute the size of the char group.
- */
- private static int computeGroupSize(final CharGroupInfo info,
- final FormatOptions formatOptions) {
- int size = FormatSpec.GROUP_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
- + BinaryDictInputOutput.getGroupCharactersSize(info.mCharacters)
- + BinaryDictInputOutput.getChildrenAddressSize(info.mFlags, formatOptions);
+ static int computePtNodeSize(final PtNodeInfo info, final FormatOptions formatOptions) {
+ int size = FormatSpec.PTNODE_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
+ + BinaryDictEncoderUtils.getPtNodeCharactersSize(info.mCharacters)
+ + getChildrenAddressSize(info.mFlags, formatOptions);
if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
- size += FormatSpec.GROUP_FREQUENCY_SIZE;
+ size += FormatSpec.PTNODE_FREQUENCY_SIZE;
}
if (info.mShortcutTargets != null && !info.mShortcutTargets.isEmpty()) {
- size += BinaryDictInputOutput.getShortcutListSize(info.mShortcutTargets);
+ size += BinaryDictEncoderUtils.getShortcutListSize(info.mShortcutTargets);
}
if (info.mBigrams != null) {
for (final PendingAttribute attr : info.mBigrams) {
- size += FormatSpec.GROUP_FLAGS_SIZE;
- size += BinaryDictInputOutput.getByteSize(attr.mAddress);
+ size += FormatSpec.PTNODE_FLAGS_SIZE;
+ size += BinaryDictEncoderUtils.getByteSize(attr.mAddress);
}
}
return size;
}
/**
- * Write a node to the stream.
+ * Write a node array to the stream.
*
* @param destination the stream to write.
- * @param infos groups to be written.
+ * @param infos an array of PtNodeInfo to be written.
* @return the size written, in bytes.
* @throws IOException
*/
- private static int writeNode(final OutputStream destination, final CharGroupInfo[] infos)
+ static int writeNodes(final OutputStream destination, final PtNodeInfo[] infos)
throws IOException {
- int size = BinaryDictInputOutput.getGroupCountSize(infos.length);
- switch (BinaryDictInputOutput.getGroupCountSize(infos.length)) {
+ int size = getPtNodeCountSize(infos.length);
+ switch (getPtNodeCountSize(infos.length)) {
case 1:
destination.write((byte)infos.length);
break;
@@ -653,335 +498,13 @@ public final class BinaryDictIOUtils {
destination.write((byte)(infos.length & 0xFF));
break;
default:
- throw new RuntimeException("Invalid group count size.");
+ throw new RuntimeException("Invalid node count size.");
}
- for (final CharGroupInfo info : infos) size += writeCharGroup(destination, info);
+ for (final PtNodeInfo info : infos) size += writePtNode(destination, info);
writeSInt24ToStream(destination, FormatSpec.NO_FORWARD_LINK_ADDRESS);
return size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
}
- /**
- * Move a group that is referred to by oldGroupOrigin to the tail of the file.
- * And set the children address to the byte after the group.
- *
- * @param nodeOrigin the address of the tail of the file.
- * @param characters
- * @param length
- * @param flags
- * @param frequency
- * @param parentAddress
- * @param shortcutTargets
- * @param bigrams
- * @param destination the stream representing the tail of the file.
- * @param buffer the buffer representing the (constant-size) body of the file.
- * @param oldNodeOrigin
- * @param oldGroupOrigin
- * @param formatOptions
- * @return the size written, in bytes.
- * @throws IOException
- */
- private static int moveGroup(final int nodeOrigin, final int[] characters, final int length,
- final int flags, final int frequency, final int parentAddress,
- final ArrayList<WeightedString> shortcutTargets,
- final ArrayList<PendingAttribute> bigrams, final OutputStream destination,
- final FusionDictionaryBufferInterface buffer, final int oldNodeOrigin,
- final int oldGroupOrigin, final FormatOptions formatOptions) throws IOException {
- int size = 0;
- final int newGroupOrigin = nodeOrigin + 1;
- final int[] writtenCharacters = Arrays.copyOfRange(characters, 0, length);
- final CharGroupInfo tmpInfo = new CharGroupInfo(newGroupOrigin, -1 /* endAddress */,
- flags, writtenCharacters, frequency, parentAddress, FormatSpec.NO_CHILDREN_ADDRESS,
- shortcutTargets, bigrams);
- size = computeGroupSize(tmpInfo, formatOptions);
- final CharGroupInfo newInfo = new CharGroupInfo(newGroupOrigin, newGroupOrigin + size,
- flags, writtenCharacters, frequency, parentAddress,
- nodeOrigin + 1 + size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE, shortcutTargets,
- bigrams);
- moveCharGroup(destination, buffer, newInfo, oldNodeOrigin, oldGroupOrigin, formatOptions);
- return 1 + size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
- }
-
- /**
- * Insert a word into a binary dictionary.
- *
- * @param buffer
- * @param destination
- * @param word
- * @param frequency
- * @param bigramStrings
- * @param shortcuts
- * @throws IOException
- * @throws UnsupportedFormatException
- */
- // TODO: Support batch insertion.
- // TODO: Remove @UsedForTesting once UserHistoryDictionary is implemented by BinaryDictionary.
- @UsedForTesting
- public static void insertWord(final FusionDictionaryBufferInterface buffer,
- final OutputStream destination, final String word, final int frequency,
- final ArrayList<WeightedString> bigramStrings,
- final ArrayList<WeightedString> shortcuts, final boolean isNotAWord,
- final boolean isBlackListEntry)
- throws IOException, UnsupportedFormatException {
- final ArrayList<PendingAttribute> bigrams = new ArrayList<PendingAttribute>();
- if (bigramStrings != null) {
- for (final WeightedString bigram : bigramStrings) {
- int position = getTerminalPosition(buffer, bigram.mWord);
- if (position == FormatSpec.NOT_VALID_WORD) {
- // TODO: figure out what is the correct thing to do here.
- } else {
- bigrams.add(new PendingAttribute(bigram.mFrequency, position));
- }
- }
- }
-
- final boolean isTerminal = true;
- final boolean hasBigrams = !bigrams.isEmpty();
- final boolean hasShortcuts = shortcuts != null && !shortcuts.isEmpty();
-
- // find the insert position of the word.
- if (buffer.position() != 0) buffer.position(0);
- final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
-
- int wordPos = 0, address = buffer.position(), nodeOriginAddress = buffer.position();
- final int[] codePoints = FusionDictionary.getCodePoints(word);
- final int wordLen = codePoints.length;
-
- for (int depth = 0; depth < Constants.DICTIONARY_MAX_WORD_LENGTH; ++depth) {
- if (wordPos >= wordLen) break;
- nodeOriginAddress = buffer.position();
- int nodeParentAddress = -1;
- final int charGroupCount = BinaryDictInputOutput.readCharGroupCount(buffer);
- boolean foundNextGroup = false;
-
- for (int i = 0; i < charGroupCount; ++i) {
- address = buffer.position();
- final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
- buffer.position(), header.mFormatOptions);
- final boolean isMovedGroup = BinaryDictInputOutput.isMovedGroup(currentInfo.mFlags,
- header.mFormatOptions);
- if (isMovedGroup) continue;
- nodeParentAddress = (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS)
- ? FormatSpec.NO_PARENT_ADDRESS : currentInfo.mParentAddress + address;
- boolean matched = true;
- for (int p = 0; p < currentInfo.mCharacters.length; ++p) {
- if (wordPos + p >= wordLen) {
- /*
- * splitting
- * before
- * abcd - ef
- *
- * insert "abc"
- *
- * after
- * abc - d - ef
- */
- final int newNodeAddress = buffer.limit();
- final int flags = BinaryDictInputOutput.makeCharGroupFlags(p > 1,
- isTerminal, 0, hasShortcuts, hasBigrams, false /* isNotAWord */,
- false /* isBlackListEntry */, header.mFormatOptions);
- int written = moveGroup(newNodeAddress, currentInfo.mCharacters, p, flags,
- frequency, nodeParentAddress, shortcuts, bigrams, destination,
- buffer, nodeOriginAddress, address, header.mFormatOptions);
-
- final int[] characters2 = Arrays.copyOfRange(currentInfo.mCharacters, p,
- currentInfo.mCharacters.length);
- if (currentInfo.mChildrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
- updateParentAddresses(buffer, currentInfo.mChildrenAddress,
- newNodeAddress + written + 1, header.mFormatOptions);
- }
- final CharGroupInfo newInfo2 = new CharGroupInfo(
- newNodeAddress + written + 1, -1 /* endAddress */,
- currentInfo.mFlags, characters2, currentInfo.mFrequency,
- newNodeAddress + 1, currentInfo.mChildrenAddress,
- currentInfo.mShortcutTargets, currentInfo.mBigrams);
- writeNode(destination, new CharGroupInfo[] { newInfo2 });
- return;
- } else if (codePoints[wordPos + p] != currentInfo.mCharacters[p]) {
- if (p > 0) {
- /*
- * splitting
- * before
- * ab - cd
- *
- * insert "ac"
- *
- * after
- * a - b - cd
- * |
- * - c
- */
-
- final int newNodeAddress = buffer.limit();
- final int childrenAddress = currentInfo.mChildrenAddress;
-
- // move prefix
- final int prefixFlags = BinaryDictInputOutput.makeCharGroupFlags(p > 1,
- false /* isTerminal */, 0 /* childrenAddressSize*/,
- false /* hasShortcut */, false /* hasBigrams */,
- false /* isNotAWord */, false /* isBlackListEntry */,
- header.mFormatOptions);
- int written = moveGroup(newNodeAddress, currentInfo.mCharacters, p,
- prefixFlags, -1 /* frequency */, nodeParentAddress, null, null,
- destination, buffer, nodeOriginAddress, address,
- header.mFormatOptions);
-
- final int[] suffixCharacters = Arrays.copyOfRange(
- currentInfo.mCharacters, p, currentInfo.mCharacters.length);
- if (currentInfo.mChildrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
- updateParentAddresses(buffer, currentInfo.mChildrenAddress,
- newNodeAddress + written + 1, header.mFormatOptions);
- }
- final int suffixFlags = BinaryDictInputOutput.makeCharGroupFlags(
- suffixCharacters.length > 1,
- (currentInfo.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0,
- 0 /* childrenAddressSize */,
- (currentInfo.mFlags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)
- != 0,
- (currentInfo.mFlags & FormatSpec.FLAG_HAS_BIGRAMS) != 0,
- isNotAWord, isBlackListEntry, header.mFormatOptions);
- final CharGroupInfo suffixInfo = new CharGroupInfo(
- newNodeAddress + written + 1, -1 /* endAddress */, suffixFlags,
- suffixCharacters, currentInfo.mFrequency, newNodeAddress + 1,
- currentInfo.mChildrenAddress, currentInfo.mShortcutTargets,
- currentInfo.mBigrams);
- written += computeGroupSize(suffixInfo, header.mFormatOptions) + 1;
-
- final int[] newCharacters = Arrays.copyOfRange(codePoints, wordPos + p,
- codePoints.length);
- final int flags = BinaryDictInputOutput.makeCharGroupFlags(
- newCharacters.length > 1, isTerminal,
- 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
- isNotAWord, isBlackListEntry, header.mFormatOptions);
- final CharGroupInfo newInfo = new CharGroupInfo(
- newNodeAddress + written, -1 /* endAddress */, flags,
- newCharacters, frequency, newNodeAddress + 1,
- FormatSpec.NO_CHILDREN_ADDRESS, shortcuts, bigrams);
- writeNode(destination, new CharGroupInfo[] { suffixInfo, newInfo });
- return;
- }
- matched = false;
- break;
- }
- }
-
- if (matched) {
- if (wordPos + currentInfo.mCharacters.length == wordLen) {
- // the word exists in the dictionary.
- // only update group.
- final int newNodeAddress = buffer.limit();
- final boolean hasMultipleChars = currentInfo.mCharacters.length > 1;
- final int flags = BinaryDictInputOutput.makeCharGroupFlags(hasMultipleChars,
- isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
- isNotAWord, isBlackListEntry, header.mFormatOptions);
- final CharGroupInfo newInfo = new CharGroupInfo(newNodeAddress + 1,
- -1 /* endAddress */, flags, currentInfo.mCharacters, frequency,
- nodeParentAddress, currentInfo.mChildrenAddress, shortcuts,
- bigrams);
- moveCharGroup(destination, buffer, newInfo, nodeOriginAddress, address,
- header.mFormatOptions);
- return;
- }
- wordPos += currentInfo.mCharacters.length;
- if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
- /*
- * found the prefix of the word.
- * make new node and link to the node from this group.
- *
- * before
- * ab - cd
- *
- * insert "abcde"
- *
- * after
- * ab - cd - e
- */
- final int newNodeAddress = buffer.limit();
- updateChildrenAddress(buffer, address, newNodeAddress,
- header.mFormatOptions);
- final int newGroupAddress = newNodeAddress + 1;
- final boolean hasMultipleChars = (wordLen - wordPos) > 1;
- final int flags = BinaryDictInputOutput.makeCharGroupFlags(hasMultipleChars,
- isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
- isNotAWord, isBlackListEntry, header.mFormatOptions);
- final int[] characters = Arrays.copyOfRange(codePoints, wordPos, wordLen);
- final CharGroupInfo newInfo = new CharGroupInfo(newGroupAddress, -1, flags,
- characters, frequency, address, FormatSpec.NO_CHILDREN_ADDRESS,
- shortcuts, bigrams);
- writeNode(destination, new CharGroupInfo[] { newInfo });
- return;
- }
- buffer.position(currentInfo.mChildrenAddress);
- foundNextGroup = true;
- break;
- }
- }
-
- if (foundNextGroup) continue;
-
- // reached the end of the array.
- final int linkAddressPosition = buffer.position();
- int nextLink = buffer.readUnsignedInt24();
- if ((nextLink & MSB24) != 0) {
- nextLink = -(nextLink & SINT24_MAX);
- }
- if (nextLink == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
- /*
- * expand this node.
- *
- * before
- * ab - cd
- *
- * insert "abef"
- *
- * after
- * ab - cd
- * |
- * - ef
- */
-
- // change the forward link address.
- final int newNodeAddress = buffer.limit();
- buffer.position(linkAddressPosition);
- writeSInt24ToBuffer(buffer, newNodeAddress);
-
- final int[] characters = Arrays.copyOfRange(codePoints, wordPos, wordLen);
- final int flags = BinaryDictInputOutput.makeCharGroupFlags(characters.length > 1,
- isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
- isNotAWord, isBlackListEntry, header.mFormatOptions);
- final CharGroupInfo newInfo = new CharGroupInfo(newNodeAddress + 1,
- -1 /* endAddress */, flags, characters, frequency, nodeParentAddress,
- FormatSpec.NO_CHILDREN_ADDRESS, shortcuts, bigrams);
- writeNode(destination, new CharGroupInfo[]{ newInfo });
- return;
- } else {
- depth--;
- buffer.position(nextLink);
- }
- }
- }
-
- /**
- * Find a word from the buffer.
- *
- * @param buffer the buffer representing the body of the dictionary file.
- * @param word the word searched
- * @return the found group
- * @throws IOException
- * @throws UnsupportedFormatException
- */
- @UsedForTesting
- public static CharGroupInfo findWordFromBuffer(final FusionDictionaryBufferInterface buffer,
- final String word) throws IOException, UnsupportedFormatException {
- int position = getTerminalPosition(buffer, word);
- if (position != FormatSpec.NOT_VALID_WORD) {
- buffer.position(0);
- final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
- buffer.position(position);
- return BinaryDictInputOutput.readCharGroup(buffer, position, header.mFormatOptions);
- }
- return null;
- }
-
private static final int HEADER_READING_BUFFER_SIZE = 16384;
/**
* Convenience method to read the header of a binary file.
@@ -992,20 +515,27 @@ public final class BinaryDictIOUtils {
* @param offset The offset in the file where to start reading the data.
* @param length The length of the data file.
*/
- public static FileHeader getDictionaryFileHeader(
+ private static FileHeader getDictionaryFileHeader(
final File file, final long offset, final long length)
throws FileNotFoundException, IOException, UnsupportedFormatException {
final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE];
- final FileInputStream inStream = new FileInputStream(file);
- try {
- inStream.read(buffer);
- final BinaryDictInputOutput.ByteBufferWrapper wrapper =
- new BinaryDictInputOutput.ByteBufferWrapper(inStream.getChannel().map(
- FileChannel.MapMode.READ_ONLY, offset, length));
- return BinaryDictInputOutput.readHeader(wrapper);
- } finally {
- inStream.close();
- }
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file,
+ new DictDecoder.DictionaryBufferFactory() {
+ @Override
+ public DictBuffer getDictionaryBuffer(File file)
+ throws FileNotFoundException, IOException {
+ final FileInputStream inStream = new FileInputStream(file);
+ try {
+ inStream.skip(offset);
+ inStream.read(buffer);
+ return new ByteArrayDictBuffer(buffer);
+ } finally {
+ inStream.close();
+ }
+ }
+ }
+ );
+ return dictDecoder.readHeader();
}
public static FileHeader getDictionaryFileHeaderOrNull(final File file, final long offset,
@@ -1019,4 +549,83 @@ public final class BinaryDictIOUtils {
return null;
}
}
+
+ /**
+ * Helper method to hide the actual value of the no children address.
+ */
+ public static boolean hasChildrenAddress(final int address) {
+ return FormatSpec.NO_CHILDREN_ADDRESS != address;
+ }
+
+ /**
+ * Helper method to check whether the node is moved.
+ */
+ public static boolean isMovedPtNode(final int flags, final FormatOptions options) {
+ return options.mSupportsDynamicUpdate
+ && ((flags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) == FormatSpec.FLAG_IS_MOVED);
+ }
+
+ /**
+ * Helper method to check whether the dictionary can be updated dynamically.
+ */
+ public static boolean supportsDynamicUpdate(final FormatOptions options) {
+ return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_DYNAMIC_UPDATE
+ && options.mSupportsDynamicUpdate;
+ }
+
+ /**
+ * Helper method to check whether the node is deleted.
+ */
+ public static boolean isDeletedPtNode(final int flags, final FormatOptions formatOptions) {
+ return formatOptions.mSupportsDynamicUpdate
+ && ((flags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) == FormatSpec.FLAG_IS_DELETED);
+ }
+
+ /**
+ * Compute the binary size of the node count
+ * @param count the node count
+ * @return the size of the node count, either 1 or 2 bytes.
+ */
+ public static int getPtNodeCountSize(final int count) {
+ if (FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT >= count) {
+ return 1;
+ } else if (FormatSpec.MAX_PTNODES_IN_A_PT_NODE_ARRAY >= count) {
+ return 2;
+ } else {
+ throw new RuntimeException("Can't have more than "
+ + FormatSpec.MAX_PTNODES_IN_A_PT_NODE_ARRAY + " PtNode in a PtNodeArray (found "
+ + count + ")");
+ }
+ }
+
+ static int getChildrenAddressSize(final int optionFlags,
+ final FormatOptions formatOptions) {
+ if (formatOptions.mSupportsDynamicUpdate) return FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
+ switch (optionFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
+ return 1;
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES:
+ return 2;
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES:
+ return 3;
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS:
+ default:
+ return 0;
+ }
+ }
+
+ /**
+ * Calculate bigram frequency from compressed value
+ *
+ * @param unigramFrequency
+ * @param bigramFrequency compressed frequency
+ * @return approximate bigram frequency
+ */
+ public static int reconstructBigramFrequency(final int unigramFrequency,
+ final int bigramFrequency) {
+ final float stepSize = (FormatSpec.MAX_TERMINAL_FREQUENCY - unigramFrequency)
+ / (1.5f + FormatSpec.MAX_BIGRAM_FREQUENCY);
+ final float resultFreqFloat = unigramFrequency + stepSize * (bigramFrequency + 1.0f);
+ return (int)resultFreqFloat;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
deleted file mode 100644
index 1b187d85d..000000000
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ /dev/null
@@ -1,1838 +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.makedict;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Reads and writes XML files for a FusionDictionary.
- *
- * All the methods in this class are static.
- */
-public final class BinaryDictInputOutput {
-
- private static final boolean DBG = MakedictLog.DBG;
-
- // Arbitrary limit to how much passes we consider address size compression should
- // terminate in. At the time of this writing, our largest dictionary completes
- // compression in five passes.
- // If the number of passes exceeds this number, makedict bails with an exception on
- // suspicion that a bug might be causing an infinite loop.
- private static final int MAX_PASSES = 24;
- private static final int MAX_JUMPS = 12;
-
- @UsedForTesting
- public interface FusionDictionaryBufferInterface {
- public int readUnsignedByte();
- public int readUnsignedShort();
- public int readUnsignedInt24();
- public int readInt();
- public int position();
- public void position(int newPosition);
- public void put(final byte b);
- public int limit();
- public int capacity();
- }
-
- public static final class ByteBufferWrapper implements FusionDictionaryBufferInterface {
- private ByteBuffer mBuffer;
-
- public ByteBufferWrapper(final ByteBuffer buffer) {
- mBuffer = buffer;
- }
-
- @Override
- public int readUnsignedByte() {
- return mBuffer.get() & 0xFF;
- }
-
- @Override
- public int readUnsignedShort() {
- return mBuffer.getShort() & 0xFFFF;
- }
-
- @Override
- public int readUnsignedInt24() {
- final int retval = readUnsignedByte();
- return (retval << 16) + readUnsignedShort();
- }
-
- @Override
- public int readInt() {
- return mBuffer.getInt();
- }
-
- @Override
- public int position() {
- return mBuffer.position();
- }
-
- @Override
- public void position(int newPos) {
- mBuffer.position(newPos);
- }
-
- @Override
- public void put(final byte b) {
- mBuffer.put(b);
- }
-
- @Override
- public int limit() {
- return mBuffer.limit();
- }
-
- @Override
- public int capacity() {
- return mBuffer.capacity();
- }
- }
-
- /**
- * A class grouping utility function for our specific character encoding.
- */
- static final class CharEncoding {
- private static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20;
- private static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF;
-
- /**
- * Helper method to find out whether this code fits on one byte
- */
- private static boolean fitsOnOneByte(final int character) {
- return character >= MINIMAL_ONE_BYTE_CHARACTER_VALUE
- && character <= MAXIMAL_ONE_BYTE_CHARACTER_VALUE;
- }
-
- /**
- * Compute the size of a character given its character code.
- *
- * Char format is:
- * 1 byte = bbbbbbbb match
- * case 000xxxxx: xxxxx << 16 + next byte << 8 + next byte
- * else: if 00011111 (= 0x1F) : this is the terminator. This is a relevant choice because
- * unicode code points range from 0 to 0x10FFFF, so any 3-byte value starting with
- * 00011111 would be outside unicode.
- * else: iso-latin-1 code
- * This allows for the whole unicode range to be encoded, including chars outside of
- * the BMP. Also everything in the iso-latin-1 charset is only 1 byte, except control
- * characters which should never happen anyway (and still work, but take 3 bytes).
- *
- * @param character the character code.
- * @return the size in binary encoded-form, either 1 or 3 bytes.
- */
- static int getCharSize(final int character) {
- // See char encoding in FusionDictionary.java
- if (fitsOnOneByte(character)) return 1;
- if (FormatSpec.INVALID_CHARACTER == character) return 1;
- return 3;
- }
-
- /**
- * Compute the byte size of a character array.
- */
- private static int getCharArraySize(final int[] chars) {
- int size = 0;
- for (int character : chars) size += getCharSize(character);
- return size;
- }
-
- /**
- * Writes a char array to a byte buffer.
- *
- * @param codePoints the code point array to write.
- * @param buffer the byte buffer to write to.
- * @param index the index in buffer to write the character array to.
- * @return the index after the last character.
- */
- private static int writeCharArray(final int[] codePoints, final byte[] buffer, int index) {
- for (int codePoint : codePoints) {
- if (1 == getCharSize(codePoint)) {
- buffer[index++] = (byte)codePoint;
- } else {
- buffer[index++] = (byte)(0xFF & (codePoint >> 16));
- buffer[index++] = (byte)(0xFF & (codePoint >> 8));
- buffer[index++] = (byte)(0xFF & codePoint);
- }
- }
- return index;
- }
-
- /**
- * Writes a string with our character format to a byte buffer.
- *
- * This will also write the terminator byte.
- *
- * @param buffer the byte buffer to write to.
- * @param origin the offset to write from.
- * @param word the string to write.
- * @return the size written, in bytes.
- */
- private static int writeString(final byte[] buffer, final int origin,
- final String word) {
- final int length = word.length();
- int index = origin;
- for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
- final int codePoint = word.codePointAt(i);
- if (1 == getCharSize(codePoint)) {
- buffer[index++] = (byte)codePoint;
- } else {
- buffer[index++] = (byte)(0xFF & (codePoint >> 16));
- buffer[index++] = (byte)(0xFF & (codePoint >> 8));
- buffer[index++] = (byte)(0xFF & codePoint);
- }
- }
- buffer[index++] = FormatSpec.GROUP_CHARACTERS_TERMINATOR;
- return index - origin;
- }
-
- /**
- * Writes a string with our character format to a ByteArrayOutputStream.
- *
- * This will also write the terminator byte.
- *
- * @param buffer the ByteArrayOutputStream to write to.
- * @param word the string to write.
- */
- private static void writeString(final ByteArrayOutputStream buffer, final String word) {
- final int length = word.length();
- for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
- final int codePoint = word.codePointAt(i);
- if (1 == getCharSize(codePoint)) {
- buffer.write((byte) codePoint);
- } else {
- buffer.write((byte) (0xFF & (codePoint >> 16)));
- buffer.write((byte) (0xFF & (codePoint >> 8)));
- buffer.write((byte) (0xFF & codePoint));
- }
- }
- buffer.write(FormatSpec.GROUP_CHARACTERS_TERMINATOR);
- }
-
- /**
- * Reads a string from a buffer. This is the converse of the above method.
- */
- private static String readString(final FusionDictionaryBufferInterface buffer) {
- final StringBuilder s = new StringBuilder();
- int character = readChar(buffer);
- while (character != FormatSpec.INVALID_CHARACTER) {
- s.appendCodePoint(character);
- character = readChar(buffer);
- }
- return s.toString();
- }
-
- /**
- * Reads a character from the buffer.
- *
- * This follows the character format documented earlier in this source file.
- *
- * @param buffer the buffer, positioned over an encoded character.
- * @return the character code.
- */
- static int readChar(final FusionDictionaryBufferInterface buffer) {
- int character = buffer.readUnsignedByte();
- if (!fitsOnOneByte(character)) {
- if (FormatSpec.GROUP_CHARACTERS_TERMINATOR == character) {
- return FormatSpec.INVALID_CHARACTER;
- }
- character <<= 16;
- character += buffer.readUnsignedShort();
- }
- return character;
- }
- }
-
- /**
- * Compute the binary size of the character array.
- *
- * If only one character, this is the size of this character. If many, it's the sum of their
- * sizes + 1 byte for the terminator.
- *
- * @param characters the character array
- * @return the size of the char array, including the terminator if any
- */
- static int getGroupCharactersSize(final int[] characters) {
- int size = CharEncoding.getCharArraySize(characters);
- if (characters.length > 1) size += FormatSpec.GROUP_TERMINATOR_SIZE;
- return size;
- }
-
- /**
- * Compute the binary size of the character array in a group
- *
- * If only one character, this is the size of this character. If many, it's the sum of their
- * sizes + 1 byte for the terminator.
- *
- * @param group the group
- * @return the size of the char array, including the terminator if any
- */
- private static int getGroupCharactersSize(final CharGroup group) {
- return getGroupCharactersSize(group.mChars);
- }
-
- /**
- * Compute the binary size of the group count
- * @param count the group count
- * @return the size of the group count, either 1 or 2 bytes.
- */
- public static int getGroupCountSize(final int count) {
- if (FormatSpec.MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT >= count) {
- return 1;
- } else if (FormatSpec.MAX_CHARGROUPS_IN_A_NODE >= count) {
- return 2;
- } else {
- throw new RuntimeException("Can't have more than "
- + FormatSpec.MAX_CHARGROUPS_IN_A_NODE + " groups in a node (found " + count
- + ")");
- }
- }
-
- /**
- * Compute the binary size of the group count for a node
- * @param node the node
- * @return the size of the group count, either 1 or 2 bytes.
- */
- private static int getGroupCountSize(final Node node) {
- return getGroupCountSize(node.mData.size());
- }
-
- /**
- * Compute the size of a shortcut in bytes.
- */
- private static int getShortcutSize(final WeightedString shortcut) {
- int size = FormatSpec.GROUP_ATTRIBUTE_FLAGS_SIZE;
- final String word = shortcut.mWord;
- final int length = word.length();
- for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
- final int codePoint = word.codePointAt(i);
- size += CharEncoding.getCharSize(codePoint);
- }
- size += FormatSpec.GROUP_TERMINATOR_SIZE;
- return size;
- }
-
- /**
- * Compute the size of a shortcut list in bytes.
- *
- * This is known in advance and does not change according to position in the file
- * like address lists do.
- */
- static int getShortcutListSize(final ArrayList<WeightedString> shortcutList) {
- if (null == shortcutList) return 0;
- int size = FormatSpec.GROUP_SHORTCUT_LIST_SIZE_SIZE;
- for (final WeightedString shortcut : shortcutList) {
- size += getShortcutSize(shortcut);
- }
- return size;
- }
-
- /**
- * Compute the maximum size of a CharGroup, assuming 3-byte addresses for everything.
- *
- * @param group the CharGroup to compute the size of.
- * @param options file format options.
- * @return the maximum size of the group.
- */
- private static int getCharGroupMaximumSize(final CharGroup group, final FormatOptions options) {
- int size = getGroupHeaderSize(group, options);
- // If terminal, one byte for the frequency
- if (group.isTerminal()) size += FormatSpec.GROUP_FREQUENCY_SIZE;
- size += FormatSpec.GROUP_MAX_ADDRESS_SIZE; // For children address
- size += getShortcutListSize(group.mShortcutTargets);
- if (null != group.mBigrams) {
- size += (FormatSpec.GROUP_ATTRIBUTE_FLAGS_SIZE
- + FormatSpec.GROUP_ATTRIBUTE_MAX_ADDRESS_SIZE)
- * group.mBigrams.size();
- }
- return size;
- }
-
- /**
- * Compute the maximum size of a node, assuming 3-byte addresses for everything, and caches
- * it in the 'actualSize' member of the node.
- *
- * @param node the node to compute the maximum size of.
- * @param options file format options.
- */
- private static void calculateNodeMaximumSize(final Node node, final FormatOptions options) {
- int size = getGroupCountSize(node);
- for (CharGroup g : node.mData) {
- final int groupSize = getCharGroupMaximumSize(g, options);
- g.mCachedSize = groupSize;
- size += groupSize;
- }
- if (options.mSupportsDynamicUpdate) {
- size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
- }
- node.mCachedSize = size;
- }
-
- /**
- * Helper method to hide the actual value of the no children address.
- */
- public static boolean hasChildrenAddress(final int address) {
- return FormatSpec.NO_CHILDREN_ADDRESS != address;
- }
-
- /**
- * Helper method to check whether the group is moved.
- */
- public static boolean isMovedGroup(final int flags, final FormatOptions options) {
- return options.mSupportsDynamicUpdate
- && ((flags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) == FormatSpec.FLAG_IS_MOVED);
- }
-
- /**
- * Helper method to check whether the group is deleted.
- */
- public static boolean isDeletedGroup(final int flags, final FormatOptions formatOptions) {
- return formatOptions.mSupportsDynamicUpdate
- && ((flags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) == FormatSpec.FLAG_IS_DELETED);
- }
-
- /**
- * Helper method to check whether the dictionary can be updated dynamically.
- */
- public static boolean supportsDynamicUpdate(final FormatOptions options) {
- return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_DYNAMIC_UPDATE
- && options.mSupportsDynamicUpdate;
- }
-
- /**
- * Compute the size of the header (flag + [parent address] + characters size) of a CharGroup.
- *
- * @param group the group of which to compute the size of the header
- * @param options file format options.
- */
- private static int getGroupHeaderSize(final CharGroup group, final FormatOptions options) {
- if (supportsDynamicUpdate(options)) {
- return FormatSpec.GROUP_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
- + getGroupCharactersSize(group);
- } else {
- return FormatSpec.GROUP_FLAGS_SIZE + getGroupCharactersSize(group);
- }
- }
-
- private static final int UINT8_MAX = 0xFF;
- private static final int UINT16_MAX = 0xFFFF;
- private static final int UINT24_MAX = 0xFFFFFF;
-
- /**
- * Compute the size, in bytes, that an address will occupy.
- *
- * This can be used either for children addresses (which are always positive) or for
- * attribute, which may be positive or negative but
- * store their sign bit separately.
- *
- * @param address the address
- * @return the byte size.
- */
- static int getByteSize(final int address) {
- assert(address <= UINT24_MAX);
- if (!hasChildrenAddress(address)) {
- return 0;
- } else if (Math.abs(address) <= UINT8_MAX) {
- return 1;
- } else if (Math.abs(address) <= UINT16_MAX) {
- return 2;
- } else {
- return 3;
- }
- }
-
- private static final int SINT24_MAX = 0x7FFFFF;
- private static final int MSB8 = 0x80;
- private static final int MSB24 = 0x800000;
-
- // End utility methods.
-
- // This method is responsible for finding a nice ordering of the nodes that favors run-time
- // cache performance and dictionary size.
- /* package for tests */ static ArrayList<Node> flattenTree(final Node root) {
- final int treeSize = FusionDictionary.countCharGroups(root);
- MakedictLog.i("Counted nodes : " + treeSize);
- final ArrayList<Node> flatTree = new ArrayList<Node>(treeSize);
- return flattenTreeInner(flatTree, root);
- }
-
- private static ArrayList<Node> flattenTreeInner(final ArrayList<Node> list, final Node node) {
- // Removing the node is necessary if the tails are merged, because we would then
- // add the same node several times when we only want it once. A number of places in
- // the code also depends on any node being only once in the list.
- // Merging tails can only be done if there are no attributes. Searching for attributes
- // in LatinIME code depends on a total breadth-first ordering, which merging tails
- // breaks. If there are no attributes, it should be fine (and reduce the file size)
- // to merge tails, and removing the node from the list would be necessary. However,
- // we don't merge tails because breaking the breadth-first ordering would result in
- // extreme overhead at bigram lookup time (it would make the search function O(n) instead
- // of the current O(log(n)), where n=number of nodes in the dictionary which is pretty
- // high).
- // If no nodes are ever merged, we can't have the same node twice in the list, hence
- // searching for duplicates in unnecessary. It is also very performance consuming,
- // since `list' is an ArrayList so it's an O(n) operation that runs on all nodes, making
- // this simple list.remove operation O(n*n) overall. On Android this overhead is very
- // high.
- // For future reference, the code to remove duplicate is a simple : list.remove(node);
- list.add(node);
- final ArrayList<CharGroup> branches = node.mData;
- final int nodeSize = branches.size();
- for (CharGroup group : branches) {
- if (null != group.mChildren) flattenTreeInner(list, group.mChildren);
- }
- return list;
- }
-
- /**
- * Get the offset from a position inside a current node to a target node, during update.
- *
- * If the current node is before the target node, the target node has not been updated yet,
- * so we should return the offset from the old position of the current node to the old position
- * of the target node. If on the other hand the target is before the current node, it already
- * has been updated, so we should return the offset from the new position in the current node
- * to the new position in the target node.
- * @param currentNode the node containing the CharGroup where the offset will be written
- * @param offsetFromStartOfCurrentNode the offset, in bytes, from the start of currentNode
- * @param targetNode the target node to get the offset to
- * @return the offset to the target node
- */
- private static int getOffsetToTargetNodeDuringUpdate(final Node currentNode,
- final int offsetFromStartOfCurrentNode, final Node targetNode) {
- final boolean isTargetBeforeCurrent = (targetNode.mCachedAddressBeforeUpdate
- < currentNode.mCachedAddressBeforeUpdate);
- if (isTargetBeforeCurrent) {
- return targetNode.mCachedAddressAfterUpdate
- - (currentNode.mCachedAddressAfterUpdate + offsetFromStartOfCurrentNode);
- } else {
- return targetNode.mCachedAddressBeforeUpdate
- - (currentNode.mCachedAddressBeforeUpdate + offsetFromStartOfCurrentNode);
- }
- }
-
- /**
- * Get the offset from a position inside a current node to a target CharGroup, during update.
- * @param currentNode the node containing the CharGroup where the offset will be written
- * @param offsetFromStartOfCurrentNode the offset, in bytes, from the start of currentNode
- * @param targetCharGroup the target CharGroup to get the offset to
- * @return the offset to the target CharGroup
- */
- // TODO: is there any way to factorize this method with the one above?
- private static int getOffsetToTargetCharGroupDuringUpdate(final Node currentNode,
- final int offsetFromStartOfCurrentNode, final CharGroup targetCharGroup) {
- final int oldOffsetBasePoint = currentNode.mCachedAddressBeforeUpdate
- + offsetFromStartOfCurrentNode;
- final boolean isTargetBeforeCurrent = (targetCharGroup.mCachedAddressBeforeUpdate
- < oldOffsetBasePoint);
- // If the target is before the current node, then its address has already been updated.
- // We can use the AfterUpdate member, and compare it to our own member after update.
- // Otherwise, the AfterUpdate member is not updated yet, so we need to use the BeforeUpdate
- // member, and of course we have to compare this to our own address before update.
- if (isTargetBeforeCurrent) {
- final int newOffsetBasePoint = currentNode.mCachedAddressAfterUpdate
- + offsetFromStartOfCurrentNode;
- return targetCharGroup.mCachedAddressAfterUpdate - newOffsetBasePoint;
- } else {
- return targetCharGroup.mCachedAddressBeforeUpdate - oldOffsetBasePoint;
- }
- }
-
- /**
- * Computes the actual node size, based on the cached addresses of the children nodes.
- *
- * Each node stores its tentative address. During dictionary address computing, these
- * are not final, but they can be used to compute the node size (the node size depends
- * on the address of the children because the number of bytes necessary to store an
- * address depends on its numeric value. The return value indicates whether the node
- * contents (as in, any of the addresses stored in the cache fields) have changed with
- * respect to their previous value.
- *
- * @param node the node to compute the size of.
- * @param dict the dictionary in which the word/attributes are to be found.
- * @param formatOptions file format options.
- * @return false if none of the cached addresses inside the node changed, true otherwise.
- */
- private static boolean computeActualNodeSize(final Node node, final FusionDictionary dict,
- final FormatOptions formatOptions) {
- boolean changed = false;
- int size = getGroupCountSize(node);
- for (CharGroup group : node.mData) {
- group.mCachedAddressAfterUpdate = node.mCachedAddressAfterUpdate + size;
- if (group.mCachedAddressAfterUpdate != group.mCachedAddressBeforeUpdate) {
- changed = true;
- }
- int groupSize = getGroupHeaderSize(group, formatOptions);
- if (group.isTerminal()) groupSize += FormatSpec.GROUP_FREQUENCY_SIZE;
- if (null == group.mChildren && formatOptions.mSupportsDynamicUpdate) {
- groupSize += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
- } else if (null != group.mChildren) {
- if (formatOptions.mSupportsDynamicUpdate) {
- groupSize += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
- } else {
- groupSize += getByteSize(getOffsetToTargetNodeDuringUpdate(node,
- groupSize + size, group.mChildren));
- }
- }
- groupSize += getShortcutListSize(group.mShortcutTargets);
- if (null != group.mBigrams) {
- for (WeightedString bigram : group.mBigrams) {
- final int offset = getOffsetToTargetCharGroupDuringUpdate(node,
- groupSize + size + FormatSpec.GROUP_FLAGS_SIZE,
- FusionDictionary.findWordInTree(dict.mRoot, bigram.mWord));
- groupSize += getByteSize(offset) + FormatSpec.GROUP_FLAGS_SIZE;
- }
- }
- group.mCachedSize = groupSize;
- size += groupSize;
- }
- if (formatOptions.mSupportsDynamicUpdate) {
- size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
- }
- if (node.mCachedSize != size) {
- node.mCachedSize = size;
- changed = true;
- }
- return changed;
- }
-
- /**
- * Initializes the cached addresses of nodes from their size.
- *
- * @param flatNodes the array of nodes.
- * @param formatOptions file format options.
- * @return the byte size of the entire stack.
- */
- private static int initializeNodesCachedAddresses(final ArrayList<Node> flatNodes,
- final FormatOptions formatOptions) {
- int nodeOffset = 0;
- for (final Node n : flatNodes) {
- n.mCachedAddressBeforeUpdate = nodeOffset;
- int groupCountSize = getGroupCountSize(n);
- int groupOffset = 0;
- for (final CharGroup g : n.mData) {
- g.mCachedAddressBeforeUpdate = g.mCachedAddressAfterUpdate =
- groupCountSize + nodeOffset + groupOffset;
- groupOffset += g.mCachedSize;
- }
- final int nodeSize = groupCountSize + groupOffset
- + (formatOptions.mSupportsDynamicUpdate
- ? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
- nodeOffset += n.mCachedSize;
- }
- return nodeOffset;
- }
-
- /**
- * Updates the cached addresses of nodes after recomputing their new positions.
- *
- * @param flatNodes the array of nodes.
- */
- private static void updateNodeCachedAddresses(final ArrayList<Node> flatNodes) {
- for (final Node n : flatNodes) {
- n.mCachedAddressBeforeUpdate = n.mCachedAddressAfterUpdate;
- for (final CharGroup g : n.mData) {
- g.mCachedAddressBeforeUpdate = g.mCachedAddressAfterUpdate;
- }
- }
- }
-
- /**
- * Compute the cached parent addresses after all has been updated.
- *
- * The parent addresses are used by some binary formats at write-to-disk time. Not all formats
- * need them. In particular, version 2 does not need them, and version 3 does.
- *
- * @param flatNodes the flat array of nodes to fill in
- */
- private static void computeParentAddresses(final ArrayList<Node> flatNodes) {
- for (final Node node : flatNodes) {
- for (final CharGroup group : node.mData) {
- if (null != group.mChildren) {
- // Assign my address to children's parent address
- // Here BeforeUpdate and AfterUpdate addresses have the same value, so it
- // does not matter which we use.
- group.mChildren.mCachedParentAddress = group.mCachedAddressAfterUpdate
- - group.mChildren.mCachedAddressAfterUpdate;
- }
- }
- }
- }
-
- /**
- * Compute the addresses and sizes of an ordered node array.
- *
- * This method takes a node array and will update its cached address and size values
- * so that they can be written into a file. It determines the smallest size each of the
- * nodes can be given the addresses of its children and attributes, and store that into
- * each node.
- * The order of the node is given by the order of the array. This method makes no effort
- * to find a good order; it only mechanically computes the size this order results in.
- *
- * @param dict the dictionary
- * @param flatNodes the ordered array of nodes
- * @param formatOptions file format options.
- * @return the same array it was passed. The nodes have been updated for address and size.
- */
- private static ArrayList<Node> computeAddresses(final FusionDictionary dict,
- final ArrayList<Node> flatNodes, final FormatOptions formatOptions) {
- // First get the worst possible sizes and offsets
- for (final Node n : flatNodes) calculateNodeMaximumSize(n, formatOptions);
- final int offset = initializeNodesCachedAddresses(flatNodes, formatOptions);
-
- MakedictLog.i("Compressing the array addresses. Original size : " + offset);
- MakedictLog.i("(Recursively seen size : " + offset + ")");
-
- int passes = 0;
- boolean changesDone = false;
- do {
- changesDone = false;
- int nodeStartOffset = 0;
- for (final Node n : flatNodes) {
- n.mCachedAddressAfterUpdate = nodeStartOffset;
- final int oldNodeSize = n.mCachedSize;
- final boolean changed = computeActualNodeSize(n, dict, formatOptions);
- final int newNodeSize = n.mCachedSize;
- if (oldNodeSize < newNodeSize) throw new RuntimeException("Increased size ?!");
- nodeStartOffset += newNodeSize;
- changesDone |= changed;
- }
- updateNodeCachedAddresses(flatNodes);
- ++passes;
- if (passes > MAX_PASSES) throw new RuntimeException("Too many passes - probably a bug");
- } while (changesDone);
-
- if (formatOptions.mSupportsDynamicUpdate) {
- computeParentAddresses(flatNodes);
- }
- final Node lastNode = flatNodes.get(flatNodes.size() - 1);
- MakedictLog.i("Compression complete in " + passes + " passes.");
- MakedictLog.i("After address compression : "
- + (lastNode.mCachedAddressAfterUpdate + lastNode.mCachedSize));
-
- return flatNodes;
- }
-
- /**
- * Sanity-checking method.
- *
- * This method checks an array of node for juxtaposition, that is, it will do
- * nothing if each node's cached address is actually the previous node's address
- * plus the previous node's size.
- * If this is not the case, it will throw an exception.
- *
- * @param array the array node to check
- */
- private static void checkFlatNodeArray(final ArrayList<Node> array) {
- int offset = 0;
- int index = 0;
- for (final Node n : array) {
- // BeforeUpdate and AfterUpdate addresses are the same here, so it does not matter
- // which we use.
- if (n.mCachedAddressAfterUpdate != offset) {
- throw new RuntimeException("Wrong address for node " + index
- + " : expected " + offset + ", got " + n.mCachedAddressAfterUpdate);
- }
- ++index;
- offset += n.mCachedSize;
- }
- }
-
- /**
- * Helper method to write a variable-size address to a file.
- *
- * @param buffer the buffer to write to.
- * @param index the index in the buffer to write the address to.
- * @param address the address to write.
- * @return the size in bytes the address actually took.
- */
- private static int writeVariableAddress(final byte[] buffer, int index, final int address) {
- switch (getByteSize(address)) {
- case 1:
- buffer[index++] = (byte)address;
- return 1;
- case 2:
- buffer[index++] = (byte)(0xFF & (address >> 8));
- buffer[index++] = (byte)(0xFF & address);
- return 2;
- case 3:
- buffer[index++] = (byte)(0xFF & (address >> 16));
- buffer[index++] = (byte)(0xFF & (address >> 8));
- buffer[index++] = (byte)(0xFF & address);
- return 3;
- case 0:
- return 0;
- default:
- throw new RuntimeException("Address " + address + " has a strange size");
- }
- }
-
- /**
- * Helper method to write a variable-size signed address to a file.
- *
- * @param buffer the buffer to write to.
- * @param index the index in the buffer to write the address to.
- * @param address the address to write.
- * @return the size in bytes the address actually took.
- */
- private static int writeVariableSignedAddress(final byte[] buffer, int index,
- final int address) {
- if (!hasChildrenAddress(address)) {
- buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
- } else {
- final int absAddress = Math.abs(address);
- buffer[index++] = (byte)((address < 0 ? MSB8 : 0) | (0xFF & (absAddress >> 16)));
- buffer[index++] = (byte)(0xFF & (absAddress >> 8));
- buffer[index++] = (byte)(0xFF & absAddress);
- }
- return 3;
- }
-
- /**
- * Makes the flag value for a char group.
- *
- * @param hasMultipleChars whether the group has multiple chars.
- * @param isTerminal whether the group is terminal.
- * @param childrenAddressSize the size of a children address.
- * @param hasShortcuts whether the group has shortcuts.
- * @param hasBigrams whether the group has bigrams.
- * @param isNotAWord whether the group is not a word.
- * @param isBlackListEntry whether the group is a blacklist entry.
- * @param formatOptions file format options.
- * @return the flags
- */
- static int makeCharGroupFlags(final boolean hasMultipleChars, final boolean isTerminal,
- final int childrenAddressSize, final boolean hasShortcuts, final boolean hasBigrams,
- final boolean isNotAWord, final boolean isBlackListEntry,
- final FormatOptions formatOptions) {
- byte flags = 0;
- if (hasMultipleChars) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
- if (isTerminal) flags |= FormatSpec.FLAG_IS_TERMINAL;
- if (formatOptions.mSupportsDynamicUpdate) {
- flags |= FormatSpec.FLAG_IS_NOT_MOVED;
- } else if (true) {
- switch (childrenAddressSize) {
- case 1:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE;
- break;
- case 2:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES;
- break;
- case 3:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
- break;
- case 0:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS;
- break;
- default:
- throw new RuntimeException("Node with a strange address");
- }
- }
- if (hasShortcuts) flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS;
- if (hasBigrams) flags |= FormatSpec.FLAG_HAS_BIGRAMS;
- if (isNotAWord) flags |= FormatSpec.FLAG_IS_NOT_A_WORD;
- if (isBlackListEntry) flags |= FormatSpec.FLAG_IS_BLACKLISTED;
- return flags;
- }
-
- private static byte makeCharGroupFlags(final CharGroup group, final int groupAddress,
- final int childrenOffset, final FormatOptions formatOptions) {
- return (byte) makeCharGroupFlags(group.mChars.length > 1, group.mFrequency >= 0,
- getByteSize(childrenOffset), group.mShortcutTargets != null, group.mBigrams != null,
- group.mIsNotAWord, group.mIsBlacklistEntry, formatOptions);
- }
-
- /**
- * Makes the flag value for a bigram.
- *
- * @param more whether there are more bigrams after this one.
- * @param offset the offset of the bigram.
- * @param bigramFrequency the frequency of the bigram, 0..255.
- * @param unigramFrequency the unigram frequency of the same word, 0..255.
- * @param word the second bigram, for debugging purposes
- * @return the flags
- */
- private static final int makeBigramFlags(final boolean more, final int offset,
- int bigramFrequency, final int unigramFrequency, final String word) {
- int bigramFlags = (more ? FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT : 0)
- + (offset < 0 ? FormatSpec.FLAG_ATTRIBUTE_OFFSET_NEGATIVE : 0);
- switch (getByteSize(offset)) {
- case 1:
- bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE;
- break;
- case 2:
- bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES;
- break;
- case 3:
- bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES;
- break;
- default:
- throw new RuntimeException("Strange offset size");
- }
- if (unigramFrequency > bigramFrequency) {
- MakedictLog.e("Unigram freq is superior to bigram freq for \"" + word
- + "\". Bigram freq is " + bigramFrequency + ", unigram freq for "
- + word + " is " + unigramFrequency);
- bigramFrequency = unigramFrequency;
- }
- // We compute the difference between 255 (which means probability = 1) and the
- // unigram score. We split this into a number of discrete steps.
- // Now, the steps are numbered 0~15; 0 represents an increase of 1 step while 15
- // represents an increase of 16 steps: a value of 15 will be interpreted as the median
- // value of the 16th step. In all justice, if the bigram frequency is low enough to be
- // rounded below the first step (which means it is less than half a step higher than the
- // unigram frequency) then the unigram frequency itself is the best approximation of the
- // bigram freq that we could possibly supply, hence we should *not* include this bigram
- // in the file at all.
- // until this is done, we'll write 0 and slightly overestimate this case.
- // In other words, 0 means "between 0.5 step and 1.5 step", 1 means "between 1.5 step
- // and 2.5 steps", and 15 means "between 15.5 steps and 16.5 steps". So we want to
- // divide our range [unigramFreq..MAX_TERMINAL_FREQUENCY] in 16.5 steps to get the
- // step size. Then we compute the start of the first step (the one where value 0 starts)
- // by adding half-a-step to the unigramFrequency. From there, we compute the integer
- // number of steps to the bigramFrequency. One last thing: we want our steps to include
- // their lower bound and exclude their higher bound so we need to have the first step
- // start at exactly 1 unit higher than floor(unigramFreq + half a step).
- // Note : to reconstruct the score, the dictionary reader will need to divide
- // MAX_TERMINAL_FREQUENCY - unigramFreq by 16.5 likewise to get the value of the step,
- // and add (discretizedFrequency + 0.5 + 0.5) times this value to get the best
- // approximation. (0.5 to get the first step start, and 0.5 to get the middle of the
- // step pointed by the discretized frequency.
- final float stepSize =
- (FormatSpec.MAX_TERMINAL_FREQUENCY - unigramFrequency)
- / (1.5f + FormatSpec.MAX_BIGRAM_FREQUENCY);
- final float firstStepStart = 1 + unigramFrequency + (stepSize / 2.0f);
- final int discretizedFrequency = (int)((bigramFrequency - firstStepStart) / stepSize);
- // If the bigram freq is less than half-a-step higher than the unigram freq, we get -1
- // here. The best approximation would be the unigram freq itself, so we should not
- // include this bigram in the dictionary. For now, register as 0, and live with the
- // small over-estimation that we get in this case. TODO: actually remove this bigram
- // if discretizedFrequency < 0.
- final int finalBigramFrequency = discretizedFrequency > 0 ? discretizedFrequency : 0;
- bigramFlags += finalBigramFrequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY;
- return bigramFlags;
- }
-
- /**
- * Makes the 2-byte value for options flags.
- */
- private static final int makeOptionsValue(final FusionDictionary dictionary,
- final FormatOptions formatOptions) {
- final DictionaryOptions options = dictionary.mOptions;
- final boolean hasBigrams = dictionary.hasBigrams();
- return (options.mFrenchLigatureProcessing ? FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG : 0)
- + (options.mGermanUmlautProcessing ? FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG : 0)
- + (hasBigrams ? FormatSpec.CONTAINS_BIGRAMS_FLAG : 0)
- + (formatOptions.mSupportsDynamicUpdate ? FormatSpec.SUPPORTS_DYNAMIC_UPDATE : 0);
- }
-
- /**
- * Makes the flag value for a shortcut.
- *
- * @param more whether there are more attributes after this one.
- * @param frequency the frequency of the attribute, 0..15
- * @return the flags
- */
- static final int makeShortcutFlags(final boolean more, final int frequency) {
- return (more ? FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT : 0)
- + (frequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY);
- }
-
- private static final int writeParentAddress(final byte[] buffer, final int index,
- final int address, final FormatOptions formatOptions) {
- if (supportsDynamicUpdate(formatOptions)) {
- if (address == FormatSpec.NO_PARENT_ADDRESS) {
- buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
- } else {
- final int absAddress = Math.abs(address);
- assert(absAddress <= SINT24_MAX);
- buffer[index] = (byte)((address < 0 ? MSB8 : 0)
- | ((absAddress >> 16) & 0xFF));
- buffer[index + 1] = (byte)((absAddress >> 8) & 0xFF);
- buffer[index + 2] = (byte)(absAddress & 0xFF);
- }
- return index + 3;
- } else {
- return index;
- }
- }
-
- /**
- * Write a node to memory. The node is expected to have its final position cached.
- *
- * This can be an empty map, but the more is inside the faster the lookups will be. It can
- * be carried on as long as nodes do not move.
- *
- * @param dict the dictionary the node is a part of (for relative offsets).
- * @param buffer the memory buffer to write to.
- * @param node the node to write.
- * @param formatOptions file format options.
- * @return the address of the END of the node.
- */
- @SuppressWarnings("unused")
- private static int writePlacedNode(final FusionDictionary dict, byte[] buffer,
- final Node node, final FormatOptions formatOptions) {
- // TODO: Make the code in common with BinaryDictIOUtils#writeCharGroup
- int index = node.mCachedAddressAfterUpdate;
-
- final int groupCount = node.mData.size();
- final int countSize = getGroupCountSize(node);
- final int parentAddress = node.mCachedParentAddress;
- if (1 == countSize) {
- buffer[index++] = (byte)groupCount;
- } else if (2 == countSize) {
- // We need to signal 2-byte size by setting the top bit of the MSB to 1, so
- // we | 0x80 to do this.
- buffer[index++] = (byte)((groupCount >> 8) | 0x80);
- buffer[index++] = (byte)(groupCount & 0xFF);
- } else {
- throw new RuntimeException("Strange size from getGroupCountSize : " + countSize);
- }
- int groupAddress = index;
- for (int i = 0; i < groupCount; ++i) {
- final CharGroup group = node.mData.get(i);
- if (index != group.mCachedAddressAfterUpdate) {
- throw new RuntimeException("Bug: write index is not the same as the cached address "
- + "of the group : " + index + " <> " + group.mCachedAddressAfterUpdate);
- }
- groupAddress += getGroupHeaderSize(group, formatOptions);
- // Sanity checks.
- if (DBG && group.mFrequency > FormatSpec.MAX_TERMINAL_FREQUENCY) {
- throw new RuntimeException("A node has a frequency > "
- + FormatSpec.MAX_TERMINAL_FREQUENCY
- + " : " + group.mFrequency);
- }
- if (group.mFrequency >= 0) groupAddress += FormatSpec.GROUP_FREQUENCY_SIZE;
- final int childrenOffset = null == group.mChildren
- ? FormatSpec.NO_CHILDREN_ADDRESS
- : group.mChildren.mCachedAddressAfterUpdate - groupAddress;
- buffer[index++] =
- makeCharGroupFlags(group, groupAddress, childrenOffset, formatOptions);
-
- if (parentAddress == FormatSpec.NO_PARENT_ADDRESS) {
- index = writeParentAddress(buffer, index, parentAddress, formatOptions);
- } else {
- index = writeParentAddress(buffer, index, parentAddress
- + (node.mCachedAddressAfterUpdate - group.mCachedAddressAfterUpdate),
- formatOptions);
- }
-
- index = CharEncoding.writeCharArray(group.mChars, buffer, index);
- if (group.hasSeveralChars()) {
- buffer[index++] = FormatSpec.GROUP_CHARACTERS_TERMINATOR;
- }
- if (group.mFrequency >= 0) {
- buffer[index++] = (byte) group.mFrequency;
- }
-
- final int shift;
- if (formatOptions.mSupportsDynamicUpdate) {
- shift = writeVariableSignedAddress(buffer, index, childrenOffset);
- } else {
- shift = writeVariableAddress(buffer, index, childrenOffset);
- }
- index += shift;
- groupAddress += shift;
-
- // Write shortcuts
- if (null != group.mShortcutTargets) {
- final int indexOfShortcutByteSize = index;
- index += FormatSpec.GROUP_SHORTCUT_LIST_SIZE_SIZE;
- groupAddress += FormatSpec.GROUP_SHORTCUT_LIST_SIZE_SIZE;
- final Iterator<WeightedString> shortcutIterator = group.mShortcutTargets.iterator();
- while (shortcutIterator.hasNext()) {
- final WeightedString target = shortcutIterator.next();
- ++groupAddress;
- int shortcutFlags = makeShortcutFlags(shortcutIterator.hasNext(),
- target.mFrequency);
- buffer[index++] = (byte)shortcutFlags;
- final int shortcutShift = CharEncoding.writeString(buffer, index, target.mWord);
- index += shortcutShift;
- groupAddress += shortcutShift;
- }
- final int shortcutByteSize = index - indexOfShortcutByteSize;
- if (shortcutByteSize > 0xFFFF) {
- throw new RuntimeException("Shortcut list too large");
- }
- buffer[indexOfShortcutByteSize] = (byte)(shortcutByteSize >> 8);
- buffer[indexOfShortcutByteSize + 1] = (byte)(shortcutByteSize & 0xFF);
- }
- // Write bigrams
- if (null != group.mBigrams) {
- final Iterator<WeightedString> bigramIterator = group.mBigrams.iterator();
- while (bigramIterator.hasNext()) {
- final WeightedString bigram = bigramIterator.next();
- final CharGroup target =
- FusionDictionary.findWordInTree(dict.mRoot, bigram.mWord);
- final int addressOfBigram = target.mCachedAddressAfterUpdate;
- final int unigramFrequencyForThisWord = target.mFrequency;
- ++groupAddress;
- final int offset = addressOfBigram - groupAddress;
- int bigramFlags = makeBigramFlags(bigramIterator.hasNext(), offset,
- bigram.mFrequency, unigramFrequencyForThisWord, bigram.mWord);
- buffer[index++] = (byte)bigramFlags;
- final int bigramShift = writeVariableAddress(buffer, index, Math.abs(offset));
- index += bigramShift;
- groupAddress += bigramShift;
- }
- }
-
- }
- if (formatOptions.mSupportsDynamicUpdate) {
- buffer[index] = buffer[index + 1] = buffer[index + 2]
- = FormatSpec.NO_FORWARD_LINK_ADDRESS;
- index += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
- }
- if (index != node.mCachedAddressAfterUpdate + node.mCachedSize) throw new RuntimeException(
- "Not the same size : written "
- + (index - node.mCachedAddressAfterUpdate) + " bytes from a node that should have "
- + node.mCachedSize + " bytes");
- return index;
- }
-
- /**
- * Dumps a collection of useful statistics about a node array.
- *
- * This prints purely informative stuff, like the total estimated file size, the
- * number of nodes, of character groups, the repartition of each address size, etc
- *
- * @param nodes the node array.
- */
- private static void showStatistics(ArrayList<Node> nodes) {
- int firstTerminalAddress = Integer.MAX_VALUE;
- int lastTerminalAddress = Integer.MIN_VALUE;
- int size = 0;
- int charGroups = 0;
- int maxGroups = 0;
- int maxRuns = 0;
- for (final Node n : nodes) {
- if (maxGroups < n.mData.size()) maxGroups = n.mData.size();
- for (final CharGroup cg : n.mData) {
- ++charGroups;
- if (cg.mChars.length > maxRuns) maxRuns = cg.mChars.length;
- if (cg.mFrequency >= 0) {
- if (n.mCachedAddressAfterUpdate < firstTerminalAddress)
- firstTerminalAddress = n.mCachedAddressAfterUpdate;
- if (n.mCachedAddressAfterUpdate > lastTerminalAddress)
- lastTerminalAddress = n.mCachedAddressAfterUpdate;
- }
- }
- if (n.mCachedAddressAfterUpdate + n.mCachedSize > size) {
- size = n.mCachedAddressAfterUpdate + n.mCachedSize;
- }
- }
- final int[] groupCounts = new int[maxGroups + 1];
- final int[] runCounts = new int[maxRuns + 1];
- for (final Node n : nodes) {
- ++groupCounts[n.mData.size()];
- for (final CharGroup cg : n.mData) {
- ++runCounts[cg.mChars.length];
- }
- }
-
- MakedictLog.i("Statistics:\n"
- + " total file size " + size + "\n"
- + " " + nodes.size() + " nodes\n"
- + " " + charGroups + " groups (" + ((float)charGroups / nodes.size())
- + " groups per node)\n"
- + " first terminal at " + firstTerminalAddress + "\n"
- + " last terminal at " + lastTerminalAddress + "\n"
- + " Group stats : max = " + maxGroups);
- for (int i = 0; i < groupCounts.length; ++i) {
- MakedictLog.i(" " + i + " : " + groupCounts[i]);
- }
- MakedictLog.i(" Character run stats : max = " + maxRuns);
- for (int i = 0; i < runCounts.length; ++i) {
- MakedictLog.i(" " + i + " : " + runCounts[i]);
- }
- }
-
- /**
- * Dumps a FusionDictionary to a file.
- *
- * This is the public entry point to write a dictionary to a file.
- *
- * @param destination the stream to write the binary data to.
- * @param dict the dictionary to write.
- * @param formatOptions file format options.
- */
- public static void writeDictionaryBinary(final OutputStream destination,
- final FusionDictionary dict, final FormatOptions formatOptions)
- throws IOException, UnsupportedFormatException {
-
- // Addresses are limited to 3 bytes, but since addresses can be relative to each node, the
- // structure itself is not limited to 16MB. However, if it is over 16MB deciding the order
- // of the nodes becomes a quite complicated problem, because though the dictionary itself
- // does not have a size limit, each node must still be within 16MB of all its children and
- // parents. As long as this is ensured, the dictionary file may grow to any size.
-
- final int version = formatOptions.mVersion;
- if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
- || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
- throw new UnsupportedFormatException("Requested file format version " + version
- + ", but this implementation only supports versions "
- + FormatSpec.MINIMUM_SUPPORTED_VERSION + " through "
- + FormatSpec.MAXIMUM_SUPPORTED_VERSION);
- }
-
- ByteArrayOutputStream headerBuffer = new ByteArrayOutputStream(256);
-
- // The magic number in big-endian order.
- if (version >= FormatSpec.FIRST_VERSION_WITH_HEADER_SIZE) {
- // Magic number for version 2+.
- headerBuffer.write((byte) (0xFF & (FormatSpec.VERSION_2_MAGIC_NUMBER >> 24)));
- headerBuffer.write((byte) (0xFF & (FormatSpec.VERSION_2_MAGIC_NUMBER >> 16)));
- headerBuffer.write((byte) (0xFF & (FormatSpec.VERSION_2_MAGIC_NUMBER >> 8)));
- headerBuffer.write((byte) (0xFF & FormatSpec.VERSION_2_MAGIC_NUMBER));
- // Dictionary version.
- headerBuffer.write((byte) (0xFF & (version >> 8)));
- headerBuffer.write((byte) (0xFF & version));
- } else {
- // Magic number for version 1.
- headerBuffer.write((byte) (0xFF & (FormatSpec.VERSION_1_MAGIC_NUMBER >> 8)));
- headerBuffer.write((byte) (0xFF & FormatSpec.VERSION_1_MAGIC_NUMBER));
- // Dictionary version.
- headerBuffer.write((byte) (0xFF & version));
- }
- // Options flags
- final int options = makeOptionsValue(dict, formatOptions);
- headerBuffer.write((byte) (0xFF & (options >> 8)));
- headerBuffer.write((byte) (0xFF & options));
- if (version >= FormatSpec.FIRST_VERSION_WITH_HEADER_SIZE) {
- final int headerSizeOffset = headerBuffer.size();
- // Placeholder to be written later with header size.
- for (int i = 0; i < 4; ++i) {
- headerBuffer.write(0);
- }
- // Write out the options.
- for (final String key : dict.mOptions.mAttributes.keySet()) {
- final String value = dict.mOptions.mAttributes.get(key);
- CharEncoding.writeString(headerBuffer, key);
- CharEncoding.writeString(headerBuffer, value);
- }
- final int size = headerBuffer.size();
- final byte[] bytes = headerBuffer.toByteArray();
- // Write out the header size.
- bytes[headerSizeOffset] = (byte) (0xFF & (size >> 24));
- bytes[headerSizeOffset + 1] = (byte) (0xFF & (size >> 16));
- bytes[headerSizeOffset + 2] = (byte) (0xFF & (size >> 8));
- bytes[headerSizeOffset + 3] = (byte) (0xFF & (size >> 0));
- destination.write(bytes);
- } else {
- headerBuffer.writeTo(destination);
- }
-
- headerBuffer.close();
-
- // Leave the choice of the optimal node order to the flattenTree function.
- MakedictLog.i("Flattening the tree...");
- ArrayList<Node> flatNodes = flattenTree(dict.mRoot);
-
- MakedictLog.i("Computing addresses...");
- computeAddresses(dict, flatNodes, formatOptions);
- MakedictLog.i("Checking array...");
- if (DBG) checkFlatNodeArray(flatNodes);
-
- // Create a buffer that matches the final dictionary size.
- final Node lastNode = flatNodes.get(flatNodes.size() - 1);
- final int bufferSize = lastNode.mCachedAddressAfterUpdate + lastNode.mCachedSize;
- final byte[] buffer = new byte[bufferSize];
- int index = 0;
-
- MakedictLog.i("Writing file...");
- int dataEndOffset = 0;
- for (Node n : flatNodes) {
- dataEndOffset = writePlacedNode(dict, buffer, n, formatOptions);
- }
-
- if (DBG) showStatistics(flatNodes);
-
- destination.write(buffer, 0, dataEndOffset);
-
- destination.close();
- MakedictLog.i("Done");
- }
-
-
- // Input methods: Read a binary dictionary to memory.
- // readDictionaryBinary is the public entry point for them.
-
- static int getChildrenAddressSize(final int optionFlags,
- final FormatOptions formatOptions) {
- if (formatOptions.mSupportsDynamicUpdate) return FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
- switch (optionFlags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) {
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE:
- return 1;
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES:
- return 2;
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES:
- return 3;
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS:
- default:
- return 0;
- }
- }
-
- static int readChildrenAddress(final FusionDictionaryBufferInterface buffer,
- final int optionFlags, final FormatOptions options) {
- if (options.mSupportsDynamicUpdate) {
- final int address = buffer.readUnsignedInt24();
- if (address == 0) return FormatSpec.NO_CHILDREN_ADDRESS;
- if ((address & MSB24) != 0) {
- return -(address & SINT24_MAX);
- } else {
- return address;
- }
- }
- int address;
- switch (optionFlags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) {
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE:
- return buffer.readUnsignedByte();
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES:
- return buffer.readUnsignedShort();
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES:
- return buffer.readUnsignedInt24();
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS:
- default:
- return FormatSpec.NO_CHILDREN_ADDRESS;
- }
- }
-
- static int readParentAddress(final FusionDictionaryBufferInterface buffer,
- final FormatOptions formatOptions) {
- if (supportsDynamicUpdate(formatOptions)) {
- final int parentAddress = buffer.readUnsignedInt24();
- final int sign = ((parentAddress & MSB24) != 0) ? -1 : 1;
- return sign * (parentAddress & SINT24_MAX);
- } else {
- return FormatSpec.NO_PARENT_ADDRESS;
- }
- }
-
- private static final int[] CHARACTER_BUFFER = new int[FormatSpec.MAX_WORD_LENGTH];
- public static CharGroupInfo readCharGroup(final FusionDictionaryBufferInterface buffer,
- final int originalGroupAddress, final FormatOptions options) {
- int addressPointer = originalGroupAddress;
- final int flags = buffer.readUnsignedByte();
- ++addressPointer;
-
- final int parentAddress = readParentAddress(buffer, options);
- if (supportsDynamicUpdate(options)) {
- addressPointer += 3;
- }
-
- final int characters[];
- if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) {
- int index = 0;
- int character = CharEncoding.readChar(buffer);
- addressPointer += CharEncoding.getCharSize(character);
- while (-1 != character) {
- // FusionDictionary is making sure that the length of the word is smaller than
- // MAX_WORD_LENGTH.
- // So we'll never write past the end of CHARACTER_BUFFER.
- CHARACTER_BUFFER[index++] = character;
- character = CharEncoding.readChar(buffer);
- addressPointer += CharEncoding.getCharSize(character);
- }
- characters = Arrays.copyOfRange(CHARACTER_BUFFER, 0, index);
- } else {
- final int character = CharEncoding.readChar(buffer);
- addressPointer += CharEncoding.getCharSize(character);
- characters = new int[] { character };
- }
- final int frequency;
- if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
- ++addressPointer;
- frequency = buffer.readUnsignedByte();
- } else {
- frequency = CharGroup.NOT_A_TERMINAL;
- }
- int childrenAddress = readChildrenAddress(buffer, flags, options);
- if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
- childrenAddress += addressPointer;
- }
- addressPointer += getChildrenAddressSize(flags, options);
- ArrayList<WeightedString> shortcutTargets = null;
- if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) {
- final int pointerBefore = buffer.position();
- shortcutTargets = new ArrayList<WeightedString>();
- buffer.readUnsignedShort(); // Skip the size
- while (true) {
- final int targetFlags = buffer.readUnsignedByte();
- final String word = CharEncoding.readString(buffer);
- shortcutTargets.add(new WeightedString(word,
- targetFlags & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY));
- if (0 == (targetFlags & FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT)) break;
- }
- addressPointer += buffer.position() - pointerBefore;
- }
- ArrayList<PendingAttribute> bigrams = null;
- if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
- bigrams = new ArrayList<PendingAttribute>();
- int bigramCount = 0;
- while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
- final int bigramFlags = buffer.readUnsignedByte();
- ++addressPointer;
- final int sign = 0 == (bigramFlags & FormatSpec.FLAG_ATTRIBUTE_OFFSET_NEGATIVE)
- ? 1 : -1;
- int bigramAddress = addressPointer;
- switch (bigramFlags & FormatSpec.MASK_ATTRIBUTE_ADDRESS_TYPE) {
- case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE:
- bigramAddress += sign * buffer.readUnsignedByte();
- addressPointer += 1;
- break;
- case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES:
- bigramAddress += sign * buffer.readUnsignedShort();
- addressPointer += 2;
- break;
- case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES:
- final int offset = (buffer.readUnsignedByte() << 16)
- + buffer.readUnsignedShort();
- bigramAddress += sign * offset;
- addressPointer += 3;
- break;
- default:
- throw new RuntimeException("Has bigrams with no address");
- }
- bigrams.add(new PendingAttribute(bigramFlags & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY,
- bigramAddress));
- if (0 == (bigramFlags & FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT)) break;
- }
- if (bigramCount >= FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
- MakedictLog.d("too many bigrams in a group.");
- }
- }
- return new CharGroupInfo(originalGroupAddress, addressPointer, flags, characters, frequency,
- parentAddress, childrenAddress, shortcutTargets, bigrams);
- }
-
- /**
- * Reads and returns the char group count out of a buffer and forwards the pointer.
- */
- public static int readCharGroupCount(final FusionDictionaryBufferInterface buffer) {
- final int msb = buffer.readUnsignedByte();
- if (FormatSpec.MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT >= msb) {
- return msb;
- } else {
- return ((FormatSpec.MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT & msb) << 8)
- + buffer.readUnsignedByte();
- }
- }
-
- // The word cache here is a stopgap bandaid to help the catastrophic performance
- // of this method. Since it performs direct, unbuffered random access to the file and
- // may be called hundreds of thousands of times, the resulting performance is not
- // reasonable without some kind of cache. Thus:
- private static TreeMap<Integer, WeightedString> wordCache =
- new TreeMap<Integer, WeightedString>();
- /**
- * Finds, as a string, the word at the address passed as an argument.
- *
- * @param buffer the buffer to read from.
- * @param headerSize the size of the header.
- * @param address the address to seek.
- * @param formatOptions file format options.
- * @return the word with its frequency, as a weighted string.
- */
- /* package for tests */ static WeightedString getWordAtAddress(
- final FusionDictionaryBufferInterface buffer, final int headerSize, final int address,
- final FormatOptions formatOptions) {
- final WeightedString cachedString = wordCache.get(address);
- if (null != cachedString) return cachedString;
-
- final WeightedString result;
- final int originalPointer = buffer.position();
- buffer.position(address);
-
- if (supportsDynamicUpdate(formatOptions)) {
- result = getWordAtAddressWithParentAddress(buffer, headerSize, address, formatOptions);
- } else {
- result = getWordAtAddressWithoutParentAddress(buffer, headerSize, address,
- formatOptions);
- }
-
- wordCache.put(address, result);
- buffer.position(originalPointer);
- return result;
- }
-
- // TODO: static!? This will behave erratically when used in multi-threaded code.
- // We need to fix this
- private static int[] sGetWordBuffer = new int[FormatSpec.MAX_WORD_LENGTH];
- @SuppressWarnings("unused")
- private static WeightedString getWordAtAddressWithParentAddress(
- final FusionDictionaryBufferInterface buffer, final int headerSize, final int address,
- final FormatOptions options) {
- int currentAddress = address;
- int index = FormatSpec.MAX_WORD_LENGTH - 1;
- int frequency = Integer.MIN_VALUE;
- // the length of the path from the root to the leaf is limited by MAX_WORD_LENGTH
- for (int count = 0; count < FormatSpec.MAX_WORD_LENGTH; ++count) {
- CharGroupInfo currentInfo;
- int loopCounter = 0;
- do {
- buffer.position(currentAddress + headerSize);
- currentInfo = readCharGroup(buffer, currentAddress, options);
- if (isMovedGroup(currentInfo.mFlags, options)) {
- currentAddress = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
- }
- if (DBG && loopCounter++ > MAX_JUMPS) {
- MakedictLog.d("Too many jumps - probably a bug");
- }
- } while (isMovedGroup(currentInfo.mFlags, options));
- if (Integer.MIN_VALUE == frequency) frequency = currentInfo.mFrequency;
- for (int i = 0; i < currentInfo.mCharacters.length; ++i) {
- sGetWordBuffer[index--] =
- currentInfo.mCharacters[currentInfo.mCharacters.length - i - 1];
- }
- if (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS) break;
- currentAddress = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
- }
-
- return new WeightedString(
- new String(sGetWordBuffer, index + 1, FormatSpec.MAX_WORD_LENGTH - index - 1),
- frequency);
- }
-
- private static WeightedString getWordAtAddressWithoutParentAddress(
- final FusionDictionaryBufferInterface buffer, final int headerSize, final int address,
- final FormatOptions options) {
- buffer.position(headerSize);
- final int count = readCharGroupCount(buffer);
- int groupOffset = getGroupCountSize(count);
- final StringBuilder builder = new StringBuilder();
- WeightedString result = null;
-
- CharGroupInfo last = null;
- for (int i = count - 1; i >= 0; --i) {
- CharGroupInfo info = readCharGroup(buffer, groupOffset, options);
- groupOffset = info.mEndAddress;
- if (info.mOriginalAddress == address) {
- builder.append(new String(info.mCharacters, 0, info.mCharacters.length));
- result = new WeightedString(builder.toString(), info.mFrequency);
- break; // and return
- }
- if (hasChildrenAddress(info.mChildrenAddress)) {
- if (info.mChildrenAddress > address) {
- if (null == last) continue;
- builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
- buffer.position(last.mChildrenAddress + headerSize);
- i = readCharGroupCount(buffer);
- groupOffset = last.mChildrenAddress + getGroupCountSize(i);
- last = null;
- continue;
- }
- last = info;
- }
- if (0 == i && hasChildrenAddress(last.mChildrenAddress)) {
- builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
- buffer.position(last.mChildrenAddress + headerSize);
- i = readCharGroupCount(buffer);
- groupOffset = last.mChildrenAddress + getGroupCountSize(i);
- last = null;
- continue;
- }
- }
- return result;
- }
-
- /**
- * Reads a single node from a buffer.
- *
- * This methods reads the file at the current position. A node is fully expected to start at
- * the current position.
- * This will recursively read other nodes into the structure, populating the reverse
- * maps on the fly and using them to keep track of already read nodes.
- *
- * @param buffer the buffer, correctly positioned at the start of a node.
- * @param headerSize the size, in bytes, of the file header.
- * @param reverseNodeMap a mapping from addresses to already read nodes.
- * @param reverseGroupMap a mapping from addresses to already read character groups.
- * @param options file format options.
- * @return the read node with all his children already read.
- */
- private static Node readNode(final FusionDictionaryBufferInterface buffer, final int headerSize,
- final Map<Integer, Node> reverseNodeMap, final Map<Integer, CharGroup> reverseGroupMap,
- final FormatOptions options)
- throws IOException {
- final ArrayList<CharGroup> nodeContents = new ArrayList<CharGroup>();
- final int nodeOrigin = buffer.position() - headerSize;
-
- do { // Scan the linked-list node.
- final int nodeHeadPosition = buffer.position() - headerSize;
- final int count = readCharGroupCount(buffer);
- int groupOffset = nodeHeadPosition + getGroupCountSize(count);
- for (int i = count; i > 0; --i) { // Scan the array of CharGroup.
- CharGroupInfo info = readCharGroup(buffer, groupOffset, options);
- if (isMovedGroup(info.mFlags, options)) continue;
- ArrayList<WeightedString> shortcutTargets = info.mShortcutTargets;
- ArrayList<WeightedString> bigrams = null;
- if (null != info.mBigrams) {
- bigrams = new ArrayList<WeightedString>();
- for (PendingAttribute bigram : info.mBigrams) {
- final WeightedString word = getWordAtAddress(
- buffer, headerSize, bigram.mAddress, options);
- final int reconstructedFrequency =
- reconstructBigramFrequency(word.mFrequency, bigram.mFrequency);
- bigrams.add(new WeightedString(word.mWord, reconstructedFrequency));
- }
- }
- if (hasChildrenAddress(info.mChildrenAddress)) {
- Node children = reverseNodeMap.get(info.mChildrenAddress);
- if (null == children) {
- final int currentPosition = buffer.position();
- buffer.position(info.mChildrenAddress + headerSize);
- children = readNode(
- buffer, headerSize, reverseNodeMap, reverseGroupMap, options);
- buffer.position(currentPosition);
- }
- nodeContents.add(
- new CharGroup(info.mCharacters, shortcutTargets, bigrams,
- info.mFrequency,
- 0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
- 0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED), children));
- } else {
- nodeContents.add(
- new CharGroup(info.mCharacters, shortcutTargets, bigrams,
- info.mFrequency,
- 0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
- 0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED)));
- }
- groupOffset = info.mEndAddress;
- }
-
- // reach the end of the array.
- if (options.mSupportsDynamicUpdate) {
- final int nextAddress = buffer.readUnsignedInt24();
- if (nextAddress >= 0 && nextAddress < buffer.limit()) {
- buffer.position(nextAddress);
- } else {
- break;
- }
- }
- } while (options.mSupportsDynamicUpdate &&
- buffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
-
- final Node node = new Node(nodeContents);
- node.mCachedAddressBeforeUpdate = nodeOrigin;
- node.mCachedAddressAfterUpdate = nodeOrigin;
- reverseNodeMap.put(node.mCachedAddressAfterUpdate, node);
- return node;
- }
-
- /**
- * Helper function to get the binary format version from the header.
- * @throws IOException
- */
- private static int getFormatVersion(final FusionDictionaryBufferInterface buffer)
- throws IOException {
- final int magic_v1 = buffer.readUnsignedShort();
- if (FormatSpec.VERSION_1_MAGIC_NUMBER == magic_v1) return buffer.readUnsignedByte();
- final int magic_v2 = (magic_v1 << 16) + buffer.readUnsignedShort();
- if (FormatSpec.VERSION_2_MAGIC_NUMBER == magic_v2) return buffer.readUnsignedShort();
- return FormatSpec.NOT_A_VERSION_NUMBER;
- }
-
- /**
- * Helper function to get and validate the binary format version.
- * @throws UnsupportedFormatException
- * @throws IOException
- */
- private static int checkFormatVersion(final FusionDictionaryBufferInterface buffer)
- throws IOException, UnsupportedFormatException {
- final int version = getFormatVersion(buffer);
- if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
- || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
- throw new UnsupportedFormatException("This file has version " + version
- + ", but this implementation does not support versions above "
- + FormatSpec.MAXIMUM_SUPPORTED_VERSION);
- }
- return version;
- }
-
- /**
- * Reads a header from a buffer.
- * @param buffer the buffer to read.
- * @throws IOException
- * @throws UnsupportedFormatException
- */
- public static FileHeader readHeader(final FusionDictionaryBufferInterface buffer)
- throws IOException, UnsupportedFormatException {
- final int version = checkFormatVersion(buffer);
- final int optionsFlags = buffer.readUnsignedShort();
-
- final HashMap<String, String> attributes = new HashMap<String, String>();
- final int headerSize;
- if (version < FormatSpec.FIRST_VERSION_WITH_HEADER_SIZE) {
- headerSize = buffer.position();
- } else {
- headerSize = buffer.readInt();
- populateOptions(buffer, headerSize, attributes);
- buffer.position(headerSize);
- }
-
- if (headerSize < 0) {
- throw new UnsupportedFormatException("header size can't be negative.");
- }
-
- final FileHeader header = new FileHeader(headerSize,
- new FusionDictionary.DictionaryOptions(attributes,
- 0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG),
- 0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)),
- new FormatOptions(version,
- 0 != (optionsFlags & FormatSpec.SUPPORTS_DYNAMIC_UPDATE)));
- return header;
- }
-
- /**
- * Reads options from a buffer and populate a map with their contents.
- *
- * The buffer is read at the current position, so the caller must take care the pointer
- * is in the right place before calling this.
- */
- public static void populateOptions(final FusionDictionaryBufferInterface buffer,
- final int headerSize, final HashMap<String, String> options) {
- while (buffer.position() < headerSize) {
- final String key = CharEncoding.readString(buffer);
- final String value = CharEncoding.readString(buffer);
- options.put(key, value);
- }
- }
-
- /**
- * Reads a buffer and returns the memory representation of the dictionary.
- *
- * This high-level method takes a buffer and reads its contents, populating a
- * FusionDictionary structure. The optional dict argument is an existing dictionary to
- * which words from the buffer should be added. If it is null, a new dictionary is created.
- *
- * @param buffer the buffer to read.
- * @param dict an optional dictionary to add words to, or null.
- * @return the created (or merged) dictionary.
- */
- @UsedForTesting
- public static FusionDictionary readDictionaryBinary(
- final FusionDictionaryBufferInterface buffer, final FusionDictionary dict)
- throws IOException, UnsupportedFormatException {
- // clear cache
- wordCache.clear();
-
- // Read header
- final FileHeader header = readHeader(buffer);
-
- Map<Integer, Node> reverseNodeMapping = new TreeMap<Integer, Node>();
- Map<Integer, CharGroup> reverseGroupMapping = new TreeMap<Integer, CharGroup>();
- final Node root = readNode(buffer, header.mHeaderSize, reverseNodeMapping,
- reverseGroupMapping, header.mFormatOptions);
-
- FusionDictionary newDict = new FusionDictionary(root, header.mDictionaryOptions);
- if (null != dict) {
- for (final Word w : dict) {
- if (w.mIsBlacklistEntry) {
- newDict.addBlacklistEntry(w.mWord, w.mShortcutTargets, w.mIsNotAWord);
- } else {
- newDict.add(w.mWord, w.mFrequency, w.mShortcutTargets, w.mIsNotAWord);
- }
- }
- for (final Word w : dict) {
- // By construction a binary dictionary may not have bigrams pointing to
- // words that are not also registered as unigrams so we don't have to avoid
- // them explicitly here.
- for (final WeightedString bigram : w.mBigrams) {
- newDict.setBigram(w.mWord, bigram.mWord, bigram.mFrequency);
- }
- }
- }
-
- return newDict;
- }
-
- /**
- * Helper method to pass a file name instead of a File object to isBinaryDictionary.
- */
- public static boolean isBinaryDictionary(final String filename) {
- final File file = new File(filename);
- return isBinaryDictionary(file);
- }
-
- /**
- * Basic test to find out whether the file is a binary dictionary or not.
- *
- * Concretely this only tests the magic number.
- *
- * @param file The file to test.
- * @return true if it's a binary dictionary, false otherwise
- */
- public static boolean isBinaryDictionary(final File file) {
- FileInputStream inStream = null;
- try {
- inStream = new FileInputStream(file);
- final ByteBuffer buffer = inStream.getChannel().map(
- FileChannel.MapMode.READ_ONLY, 0, file.length());
- final int version = getFormatVersion(new ByteBufferWrapper(buffer));
- return (version >= FormatSpec.MINIMUM_SUPPORTED_VERSION
- && version <= FormatSpec.MAXIMUM_SUPPORTED_VERSION);
- } catch (FileNotFoundException e) {
- return false;
- } catch (IOException e) {
- return false;
- } finally {
- if (inStream != null) {
- try {
- inStream.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- }
- }
-
- /**
- * Calculate bigram frequency from compressed value
- *
- * @see #makeBigramFlags
- *
- * @param unigramFrequency
- * @param bigramFrequency compressed frequency
- * @return approximate bigram frequency
- */
- public static int reconstructBigramFrequency(final int unigramFrequency,
- final int bigramFrequency) {
- final float stepSize = (FormatSpec.MAX_TERMINAL_FREQUENCY - unigramFrequency)
- / (1.5f + FormatSpec.MAX_BIGRAM_FREQUENCY);
- final float resultFreqFloat = unigramFrequency + stepSize * (bigramFrequency + 1.0f);
- return (int)resultFreqFloat;
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
new file mode 100644
index 000000000..3796a466c
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.TreeMap;
+
+/**
+ * The base class of binary dictionary decoders.
+ */
+public abstract class DictDecoder {
+
+ protected FileHeader readHeader(final DictBuffer dictBuffer)
+ throws IOException, UnsupportedFormatException {
+ if (dictBuffer == null) {
+ openDictBuffer();
+ }
+
+ final int version = HeaderReader.readVersion(dictBuffer);
+ if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
+ || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
+ throw new UnsupportedFormatException("Unsupported version : " + version);
+ }
+ // TODO: Remove this field.
+ final int optionsFlags = HeaderReader.readOptionFlags(dictBuffer);
+
+ final int headerSize = HeaderReader.readHeaderSize(dictBuffer);
+
+ if (headerSize < 0) {
+ throw new UnsupportedFormatException("header size can't be negative.");
+ }
+
+ final HashMap<String, String> attributes = HeaderReader.readAttributes(dictBuffer,
+ headerSize);
+
+ final FileHeader header = new FileHeader(headerSize,
+ new FusionDictionary.DictionaryOptions(attributes,
+ 0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG),
+ 0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)),
+ new FormatOptions(version,
+ 0 != (optionsFlags & FormatSpec.SUPPORTS_DYNAMIC_UPDATE)));
+ return header;
+ }
+
+ /**
+ * Reads and returns the file header.
+ */
+ public abstract FileHeader readHeader() throws IOException, UnsupportedFormatException;
+
+ /**
+ * Reads PtNode from nodeAddress.
+ * @param ptNodePos the position of PtNode.
+ * @param formatOptions the format options.
+ * @return PtNodeInfo.
+ */
+ public abstract PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions formatOptions);
+
+ /**
+ * Reads a buffer and returns the memory representation of the dictionary.
+ *
+ * This high-level method takes a buffer and reads its contents, populating a
+ * FusionDictionary structure. The optional dict argument is an existing dictionary to
+ * which words from the buffer should be added. If it is null, a new dictionary is created.
+ *
+ * @param dict an optional dictionary to add words to, or null.
+ * @param deleteDictIfBroken a flag indicating whether this method should remove the broken
+ * dictionary or not.
+ * @return the created (or merged) dictionary.
+ */
+ @UsedForTesting
+ public abstract FusionDictionary readDictionaryBinary(final FusionDictionary dict,
+ final boolean deleteDictIfBroken)
+ throws FileNotFoundException, IOException, UnsupportedFormatException;
+
+ /**
+ * Gets the address of the last PtNode of the exact matching word in the dictionary.
+ * If no match is found, returns NOT_VALID_WORD.
+ *
+ * @param word the word we search for.
+ * @return the address of the terminal node.
+ * @throws IOException if the file can't be read.
+ * @throws UnsupportedFormatException if the format of the file is not recognized.
+ */
+ @UsedForTesting
+ public int getTerminalPosition(final String word)
+ throws IOException, UnsupportedFormatException {
+ if (!isDictBufferOpen()) {
+ openDictBuffer();
+ }
+ return BinaryDictIOUtils.getTerminalPosition(this, word);
+ }
+
+ /**
+ * Reads unigrams and bigrams from the binary file.
+ * Doesn't store a full memory representation of the dictionary.
+ *
+ * @param words the map to store the address as a key and the word as a value.
+ * @param frequencies the map to store the address as a key and the frequency as a value.
+ * @param bigrams the map to store the address as a key and the list of address as a value.
+ * @throws IOException if the file can't be read.
+ * @throws UnsupportedFormatException if the format of the file is not recognized.
+ */
+ @UsedForTesting
+ public void readUnigramsAndBigramsBinary(final TreeMap<Integer, String> words,
+ final TreeMap<Integer, Integer> frequencies,
+ final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams)
+ throws IOException, UnsupportedFormatException {
+ if (!isDictBufferOpen()) {
+ openDictBuffer();
+ }
+ BinaryDictIOUtils.readUnigramsAndBigramsBinary(this, words, frequencies, bigrams);
+ }
+
+ /**
+ * Sets the position of the buffer to the given value.
+ *
+ * @param newPos the new position
+ */
+ public abstract void setPosition(final int newPos);
+
+ /**
+ * Gets the position of the buffer.
+ *
+ * @return the position
+ */
+ public abstract int getPosition();
+
+ /**
+ * Reads and returns the PtNode count out of a buffer and forwards the pointer.
+ */
+ public abstract int readPtNodeCount();
+
+ /**
+ * Reads the forward link and advances the position.
+ *
+ * @return true if this method moves the file pointer, false otherwise.
+ */
+ public abstract boolean readAndFollowForwardLink();
+ public abstract boolean hasNextPtNodeArray();
+
+ /**
+ * Opens the dictionary file and makes DictBuffer.
+ */
+ @UsedForTesting
+ public abstract void openDictBuffer() throws FileNotFoundException, IOException;
+ @UsedForTesting
+ public abstract boolean isDictBufferOpen();
+
+ // Constants for DictionaryBufferFactory.
+ public static final int USE_READONLY_BYTEBUFFER = 0x01000000;
+ public static final int USE_BYTEARRAY = 0x02000000;
+ public static final int USE_WRITABLE_BYTEBUFFER = 0x03000000;
+ public static final int MASK_DICTBUFFER = 0x0F000000;
+
+ public interface DictionaryBufferFactory {
+ public DictBuffer getDictionaryBuffer(final File file)
+ throws FileNotFoundException, IOException;
+ }
+
+ /**
+ * Creates DictionaryBuffer using a ByteBuffer
+ *
+ * This class uses less memory than DictionaryBufferFromByteArrayFactory,
+ * but doesn't perform as fast.
+ * When operating on a big dictionary, this class is preferred.
+ */
+ public static final class DictionaryBufferFromReadOnlyByteBufferFactory
+ implements DictionaryBufferFactory {
+ @Override
+ public DictBuffer getDictionaryBuffer(final File file)
+ throws FileNotFoundException, IOException {
+ FileInputStream inStream = null;
+ ByteBuffer buffer = null;
+ try {
+ inStream = new FileInputStream(file);
+ buffer = inStream.getChannel().map(FileChannel.MapMode.READ_ONLY,
+ 0, file.length());
+ } finally {
+ if (inStream != null) {
+ inStream.close();
+ }
+ }
+ if (buffer != null) {
+ return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Creates DictionaryBuffer using a byte array
+ *
+ * This class performs faster than other classes, but consumes more memory.
+ * When operating on a small dictionary, this class is preferred.
+ */
+ public static final class DictionaryBufferFromByteArrayFactory
+ implements DictionaryBufferFactory {
+ @Override
+ public DictBuffer getDictionaryBuffer(final File file)
+ throws FileNotFoundException, IOException {
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(file);
+ final byte[] array = new byte[(int) file.length()];
+ inStream.read(array);
+ return new ByteArrayDictBuffer(array);
+ } finally {
+ if (inStream != null) {
+ inStream.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates DictionaryBuffer using a writable ByteBuffer and a RandomAccessFile.
+ *
+ * This class doesn't perform as fast as other classes,
+ * but this class is the only option available for destructive operations (insert or delete)
+ * on a dictionary.
+ */
+ @UsedForTesting
+ public static final class DictionaryBufferFromWritableByteBufferFactory
+ implements DictionaryBufferFactory {
+ @Override
+ public DictBuffer getDictionaryBuffer(final File file)
+ throws FileNotFoundException, IOException {
+ RandomAccessFile raFile = null;
+ ByteBuffer buffer = null;
+ try {
+ raFile = new RandomAccessFile(file, "rw");
+ buffer = raFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, file.length());
+ } finally {
+ if (raFile != null) {
+ raFile.close();
+ }
+ }
+ if (buffer != null) {
+ return new BinaryDictDecoderUtils.ByteBufferDictBuffer(buffer);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * A utility class for reading a file header.
+ */
+ protected static class HeaderReader {
+ protected static int readVersion(final DictBuffer dictBuffer)
+ throws IOException, UnsupportedFormatException {
+ return BinaryDictDecoderUtils.checkFormatVersion(dictBuffer);
+ }
+
+ protected static int readOptionFlags(final DictBuffer dictBuffer) {
+ return dictBuffer.readUnsignedShort();
+ }
+
+ protected static int readHeaderSize(final DictBuffer dictBuffer) {
+ return dictBuffer.readInt();
+ }
+
+ protected static HashMap<String, String> readAttributes(final DictBuffer dictBuffer,
+ final int headerSize) {
+ final HashMap<String, String> attributes = new HashMap<String, String>();
+ while (dictBuffer.position() < headerSize) {
+ // We can avoid an infinite loop here since dictBuffer.position() is always
+ // increased by calling CharEncoding.readString.
+ final String key = CharEncoding.readString(dictBuffer);
+ final String value = CharEncoding.readString(dictBuffer);
+ attributes.put(key, value);
+ }
+ dictBuffer.position(headerSize);
+ return attributes;
+ }
+ }
+
+ /**
+ * A utility class for reading a PtNode.
+ */
+ protected static class PtNodeReader {
+ protected static int readPtNodeOptionFlags(final DictBuffer dictBuffer) {
+ return dictBuffer.readUnsignedByte();
+ }
+
+ protected static int readParentAddress(final DictBuffer dictBuffer,
+ final FormatOptions formatOptions) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ return BinaryDictDecoderUtils.readSInt24(dictBuffer);
+ } else {
+ return FormatSpec.NO_PARENT_ADDRESS;
+ }
+ }
+
+ protected static int readChildrenAddress(final DictBuffer dictBuffer, final int optionFlags,
+ final FormatOptions formatOptions) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ final int address = BinaryDictDecoderUtils.readSInt24(dictBuffer);
+ if (address == 0) return FormatSpec.NO_CHILDREN_ADDRESS;
+ return address;
+ } else {
+ switch (optionFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
+ return dictBuffer.readUnsignedByte();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES:
+ return dictBuffer.readUnsignedShort();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES:
+ return dictBuffer.readUnsignedInt24();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS:
+ default:
+ return FormatSpec.NO_CHILDREN_ADDRESS;
+ }
+ }
+ }
+
+ // Reads shortcuts and returns the read length.
+ protected static int readShortcut(final DictBuffer dictBuffer,
+ final ArrayList<WeightedString> shortcutTargets) {
+ final int pointerBefore = dictBuffer.position();
+ dictBuffer.readUnsignedShort(); // skip the size
+ while (true) {
+ final int targetFlags = dictBuffer.readUnsignedByte();
+ final String word = CharEncoding.readString(dictBuffer);
+ shortcutTargets.add(new WeightedString(word,
+ targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY));
+ if (0 == (targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
+ }
+ return dictBuffer.position() - pointerBefore;
+ }
+
+ protected static int readBigramAddresses(final DictBuffer dictBuffer,
+ final ArrayList<PendingAttribute> bigrams, final int baseAddress) {
+ int readLength = 0;
+ int bigramCount = 0;
+ while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ final int bigramFlags = dictBuffer.readUnsignedByte();
+ ++readLength;
+ final int sign = 0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE)
+ ? 1 : -1;
+ int bigramAddress = baseAddress + readLength;
+ switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE:
+ bigramAddress += sign * dictBuffer.readUnsignedByte();
+ readLength += 1;
+ break;
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES:
+ bigramAddress += sign * dictBuffer.readUnsignedShort();
+ readLength += 2;
+ break;
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES:
+ bigramAddress += sign * dictBuffer.readUnsignedInt24();
+ readLength += 3;
+ break;
+ default:
+ throw new RuntimeException("Has bigrams with no address");
+ }
+ bigrams.add(new PendingAttribute(
+ bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY,
+ bigramAddress));
+ if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
+ }
+ return readLength;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
new file mode 100644
index 000000000..ea5d492d8
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+
+import java.io.IOException;
+
+/**
+ * An interface of binary dictionary encoder.
+ */
+public interface DictEncoder {
+ public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions)
+ throws IOException, UnsupportedFormatException;
+
+ public void setPosition(final int position);
+ public int getPosition();
+ public void writePtNodeCount(final int ptNodeCount);
+ public void writeForwardLinkAddress(final int forwardLinkAddress);
+
+ public void writePtNode(final PtNode ptNode, final int parentPosition,
+ final FormatOptions formatOptions, final FusionDictionary dict);
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java
new file mode 100644
index 000000000..bf3d19101
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/DynamicBinaryDictIOUtils.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * The utility class to help dynamic updates on the binary dictionary.
+ *
+ * All the methods in this class are static.
+ */
+@UsedForTesting
+public final class DynamicBinaryDictIOUtils {
+ private static final boolean DBG = false;
+ private static final int MAX_JUMPS = 10000;
+
+ private DynamicBinaryDictIOUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ private static int markAsDeleted(final int flags) {
+ return (flags & (~FormatSpec.MASK_CHILDREN_ADDRESS_TYPE)) | FormatSpec.FLAG_IS_DELETED;
+ }
+
+ /**
+ * Delete the word from the binary file.
+ *
+ * @param dictDecoder the dict decoder.
+ * @param word the word we delete
+ * @throws IOException
+ * @throws UnsupportedFormatException
+ */
+ @UsedForTesting
+ public static void deleteWord(final Ver3DictDecoder dictDecoder, final String word)
+ throws IOException, UnsupportedFormatException {
+ final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
+ dictBuffer.position(0);
+ final FileHeader header = dictDecoder.readHeader();
+ final int wordPosition = dictDecoder.getTerminalPosition(word);
+ if (wordPosition == FormatSpec.NOT_VALID_WORD) return;
+
+ dictBuffer.position(wordPosition);
+ final int flags = dictBuffer.readUnsignedByte();
+ dictBuffer.position(wordPosition);
+ dictBuffer.put((byte)markAsDeleted(flags));
+ }
+
+ /**
+ * Update a parent address in a PtNode that is referred to by ptNodeOriginAddress.
+ *
+ * @param dictBuffer the DictBuffer to write.
+ * @param ptNodeOriginAddress the address of the PtNode.
+ * @param newParentAddress the absolute address of the parent.
+ * @param formatOptions file format options.
+ */
+ public static void updateParentAddress(final DictBuffer dictBuffer,
+ final int ptNodeOriginAddress, final int newParentAddress,
+ final FormatOptions formatOptions) {
+ final int originalPosition = dictBuffer.position();
+ dictBuffer.position(ptNodeOriginAddress);
+ if (!formatOptions.mSupportsDynamicUpdate) {
+ throw new RuntimeException("this file format does not support parent addresses");
+ }
+ final int flags = dictBuffer.readUnsignedByte();
+ if (BinaryDictIOUtils.isMovedPtNode(flags, formatOptions)) {
+ // If the node is moved, the parent address is stored in the destination node.
+ // We are guaranteed to process the destination node later, so there is no need to
+ // update anything here.
+ dictBuffer.position(originalPosition);
+ return;
+ }
+ if (DBG) {
+ MakedictLog.d("update parent address flags=" + flags + ", " + ptNodeOriginAddress);
+ }
+ final int parentOffset = newParentAddress - ptNodeOriginAddress;
+ BinaryDictIOUtils.writeSInt24ToBuffer(dictBuffer, parentOffset);
+ dictBuffer.position(originalPosition);
+ }
+
+ /**
+ * Update parent addresses in a node array stored at ptNodeOriginAddress.
+ *
+ * @param dictBuffer the DictBuffer to be modified.
+ * @param ptNodeOriginAddress the address of the node array to update.
+ * @param newParentAddress the address to be written.
+ * @param formatOptions file format options.
+ */
+ public static void updateParentAddresses(final DictBuffer dictBuffer,
+ final int ptNodeOriginAddress, final int newParentAddress,
+ final FormatOptions formatOptions) {
+ final int originalPosition = dictBuffer.position();
+ dictBuffer.position(ptNodeOriginAddress);
+ do {
+ final int count = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
+ for (int i = 0; i < count; ++i) {
+ updateParentAddress(dictBuffer, dictBuffer.position(), newParentAddress,
+ formatOptions);
+ BinaryDictIOUtils.skipPtNode(dictBuffer, formatOptions);
+ }
+ final int forwardLinkAddress = dictBuffer.readUnsignedInt24();
+ dictBuffer.position(forwardLinkAddress);
+ } while (formatOptions.mSupportsDynamicUpdate
+ && dictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
+ dictBuffer.position(originalPosition);
+ }
+
+ /**
+ * Update a children address in a PtNode that is addressed by ptNodeOriginAddress.
+ *
+ * @param dictBuffer the DictBuffer to write.
+ * @param ptNodeOriginAddress the address of the PtNode.
+ * @param newChildrenAddress the absolute address of the child.
+ * @param formatOptions file format options.
+ */
+ public static void updateChildrenAddress(final DictBuffer dictBuffer,
+ final int ptNodeOriginAddress, final int newChildrenAddress,
+ final FormatOptions formatOptions) {
+ final int originalPosition = dictBuffer.position();
+ dictBuffer.position(ptNodeOriginAddress);
+ final int flags = dictBuffer.readUnsignedByte();
+ final int parentAddress = BinaryDictDecoderUtils.readParentAddress(dictBuffer,
+ formatOptions);
+ BinaryDictIOUtils.skipString(dictBuffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
+ if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) dictBuffer.readUnsignedByte();
+ final int childrenOffset = newChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS
+ ? FormatSpec.NO_CHILDREN_ADDRESS : newChildrenAddress - dictBuffer.position();
+ BinaryDictIOUtils.writeSInt24ToBuffer(dictBuffer, childrenOffset);
+ dictBuffer.position(originalPosition);
+ }
+
+ /**
+ * Helper method to move a PtNode to the tail of the file.
+ */
+ private static int movePtNode(final OutputStream destination,
+ final DictBuffer dictBuffer, final PtNodeInfo info,
+ final int nodeArrayOriginAddress, final int oldNodeAddress,
+ final FormatOptions formatOptions) throws IOException {
+ updateParentAddress(dictBuffer, oldNodeAddress, dictBuffer.limit() + 1, formatOptions);
+ dictBuffer.position(oldNodeAddress);
+ final int currentFlags = dictBuffer.readUnsignedByte();
+ dictBuffer.position(oldNodeAddress);
+ dictBuffer.put((byte)(FormatSpec.FLAG_IS_MOVED | (currentFlags
+ & (~FormatSpec.MASK_MOVE_AND_DELETE_FLAG))));
+ int size = FormatSpec.PTNODE_FLAGS_SIZE;
+ updateForwardLink(dictBuffer, nodeArrayOriginAddress, dictBuffer.limit(), formatOptions);
+ size += BinaryDictIOUtils.writeNodes(destination, new PtNodeInfo[] { info });
+ return size;
+ }
+
+ @SuppressWarnings("unused")
+ private static void updateForwardLink(final DictBuffer dictBuffer,
+ final int nodeArrayOriginAddress, final int newNodeArrayAddress,
+ final FormatOptions formatOptions) {
+ dictBuffer.position(nodeArrayOriginAddress);
+ int jumpCount = 0;
+ while (jumpCount++ < MAX_JUMPS) {
+ final int count = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
+ for (int i = 0; i < count; ++i) {
+ BinaryDictIOUtils.skipPtNode(dictBuffer, formatOptions);
+ }
+ final int forwardLinkAddress = dictBuffer.readUnsignedInt24();
+ if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ dictBuffer.position(dictBuffer.position() - FormatSpec.FORWARD_LINK_ADDRESS_SIZE);
+ BinaryDictIOUtils.writeSInt24ToBuffer(dictBuffer, newNodeArrayAddress);
+ return;
+ }
+ dictBuffer.position(forwardLinkAddress);
+ }
+ if (DBG && jumpCount >= MAX_JUMPS) {
+ throw new RuntimeException("too many jumps, probably a bug.");
+ }
+ }
+
+ /**
+ * Move a PtNode that is referred to by oldPtNodeOrigin to the tail of the file, and set the
+ * children address to the byte after the PtNode.
+ *
+ * @param fileEndAddress the address of the tail of the file.
+ * @param codePoints the characters to put inside the PtNode.
+ * @param length how many code points to read from codePoints.
+ * @param flags the flags for this PtNode.
+ * @param frequency the frequency of this terminal.
+ * @param parentAddress the address of the parent PtNode of this PtNode.
+ * @param shortcutTargets the shortcut targets for this PtNode.
+ * @param bigrams the bigrams for this PtNode.
+ * @param destination the stream representing the tail of the file.
+ * @param dictBuffer the DictBuffer representing the (constant-size) body of the file.
+ * @param oldPtNodeArrayOrigin the origin of the old PtNode array this PtNode was a part of.
+ * @param oldPtNodeOrigin the old origin where this PtNode used to be stored.
+ * @param formatOptions format options for this dictionary.
+ * @return the size written, in bytes.
+ * @throws IOException if the file can't be accessed
+ */
+ private static int movePtNode(final int fileEndAddress, final int[] codePoints,
+ final int length, final int flags, final int frequency, final int parentAddress,
+ final ArrayList<WeightedString> shortcutTargets,
+ final ArrayList<PendingAttribute> bigrams, final OutputStream destination,
+ final DictBuffer dictBuffer, final int oldPtNodeArrayOrigin,
+ final int oldPtNodeOrigin, final FormatOptions formatOptions) throws IOException {
+ int size = 0;
+ final int newPtNodeOrigin = fileEndAddress + 1;
+ final int[] writtenCharacters = Arrays.copyOfRange(codePoints, 0, length);
+ final PtNodeInfo tmpInfo = new PtNodeInfo(newPtNodeOrigin, -1 /* endAddress */,
+ flags, writtenCharacters, frequency, parentAddress, FormatSpec.NO_CHILDREN_ADDRESS,
+ shortcutTargets, bigrams);
+ size = BinaryDictIOUtils.computePtNodeSize(tmpInfo, formatOptions);
+ final PtNodeInfo newInfo = new PtNodeInfo(newPtNodeOrigin, newPtNodeOrigin + size,
+ flags, writtenCharacters, frequency, parentAddress,
+ fileEndAddress + 1 + size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE, shortcutTargets,
+ bigrams);
+ movePtNode(destination, dictBuffer, newInfo, oldPtNodeArrayOrigin, oldPtNodeOrigin,
+ formatOptions);
+ return 1 + size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
+ }
+
+ /**
+ * Insert a word into a binary dictionary.
+ *
+ * @param dictDecoder the dict decoder.
+ * @param destination a stream to the underlying file, with the pointer at the end of the file.
+ * @param word the word to insert.
+ * @param frequency the frequency of the new word.
+ * @param bigramStrings bigram list, or null if none.
+ * @param shortcuts shortcut list, or null if none.
+ * @param isBlackListEntry whether this should be a blacklist entry.
+ * @throws IOException if the file can't be accessed.
+ * @throws UnsupportedFormatException if the existing dictionary is in an unexpected format.
+ */
+ // TODO: Support batch insertion.
+ // TODO: Remove @UsedForTesting once UserHistoryDictionary is implemented by BinaryDictionary.
+ @UsedForTesting
+ public static void insertWord(final Ver3DictDecoder dictDecoder,
+ final OutputStream destination, final String word, final int frequency,
+ final ArrayList<WeightedString> bigramStrings,
+ final ArrayList<WeightedString> shortcuts, final boolean isNotAWord,
+ final boolean isBlackListEntry)
+ throws IOException, UnsupportedFormatException {
+ final ArrayList<PendingAttribute> bigrams = new ArrayList<PendingAttribute>();
+ final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
+ if (bigramStrings != null) {
+ for (final WeightedString bigram : bigramStrings) {
+ int position = dictDecoder.getTerminalPosition(bigram.mWord);
+ if (position == FormatSpec.NOT_VALID_WORD) {
+ // TODO: figure out what is the correct thing to do here.
+ } else {
+ bigrams.add(new PendingAttribute(bigram.mFrequency, position));
+ }
+ }
+ }
+
+ final boolean isTerminal = true;
+ final boolean hasBigrams = !bigrams.isEmpty();
+ final boolean hasShortcuts = shortcuts != null && !shortcuts.isEmpty();
+
+ // find the insert position of the word.
+ if (dictBuffer.position() != 0) dictBuffer.position(0);
+ final FileHeader fileHeader = dictDecoder.readHeader();
+
+ int wordPos = 0, address = dictBuffer.position(), nodeOriginAddress = dictBuffer.position();
+ final int[] codePoints = FusionDictionary.getCodePoints(word);
+ final int wordLen = codePoints.length;
+
+ for (int depth = 0; depth < Constants.DICTIONARY_MAX_WORD_LENGTH; ++depth) {
+ if (wordPos >= wordLen) break;
+ nodeOriginAddress = dictBuffer.position();
+ int nodeParentAddress = -1;
+ final int ptNodeCount = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
+ boolean foundNextNode = false;
+
+ for (int i = 0; i < ptNodeCount; ++i) {
+ address = dictBuffer.position();
+ final PtNodeInfo currentInfo = dictDecoder.readPtNode(address,
+ fileHeader.mFormatOptions);
+ final boolean isMovedNode = BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags,
+ fileHeader.mFormatOptions);
+ if (isMovedNode) continue;
+ nodeParentAddress = (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS)
+ ? FormatSpec.NO_PARENT_ADDRESS : currentInfo.mParentAddress + address;
+ boolean matched = true;
+ for (int p = 0; p < currentInfo.mCharacters.length; ++p) {
+ if (wordPos + p >= wordLen) {
+ /*
+ * splitting
+ * before
+ * abcd - ef
+ *
+ * insert "abc"
+ *
+ * after
+ * abc - d - ef
+ */
+ final int newNodeAddress = dictBuffer.limit();
+ final int flags = BinaryDictEncoderUtils.makePtNodeFlags(p > 1,
+ isTerminal, 0, hasShortcuts, hasBigrams, false /* isNotAWord */,
+ false /* isBlackListEntry */, fileHeader.mFormatOptions);
+ int written = movePtNode(newNodeAddress, currentInfo.mCharacters, p, flags,
+ frequency, nodeParentAddress, shortcuts, bigrams, destination,
+ dictBuffer, nodeOriginAddress, address, fileHeader.mFormatOptions);
+
+ final int[] characters2 = Arrays.copyOfRange(currentInfo.mCharacters, p,
+ currentInfo.mCharacters.length);
+ if (currentInfo.mChildrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ updateParentAddresses(dictBuffer, currentInfo.mChildrenAddress,
+ newNodeAddress + written + 1, fileHeader.mFormatOptions);
+ }
+ final PtNodeInfo newInfo2 = new PtNodeInfo(
+ newNodeAddress + written + 1, -1 /* endAddress */,
+ currentInfo.mFlags, characters2, currentInfo.mFrequency,
+ newNodeAddress + 1, currentInfo.mChildrenAddress,
+ currentInfo.mShortcutTargets, currentInfo.mBigrams);
+ BinaryDictIOUtils.writeNodes(destination, new PtNodeInfo[] { newInfo2 });
+ return;
+ } else if (codePoints[wordPos + p] != currentInfo.mCharacters[p]) {
+ if (p > 0) {
+ /*
+ * splitting
+ * before
+ * ab - cd
+ *
+ * insert "ac"
+ *
+ * after
+ * a - b - cd
+ * |
+ * - c
+ */
+
+ final int newNodeAddress = dictBuffer.limit();
+ final int childrenAddress = currentInfo.mChildrenAddress;
+
+ // move prefix
+ final int prefixFlags = BinaryDictEncoderUtils.makePtNodeFlags(p > 1,
+ false /* isTerminal */, 0 /* childrenAddressSize*/,
+ false /* hasShortcut */, false /* hasBigrams */,
+ false /* isNotAWord */, false /* isBlackListEntry */,
+ fileHeader.mFormatOptions);
+ int written = movePtNode(newNodeAddress, currentInfo.mCharacters, p,
+ prefixFlags, -1 /* frequency */, nodeParentAddress, null, null,
+ destination, dictBuffer, nodeOriginAddress, address,
+ fileHeader.mFormatOptions);
+
+ final int[] suffixCharacters = Arrays.copyOfRange(
+ currentInfo.mCharacters, p, currentInfo.mCharacters.length);
+ if (currentInfo.mChildrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ updateParentAddresses(dictBuffer, currentInfo.mChildrenAddress,
+ newNodeAddress + written + 1, fileHeader.mFormatOptions);
+ }
+ final int suffixFlags = BinaryDictEncoderUtils.makePtNodeFlags(
+ suffixCharacters.length > 1,
+ (currentInfo.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0,
+ 0 /* childrenAddressSize */,
+ (currentInfo.mFlags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)
+ != 0,
+ (currentInfo.mFlags & FormatSpec.FLAG_HAS_BIGRAMS) != 0,
+ isNotAWord, isBlackListEntry, fileHeader.mFormatOptions);
+ final PtNodeInfo suffixInfo = new PtNodeInfo(
+ newNodeAddress + written + 1, -1 /* endAddress */, suffixFlags,
+ suffixCharacters, currentInfo.mFrequency, newNodeAddress + 1,
+ currentInfo.mChildrenAddress, currentInfo.mShortcutTargets,
+ currentInfo.mBigrams);
+ written += BinaryDictIOUtils.computePtNodeSize(suffixInfo,
+ fileHeader.mFormatOptions) + 1;
+
+ final int[] newCharacters = Arrays.copyOfRange(codePoints, wordPos + p,
+ codePoints.length);
+ final int flags = BinaryDictEncoderUtils.makePtNodeFlags(
+ newCharacters.length > 1, isTerminal,
+ 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, fileHeader.mFormatOptions);
+ final PtNodeInfo newInfo = new PtNodeInfo(
+ newNodeAddress + written, -1 /* endAddress */, flags,
+ newCharacters, frequency, newNodeAddress + 1,
+ FormatSpec.NO_CHILDREN_ADDRESS, shortcuts, bigrams);
+ BinaryDictIOUtils.writeNodes(destination,
+ new PtNodeInfo[] { suffixInfo, newInfo });
+ return;
+ }
+ matched = false;
+ break;
+ }
+ }
+
+ if (matched) {
+ if (wordPos + currentInfo.mCharacters.length == wordLen) {
+ // the word exists in the dictionary.
+ // only update the PtNode.
+ final int newNodeAddress = dictBuffer.limit();
+ final boolean hasMultipleChars = currentInfo.mCharacters.length > 1;
+ final int flags = BinaryDictEncoderUtils.makePtNodeFlags(hasMultipleChars,
+ isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, fileHeader.mFormatOptions);
+ final PtNodeInfo newInfo = new PtNodeInfo(newNodeAddress + 1,
+ -1 /* endAddress */, flags, currentInfo.mCharacters, frequency,
+ nodeParentAddress, currentInfo.mChildrenAddress, shortcuts,
+ bigrams);
+ movePtNode(destination, dictBuffer, newInfo, nodeOriginAddress, address,
+ fileHeader.mFormatOptions);
+ return;
+ }
+ wordPos += currentInfo.mCharacters.length;
+ if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
+ /*
+ * found the prefix of the word.
+ * make new PtNode and link to the PtNode from this PtNode.
+ *
+ * before
+ * ab - cd
+ *
+ * insert "abcde"
+ *
+ * after
+ * ab - cd - e
+ */
+ final int newNodeArrayAddress = dictBuffer.limit();
+ updateChildrenAddress(dictBuffer, address, newNodeArrayAddress,
+ fileHeader.mFormatOptions);
+ final int newNodeAddress = newNodeArrayAddress + 1;
+ final boolean hasMultipleChars = (wordLen - wordPos) > 1;
+ final int flags = BinaryDictEncoderUtils.makePtNodeFlags(hasMultipleChars,
+ isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, fileHeader.mFormatOptions);
+ final int[] characters = Arrays.copyOfRange(codePoints, wordPos, wordLen);
+ final PtNodeInfo newInfo = new PtNodeInfo(newNodeAddress, -1, flags,
+ characters, frequency, address, FormatSpec.NO_CHILDREN_ADDRESS,
+ shortcuts, bigrams);
+ BinaryDictIOUtils.writeNodes(destination, new PtNodeInfo[] { newInfo });
+ return;
+ }
+ dictBuffer.position(currentInfo.mChildrenAddress);
+ foundNextNode = true;
+ break;
+ }
+ }
+
+ if (foundNextNode) continue;
+
+ // reached the end of the array.
+ final int linkAddressPosition = dictBuffer.position();
+ int nextLink = dictBuffer.readUnsignedInt24();
+ if ((nextLink & FormatSpec.MSB24) != 0) {
+ nextLink = -(nextLink & FormatSpec.SINT24_MAX);
+ }
+ if (nextLink == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ /*
+ * expand this node.
+ *
+ * before
+ * ab - cd
+ *
+ * insert "abef"
+ *
+ * after
+ * ab - cd
+ * |
+ * - ef
+ */
+
+ // change the forward link address.
+ final int newNodeAddress = dictBuffer.limit();
+ dictBuffer.position(linkAddressPosition);
+ BinaryDictIOUtils.writeSInt24ToBuffer(dictBuffer, newNodeAddress);
+
+ final int[] characters = Arrays.copyOfRange(codePoints, wordPos, wordLen);
+ final int flags = BinaryDictEncoderUtils.makePtNodeFlags(characters.length > 1,
+ isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, fileHeader.mFormatOptions);
+ final PtNodeInfo newInfo = new PtNodeInfo(newNodeAddress + 1,
+ -1 /* endAddress */, flags, characters, frequency, nodeParentAddress,
+ FormatSpec.NO_CHILDREN_ADDRESS, shortcuts, bigrams);
+ BinaryDictIOUtils.writeNodes(destination, new PtNodeInfo[]{ newInfo });
+ return;
+ } else {
+ depth--;
+ dictBuffer.position(nextLink);
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 46266aa50..51b89a02a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -18,29 +18,66 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory;
import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import java.io.File;
+
/**
* Dictionary File Format Specification.
*/
public final class FormatSpec {
/*
- * Array of Node(FusionDictionary.Node) layout is as follows:
+ * File header layout is as follows:
+ *
+ * v |
+ * e | MAGIC_NUMBER + version of the file format, 2 bytes.
+ * r |
+ * sion
+ *
+ * o |
+ * p | not used 4 bits
+ * t | has bigrams ? 1 bit, 1 = yes, 0 = no : CONTAINS_BIGRAMS_FLAG
+ * i | FRENCH_LIGATURE_PROCESSING_FLAG
+ * o | supports dynamic updates ? 1 bit, 1 = yes, 0 = no : SUPPORTS_DYNAMIC_UPDATE
+ * n | GERMAN_UMLAUT_PROCESSING_FLAG
+ * f |
+ * lags
+ *
+ * h |
+ * e | size of the file header, 4bytes
+ * a | including the size of the magic number, the option flags and the header size
+ * d |
+ * ersize
+ *
+ * | attributes list
+ *
+ * attributes list is:
+ * <key> = | string of characters at the char format described below, with the terminator used
+ * | to signal the end of the string.
+ * <value> = | string of characters at the char format described below, with the terminator used
+ * | to signal the end of the string.
+ * if the size of already read < headersize, goto key.
+ *
+ */
+
+ /*
+ * Node array (FusionDictionary.PtNodeArray) layout is as follows:
*
- * g |
- * r | the number of groups, 1 or 2 bytes.
- * o | 1 byte = bbbbbbbb match
- * u | case 1xxxxxxx => xxxxxxx << 8 + next byte
- * p | otherwise => bbbbbbbb
- * c |
- * ount
+ * n |
+ * o | the number of PtNodes, 1 or 2 bytes.
+ * d | 1 byte = bbbbbbbb match
+ * e | case 1xxxxxxx => xxxxxxx << 8 + next byte
+ * c | otherwise => bbbbbbbb
+ * o |
+ * unt
*
- * g |
- * r | sequence of groups,
- * o | the layout of each group is described below.
- * u |
- * ps
+ * n |
+ * o | sequence of PtNodes,
+ * d | the layout of each PtNode is described below.
+ * e |
+ * s
*
* f |
* o | IF SUPPORTS_DYNAMIC_UPDATE (defined in the file header)
@@ -52,19 +89,19 @@ public final class FormatSpec {
* linkaddress
*/
- /* Node(CharGroup) layout is as follows:
+ /* Node (FusionDictionary.PtNode) layout is as follows:
* | IF !SUPPORTS_DYNAMIC_UPDATE
- * | addressType xx : mask with MASK_GROUP_ADDRESS_TYPE
- * | 2 bits, 00 = no children : FLAG_GROUP_ADDRESS_TYPE_NOADDRESS
- * f | 01 = 1 byte : FLAG_GROUP_ADDRESS_TYPE_ONEBYTE
- * l | 10 = 2 bytes : FLAG_GROUP_ADDRESS_TYPE_TWOBYTES
- * a | 11 = 3 bytes : FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
+ * | addressType xx : mask with MASK_CHILDREN_ADDRESS_TYPE
+ * | 2 bits, 00 = no children : FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS
+ * f | 01 = 1 byte : FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE
+ * l | 10 = 2 bytes : FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES
+ * a | 11 = 3 bytes : FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES
* g | ELSE
- * s | is moved ? 2 bits, 11 = no : FLAG_IS_NOT_MOVED
- * | This must be the same as FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
- * | 01 = yes : FLAG_IS_MOVED
+ * s | is moved ? 2 bits, 11 = no : FLAG_IS_NOT_MOVED
+ * | This must be the same as FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES
+ * | 01 = yes : FLAG_IS_MOVED
* | the new address is stored in the same place as the parent address
- * | is deleted? 10 = yes : FLAG_IS_DELETED
+ * | is deleted? 10 = yes : FLAG_IS_DELETED
* | has several chars ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_MULTIPLE_CHARS
* | has a terminal ? 1 bit, 1 = yes, 0 = no : FLAG_IS_TERMINAL
* | has shortcut targets ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_SHORTCUT_TARGETS
@@ -78,11 +115,13 @@ public final class FormatSpec {
* e | 1 byte = bbbbbbbb match
* n | case 1xxxxxxx => -((0xxxxxxx << 16) + (next byte << 8) + next byte)
* t | otherwise => (bbbbbbbb << 16) + (next byte << 8) + next byte
- * a |
- * ddress
+ * a | This address is relative to the head of the PtNode.
+ * d | If the node doesn't have a parent, this field is set to 0.
+ * d |
+ * ress
*
* c | IF FLAG_HAS_MULTIPLE_CHARS
- * h | char, char, char, char n * (1 or 3 bytes) : use CharGroupInfo for i/o helpers
+ * h | char, char, char, char n * (1 or 3 bytes) : use PtNodeInfo for i/o helpers
* a | end 1 byte, = 0
* r | ELSE
* s | char 1 or 3 bytes
@@ -93,17 +132,23 @@ public final class FormatSpec {
* e | frequency 1 byte
* q |
*
- * c | IF 00 = FLAG_GROUP_ADDRESS_TYPE_NOADDRESS = addressType
- * h | // nothing
- * i | ELSIF 01 = FLAG_GROUP_ADDRESS_TYPE_ONEBYTE == addressType
- * l | children address, 1 byte
- * d | ELSIF 10 = FLAG_GROUP_ADDRESS_TYPE_TWOBYTES == addressType
- * r | children address, 2 bytes
- * e | ELSE // 11 = FLAG_GROUP_ADDRESS_TYPE_THREEBYTES = addressType
- * n | children address, 3 bytes
- * A | END
- * d
- * dress
+ * c | IF SUPPORTS_DYNAMIC_UPDATE
+ * h | children address, 3 bytes
+ * i | 1 byte = bbbbbbbb match
+ * l | case 1xxxxxxx => -((0xxxxxxx << 16) + (next byte << 8) + next byte)
+ * d | otherwise => (bbbbbbbb<<16) + (next byte << 8) + next byte
+ * r | if this node doesn't have children, this field is set to 0.
+ * e | (see BinaryDictEncoderUtils#writeVariableSignedAddress)
+ * n | ELSIF 00 = FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS == addressType
+ * a | // nothing
+ * d | ELSIF 01 = FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE == addressType
+ * d | children address, 1 byte
+ * r | ELSIF 10 = FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES == addressType
+ * e | children address, 2 bytes
+ * s | ELSE // 11 = FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES = addressType
+ * s | children address, 3 bytes
+ * | END
+ * | This address is relative to the position of this field.
*
* | IF FLAG_IS_TERMINAL && FLAG_HAS_SHORTCUT_TARGETS
* | shortcut string list
@@ -122,42 +167,43 @@ public final class FormatSpec {
* characters which should never happen anyway (and still work, but take 3 bytes).
*
* bigram address list is:
- * <flags> = | hasNext = 1 bit, 1 = yes, 0 = no : FLAG_ATTRIBUTE_HAS_NEXT
- * | addressSign = 1 bit, : FLAG_ATTRIBUTE_OFFSET_NEGATIVE
+ * <flags> = | hasNext = 1 bit, 1 = yes, 0 = no : FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT
+ * | addressSign = 1 bit, : FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE
* | 1 = must take -address, 0 = must take +address
- * | xx : mask with MASK_ATTRIBUTE_ADDRESS_TYPE
- * | addressFormat = 2 bits, 00 = unused : FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE
- * | 01 = 1 byte : FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE
- * | 10 = 2 bytes : FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES
- * | 11 = 3 bytes : FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES
- * | 4 bits : frequency : mask with FLAG_ATTRIBUTE_FREQUENCY
- * <address> | IF (01 == FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE == addressFormat)
+ * | xx : mask with MASK_BIGRAM_ATTR_ADDRESS_TYPE
+ * | addressFormat = 2 bits, 00 = unused : FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE
+ * | 01 = 1 byte : FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE
+ * | 10 = 2 bytes : FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES
+ * | 11 = 3 bytes : FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES
+ * | 4 bits : frequency : mask with FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY
+ * <address> | IF (01 == FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE == addressFormat)
* | read 1 byte, add top 4 bits
- * | ELSIF (10 == FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES == addressFormat)
+ * | ELSIF (10 == FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES == addressFormat)
* | read 2 bytes, add top 4 bits
- * | ELSE // 11 == FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES == addressFormat
+ * | ELSE // 11 == FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES == addressFormat
* | read 3 bytes, add top 4 bits
* | END
- * | if (FLAG_ATTRIBUTE_OFFSET_NEGATIVE) then address = -address
- * if (FLAG_ATTRIBUTE_HAS_NEXT) goto bigram_and_shortcut_address_list_is
+ * | if (FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE) then address = -address
+ * if (FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT) goto bigram_and_shortcut_address_list_is
*
* shortcut string list is:
- * <byte size> = GROUP_SHORTCUT_LIST_SIZE_SIZE bytes, big-endian: size of the list, in bytes.
- * <flags> = | hasNext = 1 bit, 1 = yes, 0 = no : FLAG_ATTRIBUTE_HAS_NEXT
+ * <byte size> = PTNODE_SHORTCUT_LIST_SIZE_SIZE bytes, big-endian: size of the list, in bytes.
+ * <flags> = | hasNext = 1 bit, 1 = yes, 0 = no : FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT
* | reserved = 3 bits, must be 0
- * | 4 bits : frequency : mask with FLAG_ATTRIBUTE_FREQUENCY
+ * | 4 bits : frequency : mask with FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY
* <shortcut> = | string of characters at the char format described above, with the terminator
* | used to signal the end of the string.
- * if (FLAG_ATTRIBUTE_HAS_NEXT goto flags
+ * if (FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT goto flags
*/
- static final int VERSION_1_MAGIC_NUMBER = 0x78B1;
- public static final int VERSION_2_MAGIC_NUMBER = 0x9BC13AFE;
- static final int MINIMUM_SUPPORTED_VERSION = 1;
- static final int MAXIMUM_SUPPORTED_VERSION = 3;
+ public static final int MAGIC_NUMBER = 0x9BC13AFE;
+ static final int MINIMUM_SUPPORTED_VERSION = 2;
+ static final int MAXIMUM_SUPPORTED_VERSION = 4;
static final int NOT_A_VERSION_NUMBER = -1;
- static final int FIRST_VERSION_WITH_HEADER_SIZE = 2;
static final int FIRST_VERSION_WITH_DYNAMIC_UPDATE = 3;
+ static final int FIRST_VERSION_WITH_TERMINAL_ID = 4;
+ static final int VERSION3 = 3;
+ static final int VERSION4 = 4;
// These options need to be the same numeric values as the one in the native reading code.
static final int GERMAN_UMLAUT_PROCESSING_FLAG = 0x1;
@@ -174,11 +220,11 @@ public final class FormatSpec {
static final int FORWARD_LINK_ADDRESS_SIZE = 3;
// These flags are used only in the static dictionary.
- static final int MASK_GROUP_ADDRESS_TYPE = 0xC0;
- static final int FLAG_GROUP_ADDRESS_TYPE_NOADDRESS = 0x00;
- static final int FLAG_GROUP_ADDRESS_TYPE_ONEBYTE = 0x40;
- static final int FLAG_GROUP_ADDRESS_TYPE_TWOBYTES = 0x80;
- static final int FLAG_GROUP_ADDRESS_TYPE_THREEBYTES = 0xC0;
+ static final int MASK_CHILDREN_ADDRESS_TYPE = 0xC0;
+ static final int FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS = 0x00;
+ static final int FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE = 0x40;
+ static final int FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES = 0x80;
+ static final int FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES = 0xC0;
static final int FLAG_HAS_MULTIPLE_CHARS = 0x20;
@@ -195,32 +241,39 @@ public final class FormatSpec {
static final int FLAG_IS_NOT_MOVED = 0x80 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
static final int FLAG_IS_DELETED = 0x80;
- static final int FLAG_ATTRIBUTE_HAS_NEXT = 0x80;
- static final int FLAG_ATTRIBUTE_OFFSET_NEGATIVE = 0x40;
- static final int MASK_ATTRIBUTE_ADDRESS_TYPE = 0x30;
- static final int FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE = 0x10;
- static final int FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES = 0x20;
- static final int FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES = 0x30;
- static final int FLAG_ATTRIBUTE_FREQUENCY = 0x0F;
+ static final int FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT = 0x80;
+ static final int FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE = 0x40;
+ static final int MASK_BIGRAM_ATTR_ADDRESS_TYPE = 0x30;
+ static final int FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE = 0x10;
+ static final int FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES = 0x20;
+ static final int FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES = 0x30;
+ static final int FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY = 0x0F;
- static final int GROUP_CHARACTERS_TERMINATOR = 0x1F;
+ static final int PTNODE_CHARACTERS_TERMINATOR = 0x1F;
- static final int GROUP_TERMINATOR_SIZE = 1;
- static final int GROUP_FLAGS_SIZE = 1;
- static final int GROUP_FREQUENCY_SIZE = 1;
- static final int GROUP_MAX_ADDRESS_SIZE = 3;
- static final int GROUP_ATTRIBUTE_FLAGS_SIZE = 1;
- static final int GROUP_ATTRIBUTE_MAX_ADDRESS_SIZE = 3;
- static final int GROUP_SHORTCUT_LIST_SIZE_SIZE = 2;
+ static final int PTNODE_TERMINATOR_SIZE = 1;
+ static final int PTNODE_FLAGS_SIZE = 1;
+ static final int PTNODE_FREQUENCY_SIZE = 1;
+ static final int PTNODE_TERMINAL_ID_SIZE = 4;
+ static final int PTNODE_MAX_ADDRESS_SIZE = 3;
+ static final int PTNODE_ATTRIBUTE_FLAGS_SIZE = 1;
+ static final int PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE = 3;
+ static final int PTNODE_SHORTCUT_LIST_SIZE_SIZE = 2;
+
+ // These values are used only by version 4 or later.
+ static final String TRIE_FILE_EXTENSION = ".trie";
+ static final String FREQ_FILE_EXTENSION = ".freq";
+ static final int FREQUENCY_AND_FLAGS_SIZE = 2;
static final int NO_CHILDREN_ADDRESS = Integer.MIN_VALUE;
static final int NO_PARENT_ADDRESS = 0;
static final int NO_FORWARD_LINK_ADDRESS = 0;
static final int INVALID_CHARACTER = -1;
- static final int MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT = 0x7F; // 127
- static final int MAX_CHARGROUPS_IN_A_NODE = 0x7FFF; // 32767
- static final int MAX_BIGRAMS_IN_A_GROUP = 10000;
+ static final int MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT = 0x7F; // 127
+ static final int MAX_PTNODES_IN_A_PT_NODE_ARRAY = 0x7FFF; // 32767
+ static final int MAX_BIGRAMS_IN_A_PTNODE = 10000;
+ static final int MAX_SHORTCUT_LIST_SIZE_IN_A_PTNODE = 0xFFFF;
static final int MAX_TERMINAL_FREQUENCY = 255;
static final int MAX_BIGRAM_FREQUENCY = 15;
@@ -231,12 +284,20 @@ public final class FormatSpec {
static final int NOT_VALID_WORD = -99;
static final int SIGNED_CHILDREN_ADDRESS_SIZE = 3;
+ static final int UINT8_MAX = 0xFF;
+ static final int UINT16_MAX = 0xFFFF;
+ static final int UINT24_MAX = 0xFFFFFF;
+ static final int SINT24_MAX = 0x7FFFFF;
+ static final int MSB8 = 0x80;
+ static final int MSB24 = 0x800000;
+
/**
* Options about file format.
*/
public static final class FormatOptions {
public final int mVersion;
public final boolean mSupportsDynamicUpdate;
+ public final boolean mHasTerminalId;
@UsedForTesting
public FormatOptions(final int version) {
this(version, false);
@@ -250,6 +311,7 @@ public final class FormatSpec {
+ FIRST_VERSION_WITH_DYNAMIC_UPDATE + " and ulterior.");
}
mSupportsDynamicUpdate = supportsDynamicUpdate;
+ mHasTerminalId = (version >= FIRST_VERSION_WITH_TERMINAL_ID);
}
}
@@ -294,6 +356,36 @@ public final class FormatSpec {
}
}
+ /**
+ * Returns new dictionary decoder.
+ *
+ * @param dictFile the dictionary file.
+ * @param bufferType The type of buffer, as one of USE_* in DictDecoder.
+ * @return new dictionary decoder if the dictionary file exists, otherwise null.
+ */
+ public static DictDecoder getDictDecoder(final File dictFile, final int bufferType) {
+ if (dictFile.isDirectory()) {
+ return new Ver4DictDecoder(dictFile, bufferType);
+ } else if (dictFile.isFile()) {
+ return new Ver3DictDecoder(dictFile, bufferType);
+ }
+ return null;
+ }
+
+ public static DictDecoder getDictDecoder(final File dictFile,
+ final DictionaryBufferFactory factory) {
+ if (dictFile.isDirectory()) {
+ return new Ver4DictDecoder(dictFile, factory);
+ } else if (dictFile.isFile()) {
+ return new Ver3DictDecoder(dictFile, factory);
+ }
+ return null;
+ }
+
+ public static DictDecoder getDictDecoder(final File dictFile) {
+ return getDictDecoder(dictFile, DictDecoder.USE_READONLY_BYTEBUFFER);
+ }
+
private FormatSpec() {
// This utility class is not publicly instantiable.
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 118dc22b8..be653feec 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -37,15 +37,15 @@ public final class FusionDictionary implements Iterable<Word> {
private static int CHARACTER_NOT_FOUND_INDEX = -1;
/**
- * A node of the dictionary, containing several CharGroups.
+ * A node array of the dictionary, containing several PtNodes.
*
- * A node is but an ordered array of CharGroups, which essentially contain all the
+ * A PtNodeArray is but an ordered array of PtNodes, which essentially contain all the
* real information.
* This class also contains fields to cache size and address, to help with binary
* generation.
*/
- public static final class Node {
- ArrayList<CharGroup> mData;
+ public static final class PtNodeArray {
+ ArrayList<PtNode> mData;
// To help with binary generation
int mCachedSize = Integer.MIN_VALUE;
// mCachedAddressBefore/AfterUpdate are helpers for binary dictionary generation. They
@@ -57,10 +57,10 @@ public final class FusionDictionary implements Iterable<Word> {
int mCachedAddressAfterUpdate = Integer.MIN_VALUE;
int mCachedParentAddress = 0;
- public Node() {
- mData = new ArrayList<CharGroup>();
+ public PtNodeArray() {
+ mData = new ArrayList<PtNode>();
}
- public Node(ArrayList<CharGroup> data) {
+ public PtNodeArray(ArrayList<PtNode> data) {
mData = data;
}
}
@@ -93,24 +93,26 @@ public final class FusionDictionary implements Iterable<Word> {
}
/**
- * A group of characters, with a frequency, shortcut targets, bigrams, and children.
+ * PtNode is a group of characters, with a frequency, shortcut targets, bigrams, and children
+ * (Pt means Patricia Trie).
*
- * This is the central class of the in-memory representation. A CharGroup is what can
+ * This is the central class of the in-memory representation. A PtNode is what can
* be seen as a traditional "trie node", except it can hold several characters at the
- * same time. A CharGroup essentially represents one or several characters in the middle
- * of the trie trie; as such, it can be a terminal, and it can have children.
- * In this in-memory representation, whether the CharGroup is a terminal or not is represented
+ * same time. A PtNode essentially represents one or several characters in the middle
+ * of the trie tree; as such, it can be a terminal, and it can have children.
+ * In this in-memory representation, whether the PtNode is a terminal or not is represented
* in the frequency, where NOT_A_TERMINAL (= -1) means this is not a terminal and any other
* value is the frequency of this terminal. A terminal may have non-null shortcuts and/or
* bigrams, but a non-terminal may not. Moreover, children, if present, are null.
*/
- public static final class CharGroup {
+ public static final class PtNode {
public static final int NOT_A_TERMINAL = -1;
final int mChars[];
ArrayList<WeightedString> mShortcutTargets;
ArrayList<WeightedString> mBigrams;
int mFrequency; // NOT_A_TERMINAL == mFrequency indicates this is not a terminal.
- Node mChildren;
+ int mTerminalId; // NOT_A_TERMINAL == mTerminalId indicates this is not a terminal.
+ PtNodeArray mChildren;
boolean mIsNotAWord; // Only a shortcut
boolean mIsBlacklistEntry;
// mCachedSize and mCachedAddressBefore/AfterUpdate are helpers for binary dictionary
@@ -119,15 +121,16 @@ public final class FusionDictionary implements Iterable<Word> {
// same time. Updating will update the AfterUpdate value, and the code will move them
// to BeforeUpdate before the next update pass.
// The update process does not need two versions of mCachedSize.
- int mCachedSize; // The size, in bytes, of this char group.
- int mCachedAddressBeforeUpdate; // The address of this char group (before update)
- int mCachedAddressAfterUpdate; // The address of this char group (after update)
+ int mCachedSize; // The size, in bytes, of this PtNode.
+ int mCachedAddressBeforeUpdate; // The address of this PtNode (before update)
+ int mCachedAddressAfterUpdate; // The address of this PtNode (after update)
- public CharGroup(final int[] chars, final ArrayList<WeightedString> shortcutTargets,
+ public PtNode(final int[] chars, final ArrayList<WeightedString> shortcutTargets,
final ArrayList<WeightedString> bigrams, final int frequency,
final boolean isNotAWord, final boolean isBlacklistEntry) {
mChars = chars;
mFrequency = frequency;
+ mTerminalId = frequency;
mShortcutTargets = shortcutTargets;
mBigrams = bigrams;
mChildren = null;
@@ -135,9 +138,10 @@ public final class FusionDictionary implements Iterable<Word> {
mIsBlacklistEntry = isBlacklistEntry;
}
- public CharGroup(final int[] chars, final ArrayList<WeightedString> shortcutTargets,
+ public PtNode(final int[] chars, final ArrayList<WeightedString> shortcutTargets,
final ArrayList<WeightedString> bigrams, final int frequency,
- final boolean isNotAWord, final boolean isBlacklistEntry, final Node children) {
+ final boolean isNotAWord, final boolean isBlacklistEntry,
+ final PtNodeArray children) {
mChars = chars;
mFrequency = frequency;
mShortcutTargets = shortcutTargets;
@@ -147,13 +151,17 @@ public final class FusionDictionary implements Iterable<Word> {
mIsBlacklistEntry = isBlacklistEntry;
}
- public void addChild(CharGroup n) {
+ public void addChild(PtNode n) {
if (null == mChildren) {
- mChildren = new Node();
+ mChildren = new PtNodeArray();
}
mChildren.mData.add(n);
}
+ public int getTerminalId() {
+ return mTerminalId;
+ }
+
public boolean isTerminal() {
return NOT_A_TERMINAL != mFrequency;
}
@@ -244,7 +252,7 @@ public final class FusionDictionary implements Iterable<Word> {
}
/**
- * Updates the CharGroup with the given properties. Adds the shortcut and bigram lists to
+ * Updates the PtNode with the given properties. Adds the shortcut and bigram lists to
* the existing ones if any. Note: unigram, bigram, and shortcut frequencies are only
* updated if they are higher than the existing ones.
*/
@@ -344,10 +352,10 @@ public final class FusionDictionary implements Iterable<Word> {
}
public final DictionaryOptions mOptions;
- public final Node mRoot;
+ public final PtNodeArray mRootNodeArray;
- public FusionDictionary(final Node root, final DictionaryOptions options) {
- mRoot = root;
+ public FusionDictionary(final PtNodeArray rootNodeArray, final DictionaryOptions options) {
+ mRootNodeArray = rootNodeArray;
mOptions = options;
}
@@ -406,13 +414,13 @@ public final class FusionDictionary implements Iterable<Word> {
}
/**
- * Sanity check for a node.
+ * Sanity check for a PtNode array.
*
- * This method checks that all CharGroups in a node are ordered as expected.
+ * This method checks that all PtNodes in a node array are ordered as expected.
* If they are, nothing happens. If they aren't, an exception is thrown.
*/
- private void checkStack(Node node) {
- ArrayList<CharGroup> stack = node.mData;
+ private void checkStack(PtNodeArray ptNodeArray) {
+ ArrayList<PtNode> stack = ptNodeArray.mData;
int lastValue = -1;
for (int i = 0; i < stack.size(); ++i) {
int currentValue = stack.get(i).mChars[0];
@@ -431,18 +439,18 @@ public final class FusionDictionary implements Iterable<Word> {
* @param frequency the bigram frequency
*/
public void setBigram(final String word1, final String word2, final int frequency) {
- CharGroup charGroup = findWordInTree(mRoot, word1);
- if (charGroup != null) {
- final CharGroup charGroup2 = findWordInTree(mRoot, word2);
- if (charGroup2 == null) {
+ PtNode ptNode = findWordInTree(mRootNodeArray, word1);
+ if (ptNode != null) {
+ final PtNode ptNode2 = findWordInTree(mRootNodeArray, word2);
+ if (ptNode2 == null) {
add(getCodePoints(word2), 0, null, false /* isNotAWord */,
false /* isBlacklistEntry */);
- // The chargroup for the first word may have moved by the above insertion,
+ // The PtNode for the first word may have moved by the above insertion,
// if word1 and word2 share a common stem that happens not to have been
- // a cutting point until now. In this case, we need to refresh charGroup.
- charGroup = findWordInTree(mRoot, word1);
+ // a cutting point until now. In this case, we need to refresh ptNode.
+ ptNode = findWordInTree(mRootNodeArray, word1);
}
- charGroup.addBigram(word2, frequency);
+ ptNode.addBigram(word2, frequency);
} else {
throw new RuntimeException("First word of bigram not found");
}
@@ -469,92 +477,91 @@ public final class FusionDictionary implements Iterable<Word> {
return;
}
- Node currentNode = mRoot;
+ PtNodeArray currentNodeArray = mRootNodeArray;
int charIndex = 0;
- CharGroup currentGroup = null;
+ PtNode currentPtNode = null;
int differentCharIndex = 0; // Set by the loop to the index of the char that differs
- int nodeIndex = findIndexOfChar(mRoot, word[charIndex]);
+ int nodeIndex = findIndexOfChar(mRootNodeArray, word[charIndex]);
while (CHARACTER_NOT_FOUND_INDEX != nodeIndex) {
- currentGroup = currentNode.mData.get(nodeIndex);
- differentCharIndex = compareArrays(currentGroup.mChars, word, charIndex);
+ currentPtNode = currentNodeArray.mData.get(nodeIndex);
+ differentCharIndex = compareCharArrays(currentPtNode.mChars, word, charIndex);
if (ARRAYS_ARE_EQUAL != differentCharIndex
- && differentCharIndex < currentGroup.mChars.length) break;
- if (null == currentGroup.mChildren) break;
- charIndex += currentGroup.mChars.length;
+ && differentCharIndex < currentPtNode.mChars.length) break;
+ if (null == currentPtNode.mChildren) break;
+ charIndex += currentPtNode.mChars.length;
if (charIndex >= word.length) break;
- currentNode = currentGroup.mChildren;
- nodeIndex = findIndexOfChar(currentNode, word[charIndex]);
+ currentNodeArray = currentPtNode.mChildren;
+ nodeIndex = findIndexOfChar(currentNodeArray, word[charIndex]);
}
if (CHARACTER_NOT_FOUND_INDEX == nodeIndex) {
// No node at this point to accept the word. Create one.
- final int insertionIndex = findInsertionIndex(currentNode, word[charIndex]);
- final CharGroup newGroup = new CharGroup(
- Arrays.copyOfRange(word, charIndex, word.length),
+ final int insertionIndex = findInsertionIndex(currentNodeArray, word[charIndex]);
+ final PtNode newPtNode = new PtNode(Arrays.copyOfRange(word, charIndex, word.length),
shortcutTargets, null /* bigrams */, frequency, isNotAWord, isBlacklistEntry);
- currentNode.mData.add(insertionIndex, newGroup);
- if (DBG) checkStack(currentNode);
+ currentNodeArray.mData.add(insertionIndex, newPtNode);
+ if (DBG) checkStack(currentNodeArray);
} else {
// There is a word with a common prefix.
- if (differentCharIndex == currentGroup.mChars.length) {
+ if (differentCharIndex == currentPtNode.mChars.length) {
if (charIndex + differentCharIndex >= word.length) {
// The new word is a prefix of an existing word, but the node on which it
- // should end already exists as is. Since the old CharNode was not a terminal,
+ // should end already exists as is. Since the old PtNode was not a terminal,
// make it one by filling in its frequency and other attributes
- currentGroup.update(frequency, shortcutTargets, null, isNotAWord,
+ currentPtNode.update(frequency, shortcutTargets, null, isNotAWord,
isBlacklistEntry);
} else {
// The new word matches the full old word and extends past it.
// We only have to create a new node and add it to the end of this.
- final CharGroup newNode = new CharGroup(
+ final PtNode newNode = new PtNode(
Arrays.copyOfRange(word, charIndex + differentCharIndex, word.length),
shortcutTargets, null /* bigrams */, frequency, isNotAWord,
isBlacklistEntry);
- currentGroup.mChildren = new Node();
- currentGroup.mChildren.mData.add(newNode);
+ currentPtNode.mChildren = new PtNodeArray();
+ currentPtNode.mChildren.mData.add(newNode);
}
} else {
if (0 == differentCharIndex) {
// Exact same word. Update the frequency if higher. This will also add the
// new shortcuts to the existing shortcut list if it already exists.
- currentGroup.update(frequency, shortcutTargets, null,
- currentGroup.mIsNotAWord && isNotAWord,
- currentGroup.mIsBlacklistEntry || isBlacklistEntry);
+ currentPtNode.update(frequency, shortcutTargets, null,
+ currentPtNode.mIsNotAWord && isNotAWord,
+ currentPtNode.mIsBlacklistEntry || isBlacklistEntry);
} else {
// Partial prefix match only. We have to replace the current node with a node
// containing the current prefix and create two new ones for the tails.
- Node newChildren = new Node();
- final CharGroup newOldWord = new CharGroup(
- Arrays.copyOfRange(currentGroup.mChars, differentCharIndex,
- currentGroup.mChars.length), currentGroup.mShortcutTargets,
- currentGroup.mBigrams, currentGroup.mFrequency,
- currentGroup.mIsNotAWord, currentGroup.mIsBlacklistEntry,
- currentGroup.mChildren);
+ PtNodeArray newChildren = new PtNodeArray();
+ final PtNode newOldWord = new PtNode(
+ Arrays.copyOfRange(currentPtNode.mChars, differentCharIndex,
+ currentPtNode.mChars.length), currentPtNode.mShortcutTargets,
+ currentPtNode.mBigrams, currentPtNode.mFrequency,
+ currentPtNode.mIsNotAWord, currentPtNode.mIsBlacklistEntry,
+ currentPtNode.mChildren);
newChildren.mData.add(newOldWord);
- final CharGroup newParent;
+ final PtNode newParent;
if (charIndex + differentCharIndex >= word.length) {
- newParent = new CharGroup(
- Arrays.copyOfRange(currentGroup.mChars, 0, differentCharIndex),
+ newParent = new PtNode(
+ Arrays.copyOfRange(currentPtNode.mChars, 0, differentCharIndex),
shortcutTargets, null /* bigrams */, frequency,
isNotAWord, isBlacklistEntry, newChildren);
} else {
- newParent = new CharGroup(
- Arrays.copyOfRange(currentGroup.mChars, 0, differentCharIndex),
+ newParent = new PtNode(
+ Arrays.copyOfRange(currentPtNode.mChars, 0, differentCharIndex),
null /* shortcutTargets */, null /* bigrams */, -1,
false /* isNotAWord */, false /* isBlacklistEntry */, newChildren);
- final CharGroup newWord = new CharGroup(Arrays.copyOfRange(word,
+ final PtNode newWord = new PtNode(Arrays.copyOfRange(word,
charIndex + differentCharIndex, word.length),
shortcutTargets, null /* bigrams */, frequency,
isNotAWord, isBlacklistEntry);
final int addIndex = word[charIndex + differentCharIndex]
- > currentGroup.mChars[differentCharIndex] ? 1 : 0;
+ > currentPtNode.mChars[differentCharIndex] ? 1 : 0;
newChildren.mData.add(addIndex, newWord);
}
- currentNode.mData.set(nodeIndex, newParent);
+ currentNodeArray.mData.set(nodeIndex, newParent);
}
- if (DBG) checkStack(currentNode);
+ if (DBG) checkStack(currentNodeArray);
}
}
}
@@ -576,7 +583,7 @@ public final class FusionDictionary implements Iterable<Word> {
* @param dstOffset the offset in the right-hand side string.
* @return the index at which the strings differ, or ARRAYS_ARE_EQUAL = 0 if they don't.
*/
- private static int compareArrays(final int[] src, final int[] dst, int dstOffset) {
+ private static int compareCharArrays(final int[] src, final int[] dst, int dstOffset) {
// We do NOT test the first char, because we come from a method that already
// tested it.
for (int i = 1; i < src.length; ++i) {
@@ -588,43 +595,43 @@ public final class FusionDictionary implements Iterable<Word> {
}
/**
- * Helper class that compares and sorts two chargroups according to their
+ * Helper class that compares and sorts two PtNodes according to their
* first element only. I repeat: ONLY the first element is considered, the rest
* is ignored.
* This comparator imposes orderings that are inconsistent with equals.
*/
- static private final class CharGroupComparator implements java.util.Comparator<CharGroup> {
+ static private final class PtNodeComparator implements java.util.Comparator<PtNode> {
@Override
- public int compare(CharGroup c1, CharGroup c2) {
- if (c1.mChars[0] == c2.mChars[0]) return 0;
- return c1.mChars[0] < c2.mChars[0] ? -1 : 1;
+ public int compare(PtNode p1, PtNode p2) {
+ if (p1.mChars[0] == p2.mChars[0]) return 0;
+ return p1.mChars[0] < p2.mChars[0] ? -1 : 1;
}
}
- final static private CharGroupComparator CHARGROUP_COMPARATOR = new CharGroupComparator();
+ final static private PtNodeComparator PTNODE_COMPARATOR = new PtNodeComparator();
/**
- * Finds the insertion index of a character within a node.
+ * Finds the insertion index of a character within a node array.
*/
- private static int findInsertionIndex(final Node node, int character) {
- final ArrayList<CharGroup> data = node.mData;
- final CharGroup reference = new CharGroup(new int[] { character },
+ private static int findInsertionIndex(final PtNodeArray nodeArray, int character) {
+ final ArrayList<PtNode> data = nodeArray.mData;
+ final PtNode reference = new PtNode(new int[] { character },
null /* shortcutTargets */, null /* bigrams */, 0, false /* isNotAWord */,
false /* isBlacklistEntry */);
- int result = Collections.binarySearch(data, reference, CHARGROUP_COMPARATOR);
+ int result = Collections.binarySearch(data, reference, PTNODE_COMPARATOR);
return result >= 0 ? result : -result - 1;
}
/**
- * Find the index of a char in a node, if it exists.
+ * Find the index of a char in a node array, if it exists.
*
- * @param node the node to search in.
+ * @param nodeArray the node array to search in.
* @param character the character to search for.
* @return the position of the character if it's there, or CHARACTER_NOT_FOUND_INDEX = -1 else.
*/
- private static int findIndexOfChar(final Node node, int character) {
- final int insertionIndex = findInsertionIndex(node, character);
- if (node.mData.size() <= insertionIndex) return CHARACTER_NOT_FOUND_INDEX;
- return character == node.mData.get(insertionIndex).mChars[0] ? insertionIndex
+ private static int findIndexOfChar(final PtNodeArray nodeArray, int character) {
+ final int insertionIndex = findInsertionIndex(nodeArray, character);
+ if (nodeArray.mData.size() <= insertionIndex) return CHARACTER_NOT_FOUND_INDEX;
+ return character == nodeArray.mData.get(insertionIndex).mChars[0] ? insertionIndex
: CHARACTER_NOT_FOUND_INDEX;
}
@@ -632,35 +639,37 @@ public final class FusionDictionary implements Iterable<Word> {
* Helper method to find a word in a given branch.
*/
@SuppressWarnings("unused")
- public static CharGroup findWordInTree(Node node, final String string) {
+ public static PtNode findWordInTree(PtNodeArray nodeArray, final String string) {
int index = 0;
final StringBuilder checker = DBG ? new StringBuilder() : null;
final int[] codePoints = getCodePoints(string);
- CharGroup currentGroup;
+ PtNode currentPtNode;
do {
- int indexOfGroup = findIndexOfChar(node, codePoints[index]);
+ int indexOfGroup = findIndexOfChar(nodeArray, codePoints[index]);
if (CHARACTER_NOT_FOUND_INDEX == indexOfGroup) return null;
- currentGroup = node.mData.get(indexOfGroup);
+ currentPtNode = nodeArray.mData.get(indexOfGroup);
- if (codePoints.length - index < currentGroup.mChars.length) return null;
+ if (codePoints.length - index < currentPtNode.mChars.length) return null;
int newIndex = index;
- while (newIndex < codePoints.length && newIndex - index < currentGroup.mChars.length) {
- if (currentGroup.mChars[newIndex - index] != codePoints[newIndex]) return null;
+ while (newIndex < codePoints.length && newIndex - index < currentPtNode.mChars.length) {
+ if (currentPtNode.mChars[newIndex - index] != codePoints[newIndex]) return null;
newIndex++;
}
index = newIndex;
- if (DBG) checker.append(new String(currentGroup.mChars, 0, currentGroup.mChars.length));
+ if (DBG) {
+ checker.append(new String(currentPtNode.mChars, 0, currentPtNode.mChars.length));
+ }
if (index < codePoints.length) {
- node = currentGroup.mChildren;
+ nodeArray = currentPtNode.mChildren;
}
- } while (null != node && index < codePoints.length);
+ } while (null != nodeArray && index < codePoints.length);
if (index < codePoints.length) return null;
- if (!currentGroup.isTerminal()) return null;
+ if (!currentPtNode.isTerminal()) return null;
if (DBG && !string.equals(checker.toString())) return null;
- return currentGroup;
+ return currentPtNode;
}
/**
@@ -670,22 +679,22 @@ public final class FusionDictionary implements Iterable<Word> {
if (null == s || "".equals(s)) {
throw new RuntimeException("Can't search for a null or empty string");
}
- return null != findWordInTree(mRoot, s);
+ return null != findWordInTree(mRootNodeArray, s);
}
/**
- * Recursively count the number of character groups in a given branch of the trie.
+ * Recursively count the number of PtNodes in a given branch of the trie.
*
- * @param node the parent node.
- * @return the number of char groups in all the branch under this node.
+ * @param nodeArray the parent node.
+ * @return the number of PtNodes in all the branch under this node.
*/
- public static int countCharGroups(final Node node) {
- final int nodeSize = node.mData.size();
+ public static int countPtNodes(final PtNodeArray nodeArray) {
+ final int nodeSize = nodeArray.mData.size();
int size = nodeSize;
for (int i = nodeSize - 1; i >= 0; --i) {
- CharGroup group = node.mData.get(i);
- if (null != group.mChildren)
- size += countCharGroups(group.mChildren);
+ PtNode ptNode = nodeArray.mData.get(i);
+ if (null != ptNode.mChildren)
+ size += countPtNodes(ptNode.mChildren);
}
return size;
}
@@ -693,15 +702,15 @@ public final class FusionDictionary implements Iterable<Word> {
/**
* Recursively count the number of nodes in a given branch of the trie.
*
- * @param node the node to count.
+ * @param nodeArray the node array to count.
* @return the number of nodes in this branch.
*/
- public static int countNodes(final Node node) {
+ public static int countNodeArrays(final PtNodeArray nodeArray) {
int size = 1;
- for (int i = node.mData.size() - 1; i >= 0; --i) {
- CharGroup group = node.mData.get(i);
- if (null != group.mChildren)
- size += countNodes(group.mChildren);
+ for (int i = nodeArray.mData.size() - 1; i >= 0; --i) {
+ PtNode ptNode = nodeArray.mData.get(i);
+ if (null != ptNode.mChildren)
+ size += countNodeArrays(ptNode.mChildren);
}
return size;
}
@@ -709,12 +718,12 @@ public final class FusionDictionary implements Iterable<Word> {
// Recursively find out whether there are any bigrams.
// This can be pretty expensive especially if there aren't any (we return as soon
// as we find one, so it's much cheaper if there are bigrams)
- private static boolean hasBigramsInternal(final Node node) {
- if (null == node) return false;
- for (int i = node.mData.size() - 1; i >= 0; --i) {
- CharGroup group = node.mData.get(i);
- if (null != group.mBigrams) return true;
- if (hasBigramsInternal(group.mChildren)) return true;
+ private static boolean hasBigramsInternal(final PtNodeArray nodeArray) {
+ if (null == nodeArray) return false;
+ for (int i = nodeArray.mData.size() - 1; i >= 0; --i) {
+ PtNode ptNode = nodeArray.mData.get(i);
+ if (null != ptNode.mBigrams) return true;
+ if (hasBigramsInternal(ptNode.mChildren)) return true;
}
return false;
}
@@ -729,7 +738,7 @@ public final class FusionDictionary implements Iterable<Word> {
// find a more efficient way of doing this, without compromising too much on memory
// and ease of use.
public boolean hasBigrams() {
- return hasBigramsInternal(mRoot);
+ return hasBigramsInternal(mRootNodeArray);
}
// Historically, the tails of the words were going to be merged to save space.
@@ -747,16 +756,16 @@ public final class FusionDictionary implements Iterable<Word> {
MakedictLog.i("Do not merge tails");
return;
-// MakedictLog.i("Merging nodes. Number of nodes : " + countNodes(root));
-// MakedictLog.i("Number of groups : " + countCharGroups(root));
+// MakedictLog.i("Merging PtNodes. Number of PtNodes : " + countPtNodes(root));
+// MakedictLog.i("Number of PtNodes : " + countPtNodes(root));
//
-// final HashMap<String, ArrayList<Node>> repository =
-// new HashMap<String, ArrayList<Node>>();
+// final HashMap<String, ArrayList<PtNodeArray>> repository =
+// new HashMap<String, ArrayList<PtNodeArray>>();
// mergeTailsInner(repository, root);
//
// MakedictLog.i("Number of different pseudohashes : " + repository.size());
// int size = 0;
-// for (ArrayList<Node> a : repository.values()) {
+// for (ArrayList<PtNodeArray> a : repository.values()) {
// size += a.size();
// }
// MakedictLog.i("Number of nodes after merge : " + (1 + size));
@@ -764,58 +773,58 @@ public final class FusionDictionary implements Iterable<Word> {
}
// The following methods are used by the deactivated mergeTails()
-// private static boolean isEqual(Node a, Node b) {
+// private static boolean isEqual(PtNodeArray a, PtNodeArray b) {
// if (null == a && null == b) return true;
// if (null == a || null == b) return false;
// if (a.data.size() != b.data.size()) return false;
// final int size = a.data.size();
// for (int i = size - 1; i >= 0; --i) {
-// CharGroup aGroup = a.data.get(i);
-// CharGroup bGroup = b.data.get(i);
-// if (aGroup.frequency != bGroup.frequency) return false;
-// if (aGroup.alternates == null && bGroup.alternates != null) return false;
-// if (aGroup.alternates != null && !aGroup.equals(bGroup.alternates)) return false;
-// if (!Arrays.equals(aGroup.chars, bGroup.chars)) return false;
-// if (!isEqual(aGroup.children, bGroup.children)) return false;
+// PtNode aPtNode = a.data.get(i);
+// PtNode bPtNode = b.data.get(i);
+// if (aPtNode.frequency != bPtNode.frequency) return false;
+// if (aPtNode.alternates == null && bPtNode.alternates != null) return false;
+// if (aPtNode.alternates != null && !aPtNode.equals(bPtNode.alternates)) return false;
+// if (!Arrays.equals(aPtNode.chars, bPtNode.chars)) return false;
+// if (!isEqual(aPtNode.children, bPtNode.children)) return false;
// }
// return true;
// }
-// static private HashMap<String, ArrayList<Node>> mergeTailsInner(
-// final HashMap<String, ArrayList<Node>> map, final Node node) {
-// final ArrayList<CharGroup> branches = node.data;
+// static private HashMap<String, ArrayList<PtNodeArray>> mergeTailsInner(
+// final HashMap<String, ArrayList<PtNodeArray>> map, final PtNodeArray nodeArray) {
+// final ArrayList<PtNode> branches = nodeArray.data;
// final int nodeSize = branches.size();
// for (int i = 0; i < nodeSize; ++i) {
-// CharGroup group = branches.get(i);
-// if (null != group.children) {
-// String pseudoHash = getPseudoHash(group.children);
-// ArrayList<Node> similarList = map.get(pseudoHash);
+// PtNode ptNode = branches.get(i);
+// if (null != ptNode.children) {
+// String pseudoHash = getPseudoHash(ptNode.children);
+// ArrayList<PtNodeArray> similarList = map.get(pseudoHash);
// if (null == similarList) {
-// similarList = new ArrayList<Node>();
+// similarList = new ArrayList<PtNodeArray>();
// map.put(pseudoHash, similarList);
// }
// boolean merged = false;
-// for (Node similar : similarList) {
-// if (isEqual(group.children, similar)) {
-// group.children = similar;
+// for (PtNodeArray similar : similarList) {
+// if (isEqual(ptNode.children, similar)) {
+// ptNode.children = similar;
// merged = true;
// break;
// }
// }
// if (!merged) {
-// similarList.add(group.children);
+// similarList.add(ptNode.children);
// }
-// mergeTailsInner(map, group.children);
+// mergeTailsInner(map, ptNode.children);
// }
// }
// return map;
// }
-// private static String getPseudoHash(final Node node) {
+// private static String getPseudoHash(final PtNodeArray nodeArray) {
// StringBuilder s = new StringBuilder();
-// for (CharGroup g : node.data) {
-// s.append(g.frequency);
-// for (int ch : g.chars) {
+// for (PtNode ptNode : nodeArray.data) {
+// s.append(ptNode.frequency);
+// for (int ch : ptNode.chars) {
// s.append(Character.toChars(ch));
// }
// }
@@ -829,20 +838,20 @@ public final class FusionDictionary implements Iterable<Word> {
*/
public static final class DictionaryIterator implements Iterator<Word> {
private static final class Position {
- public Iterator<CharGroup> pos;
+ public Iterator<PtNode> pos;
public int length;
- public Position(ArrayList<CharGroup> groups) {
- pos = groups.iterator();
+ public Position(ArrayList<PtNode> ptNodes) {
+ pos = ptNodes.iterator();
length = 0;
}
}
final StringBuilder mCurrentString;
final LinkedList<Position> mPositions;
- public DictionaryIterator(ArrayList<CharGroup> root) {
+ public DictionaryIterator(ArrayList<PtNode> ptRoot) {
mCurrentString = new StringBuilder();
mPositions = new LinkedList<Position>();
- final Position rootPos = new Position(root);
+ final Position rootPos = new Position(ptRoot);
mPositions.add(rootPos);
}
@@ -863,20 +872,20 @@ public final class FusionDictionary implements Iterable<Word> {
do {
if (currentPos.pos.hasNext()) {
- final CharGroup currentGroup = currentPos.pos.next();
+ final PtNode currentPtNode = currentPos.pos.next();
currentPos.length = mCurrentString.length();
- for (int i : currentGroup.mChars) {
+ for (int i : currentPtNode.mChars) {
mCurrentString.append(Character.toChars(i));
}
- if (null != currentGroup.mChildren) {
- currentPos = new Position(currentGroup.mChildren.mData);
+ if (null != currentPtNode.mChildren) {
+ currentPos = new Position(currentPtNode.mChildren.mData);
currentPos.length = mCurrentString.length();
mPositions.addLast(currentPos);
}
- if (currentGroup.mFrequency >= 0) {
- return new Word(mCurrentString.toString(), currentGroup.mFrequency,
- currentGroup.mShortcutTargets, currentGroup.mBigrams,
- currentGroup.mIsNotAWord, currentGroup.mIsBlacklistEntry);
+ if (currentPtNode.mFrequency >= 0) {
+ return new Word(mCurrentString.toString(), currentPtNode.mFrequency,
+ currentPtNode.mShortcutTargets, currentPtNode.mBigrams,
+ currentPtNode.mIsNotAWord, currentPtNode.mIsBlacklistEntry);
}
} else {
mPositions.removeLast();
@@ -901,6 +910,6 @@ public final class FusionDictionary implements Iterable<Word> {
*/
@Override
public Iterator<Word> iterator() {
- return new DictionaryIterator(mRoot.mData);
+ return new DictionaryIterator(mRootNodeArray.mData);
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java b/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
index b3617443e..188de7a0f 100644
--- a/java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java
+++ b/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
@@ -21,9 +21,9 @@ import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.util.ArrayList;
/**
- * Raw char group info straight out of a file. This will contain numbers for addresses.
+ * Raw PtNode info straight out of a file. This will contain numbers for addresses.
*/
-public final class CharGroupInfo {
+public final class PtNodeInfo {
public final int mOriginalAddress;
public final int mEndAddress;
@@ -35,7 +35,7 @@ public final class CharGroupInfo {
public final ArrayList<WeightedString> mShortcutTargets;
public final ArrayList<PendingAttribute> mBigrams;
- public CharGroupInfo(final int originalAddress, final int endAddress, final int flags,
+ public PtNodeInfo(final int originalAddress, final int endAddress, final int flags,
final int[] characters, final int frequency, final int parentAddress,
final int childrenAddress, final ArrayList<WeightedString> shortcutTargets,
final ArrayList<PendingAttribute> bigrams) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
new file mode 100644
index 000000000..848277cd4
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.utils.JniUtils;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * An implementation of DictDecoder for version 3 binary dictionary.
+ */
+@UsedForTesting
+public class Ver3DictDecoder extends DictDecoder {
+ private static final String TAG = Ver3DictDecoder.class.getSimpleName();
+
+ static {
+ JniUtils.loadNativeLibrary();
+ }
+
+ // TODO: implement something sensical instead of just a phony method
+ private static native int doNothing();
+
+ protected static class PtNodeReader extends DictDecoder.PtNodeReader {
+ private static int readFrequency(final DictBuffer dictBuffer) {
+ return dictBuffer.readUnsignedByte();
+ }
+ }
+
+ private final File mDictionaryBinaryFile;
+ private final DictionaryBufferFactory mBufferFactory;
+ private DictBuffer mDictBuffer;
+
+ /* package */ Ver3DictDecoder(final File file, final int factoryFlag) {
+ mDictionaryBinaryFile = file;
+ mDictBuffer = null;
+
+ if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) {
+ mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
+ } else if ((factoryFlag & MASK_DICTBUFFER) == USE_BYTEARRAY) {
+ mBufferFactory = new DictionaryBufferFromByteArrayFactory();
+ } else if ((factoryFlag & MASK_DICTBUFFER) == USE_WRITABLE_BYTEBUFFER) {
+ mBufferFactory = new DictionaryBufferFromWritableByteBufferFactory();
+ } else {
+ mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
+ }
+ }
+
+ /* package */ Ver3DictDecoder(final File file, final DictionaryBufferFactory factory) {
+ mDictionaryBinaryFile = file;
+ mBufferFactory = factory;
+ }
+
+ @Override
+ public void openDictBuffer() throws FileNotFoundException, IOException {
+ mDictBuffer = mBufferFactory.getDictionaryBuffer(mDictionaryBinaryFile);
+ }
+
+ @Override
+ public boolean isDictBufferOpen() {
+ return mDictBuffer != null;
+ }
+
+ /* package */ DictBuffer getDictBuffer() {
+ return mDictBuffer;
+ }
+
+ @UsedForTesting
+ /* package */ DictBuffer openAndGetDictBuffer() throws FileNotFoundException, IOException {
+ openDictBuffer();
+ return getDictBuffer();
+ }
+
+ @Override
+ public FileHeader readHeader() throws IOException, UnsupportedFormatException {
+ if (mDictBuffer == null) {
+ openDictBuffer();
+ }
+ final FileHeader header = super.readHeader(mDictBuffer);
+ final int version = header.mFormatOptions.mVersion;
+ if (!(version >= 2 && version <= 3)) {
+ throw new UnsupportedFormatException("File header has a wrong version : " + version);
+ }
+ return header;
+ }
+
+ // TODO: Make this buffer multi thread safe.
+ private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH];
+ @Override
+ public PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions options) {
+ int addressPointer = ptNodePos;
+ final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_FLAGS_SIZE;
+
+ final int parentAddress = PtNodeReader.readParentAddress(mDictBuffer, options);
+ if (BinaryDictIOUtils.supportsDynamicUpdate(options)) {
+ addressPointer += FormatSpec.PARENT_ADDRESS_SIZE;
+ }
+
+ final int characters[];
+ if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) {
+ int index = 0;
+ int character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ while (FormatSpec.INVALID_CHARACTER != character) {
+ // FusionDictionary is making sure that the length of the word is smaller than
+ // MAX_WORD_LENGTH.
+ // So we'll never write past the end of mCharacterBuffer.
+ mCharacterBuffer[index++] = character;
+ character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ }
+ characters = Arrays.copyOfRange(mCharacterBuffer, 0, index);
+ } else {
+ final int character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ characters = new int[] { character };
+ }
+ final int frequency;
+ if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
+ frequency = PtNodeReader.readFrequency(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_FREQUENCY_SIZE;
+ } else {
+ frequency = PtNode.NOT_A_TERMINAL;
+ }
+ int childrenAddress = PtNodeReader.readChildrenAddress(mDictBuffer, flags, options);
+ if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ childrenAddress += addressPointer;
+ }
+ addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags, options);
+ final ArrayList<WeightedString> shortcutTargets;
+ if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) {
+ // readShortcut will add shortcuts to shortcutTargets.
+ shortcutTargets = new ArrayList<WeightedString>();
+ addressPointer += PtNodeReader.readShortcut(mDictBuffer, shortcutTargets);
+ } else {
+ shortcutTargets = null;
+ }
+
+ final ArrayList<PendingAttribute> bigrams;
+ if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
+ bigrams = new ArrayList<PendingAttribute>();
+ addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams,
+ addressPointer);
+ if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ MakedictLog.d("too many bigrams in a PtNode.");
+ }
+ } else {
+ bigrams = null;
+ }
+ return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, frequency,
+ parentAddress, childrenAddress, shortcutTargets, bigrams);
+ }
+
+ @Override
+ public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
+ final boolean deleteDictIfBroken)
+ throws FileNotFoundException, IOException, UnsupportedFormatException {
+ if (mDictBuffer == null) {
+ openDictBuffer();
+ }
+ try {
+ return BinaryDictDecoderUtils.readDictionaryBinary(this, dict);
+ } catch (IOException e) {
+ Log.e(TAG, "The dictionary " + mDictionaryBinaryFile.getName() + " is broken.", e);
+ if (deleteDictIfBroken && !mDictionaryBinaryFile.delete()) {
+ Log.e(TAG, "Failed to delete the broken dictionary.");
+ }
+ throw e;
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "The dictionary " + mDictionaryBinaryFile.getName() + " is broken.", e);
+ if (deleteDictIfBroken && !mDictionaryBinaryFile.delete()) {
+ Log.e(TAG, "Failed to delete the broken dictionary.");
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void setPosition(int newPos) {
+ mDictBuffer.position(newPos);
+ }
+
+ @Override
+ public int getPosition() {
+ return mDictBuffer.position();
+ }
+
+ @Override
+ public int readPtNodeCount() {
+ return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer);
+ }
+
+ @Override
+ public boolean readAndFollowForwardLink() {
+ final int nextAddress = mDictBuffer.readUnsignedInt24();
+ if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
+ mDictBuffer.position(nextAddress);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasNextPtNodeArray() {
+ return mDictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java
new file mode 100644
index 000000000..76f0f4052
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * An implementation of DictEncoder for version 3 binary dictionary.
+ */
+public class Ver3DictEncoder implements DictEncoder {
+
+ private final File mDictFile;
+ private OutputStream mOutStream;
+ private byte[] mBuffer;
+ private int mPosition;
+
+ public Ver3DictEncoder(final File dictFile) {
+ mDictFile = dictFile;
+ mOutStream = null;
+ mBuffer = null;
+ }
+
+ // This constructor is used only by BinaryDictOffdeviceUtilsTests.
+ // If you want to use this in the production code, you should consider keeping consistency of
+ // the interface of Ver3DictDecoder by using factory.
+ public Ver3DictEncoder(final OutputStream outStream) {
+ mDictFile = null;
+ mOutStream = outStream;
+ }
+
+ private void openStream() throws FileNotFoundException {
+ mOutStream = new FileOutputStream(mDictFile);
+ }
+
+ private void close() throws IOException {
+ if (mOutStream != null) {
+ mOutStream.close();
+ mOutStream = null;
+ }
+ }
+
+ @Override
+ public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions)
+ throws IOException, UnsupportedFormatException {
+ if (formatOptions.mVersion > FormatSpec.VERSION3) {
+ throw new UnsupportedFormatException(
+ "The given format options has wrong version number : "
+ + formatOptions.mVersion);
+ }
+
+ if (mOutStream == null) {
+ openStream();
+ }
+ BinaryDictEncoderUtils.writeDictionaryHeader(mOutStream, dict, formatOptions);
+
+ // Addresses are limited to 3 bytes, but since addresses can be relative to each node
+ // array, the structure itself is not limited to 16MB. However, if it is over 16MB deciding
+ // the order of the PtNode arrays becomes a quite complicated problem, because though the
+ // dictionary itself does not have a size limit, each node array must still be within 16MB
+ // of all its children and parents. As long as this is ensured, the dictionary file may
+ // grow to any size.
+
+ // Leave the choice of the optimal node order to the flattenTree function.
+ MakedictLog.i("Flattening the tree...");
+ ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray);
+
+ MakedictLog.i("Computing addresses...");
+ BinaryDictEncoderUtils.computeAddresses(dict, flatNodes, formatOptions);
+ MakedictLog.i("Checking PtNode array...");
+ if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes);
+
+ // Create a buffer that matches the final dictionary size.
+ final PtNodeArray lastNodeArray = flatNodes.get(flatNodes.size() - 1);
+ final int bufferSize = lastNodeArray.mCachedAddressAfterUpdate + lastNodeArray.mCachedSize;
+ mBuffer = new byte[bufferSize];
+
+ MakedictLog.i("Writing file...");
+
+ for (PtNodeArray nodeArray : flatNodes) {
+ BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray, formatOptions);
+ }
+ if (MakedictLog.DBG) BinaryDictEncoderUtils.showStatistics(flatNodes);
+ mOutStream.write(mBuffer, 0, mPosition);
+
+ MakedictLog.i("Done");
+ close();
+ }
+
+ @Override
+ public void setPosition(final int position) {
+ if (mBuffer == null || position < 0 || position >= mBuffer.length) return;
+ mPosition = position;
+ }
+
+ @Override
+ public int getPosition() {
+ return mPosition;
+ }
+
+ @Override
+ public void writePtNodeCount(final int ptNodeCount) {
+ final int countSize = BinaryDictIOUtils.getPtNodeCountSize(ptNodeCount);
+ if (countSize != 1 && countSize != 2) {
+ throw new RuntimeException("Strange size from getGroupCountSize : " + countSize);
+ }
+ mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, ptNodeCount,
+ countSize);
+ }
+
+ private void writePtNodeFlags(final PtNode ptNode, final int parentAddress,
+ final FormatOptions formatOptions) {
+ final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
+ mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition,
+ BinaryDictEncoderUtils.makePtNodeFlags(ptNode, mPosition, childrenPos,
+ formatOptions),
+ FormatSpec.PTNODE_FLAGS_SIZE);
+ }
+
+ private void writeParentPosition(final int parentPosition, final PtNode ptNode,
+ final FormatOptions formatOptions) {
+ if (parentPosition == FormatSpec.NO_PARENT_ADDRESS) {
+ mPosition = BinaryDictEncoderUtils.writeParentAddress(mBuffer, mPosition,
+ parentPosition, formatOptions);
+ } else {
+ mPosition = BinaryDictEncoderUtils.writeParentAddress(mBuffer, mPosition,
+ parentPosition - ptNode.mCachedAddressAfterUpdate, formatOptions);
+ }
+ }
+
+ private void writeCharacters(final int[] codePoints, final boolean hasSeveralChars) {
+ mPosition = CharEncoding.writeCharArray(codePoints, mBuffer, mPosition);
+ if (hasSeveralChars) {
+ mBuffer[mPosition++] = FormatSpec.PTNODE_CHARACTERS_TERMINATOR;
+ }
+ }
+
+ private void writeFrequency(final int frequency) {
+ if (frequency >= 0) {
+ mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, frequency,
+ FormatSpec.PTNODE_FREQUENCY_SIZE);
+ }
+ }
+
+ private void writeChildrenPosition(final PtNode ptNode, final FormatOptions formatOptions) {
+ final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
+ if (formatOptions.mSupportsDynamicUpdate) {
+ mPosition += BinaryDictEncoderUtils.writeSignedChildrenPosition(mBuffer, mPosition,
+ childrenPos);
+ } else {
+ mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition,
+ childrenPos);
+ }
+ }
+
+ /**
+ * Write a shortcut attributes list to mBuffer.
+ *
+ * @param shortcuts the shortcut attributes list.
+ */
+ private void writeShortcuts(final ArrayList<WeightedString> shortcuts) {
+ if (null == shortcuts || shortcuts.isEmpty()) return;
+
+ final int indexOfShortcutByteSize = mPosition;
+ mPosition += FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE;
+ final Iterator<WeightedString> shortcutIterator = shortcuts.iterator();
+ while (shortcutIterator.hasNext()) {
+ final WeightedString target = shortcutIterator.next();
+ final int shortcutFlags = BinaryDictEncoderUtils.makeShortcutFlags(
+ shortcutIterator.hasNext(),
+ target.mFrequency);
+ mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, shortcutFlags,
+ FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
+ final int shortcutShift = CharEncoding.writeString(mBuffer, mPosition, target.mWord);
+ mPosition += shortcutShift;
+ }
+ final int shortcutByteSize = mPosition - indexOfShortcutByteSize;
+ if (shortcutByteSize > FormatSpec.MAX_SHORTCUT_LIST_SIZE_IN_A_PTNODE) {
+ throw new RuntimeException("Shortcut list too large");
+ }
+ BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, indexOfShortcutByteSize, shortcutByteSize,
+ FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE);
+ }
+
+ /**
+ * Write a bigram attributes list to mBuffer.
+ *
+ * @param bigrams the bigram attributes list.
+ * @param dict the dictionary the node array is a part of (for relative offsets).
+ */
+ private void writeBigrams(final ArrayList<WeightedString> bigrams,
+ final FusionDictionary dict) {
+ if (bigrams == null) return;
+
+ final Iterator<WeightedString> bigramIterator = bigrams.iterator();
+ while (bigramIterator.hasNext()) {
+ final WeightedString bigram = bigramIterator.next();
+ final PtNode target =
+ FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord);
+ final int addressOfBigram = target.mCachedAddressAfterUpdate;
+ final int unigramFrequencyForThisWord = target.mFrequency;
+ final int offset = addressOfBigram
+ - (mPosition + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
+ final int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(),
+ offset, bigram.mFrequency, unigramFrequencyForThisWord, bigram.mWord);
+ mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, bigramFlags,
+ FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
+ mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition,
+ Math.abs(offset));
+ }
+ }
+
+ @Override
+ public void writeForwardLinkAddress(final int forwardLinkAddress) {
+ mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, forwardLinkAddress,
+ FormatSpec.FORWARD_LINK_ADDRESS_SIZE);
+ }
+
+ @Override
+ public void writePtNode(final PtNode ptNode, final int parentPosition,
+ final FormatOptions formatOptions, final FusionDictionary dict) {
+ writePtNodeFlags(ptNode, parentPosition, formatOptions);
+ writeParentPosition(parentPosition, ptNode, formatOptions);
+ writeCharacters(ptNode.mChars, ptNode.hasSeveralChars());
+ writeFrequency(ptNode.mFrequency);
+ writeChildrenPosition(ptNode, formatOptions);
+ writeShortcuts(ptNode.mShortcutTargets);
+ writeBigrams(ptNode.mBigrams, dict);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
new file mode 100644
index 000000000..36c5a2720
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * An implementation of binary dictionary decoder for version 4 binary dictionary.
+ */
+@UsedForTesting
+public class Ver4DictDecoder extends DictDecoder {
+ private static final String TAG = Ver4DictDecoder.class.getSimpleName();
+
+ private static final int FILETYPE_TRIE = 1;
+ private static final int FILETYPE_FREQUENCY = 2;
+
+ private final File mDictDirectory;
+ private final DictionaryBufferFactory mBufferFactory;
+ private DictBuffer mDictBuffer;
+ private DictBuffer mFrequencyBuffer;
+
+ @UsedForTesting
+ /* package */ Ver4DictDecoder(final File dictDirectory, final int factoryFlag) {
+ mDictDirectory = dictDirectory;
+ mDictBuffer = mFrequencyBuffer = null;
+
+ if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) {
+ mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
+ } else if ((factoryFlag & MASK_DICTBUFFER) == USE_BYTEARRAY) {
+ mBufferFactory = new DictionaryBufferFromByteArrayFactory();
+ } else if ((factoryFlag & MASK_DICTBUFFER) == USE_WRITABLE_BYTEBUFFER) {
+ mBufferFactory = new DictionaryBufferFromWritableByteBufferFactory();
+ } else {
+ mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
+ }
+ }
+
+ @UsedForTesting
+ /* package */ Ver4DictDecoder(final File dictDirectory, final DictionaryBufferFactory factory) {
+ mDictDirectory = dictDirectory;
+ mBufferFactory = factory;
+ mDictBuffer = mFrequencyBuffer = null;
+ }
+
+ private File getFile(final int fileType) {
+ if (fileType == FILETYPE_TRIE) {
+ return new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.TRIE_FILE_EXTENSION);
+ } else if (fileType == FILETYPE_FREQUENCY) {
+ return new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.FREQ_FILE_EXTENSION);
+ } else {
+ throw new RuntimeException("Unsupported kind of file : " + fileType);
+ }
+ }
+
+ @Override
+ public void openDictBuffer() throws FileNotFoundException, IOException {
+ final String filename = mDictDirectory.getName();
+ mDictBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_TRIE));
+ mFrequencyBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_FREQUENCY));
+ }
+
+ @Override
+ public boolean isDictBufferOpen() {
+ return mDictBuffer != null;
+ }
+
+ /* package */ DictBuffer getDictBuffer() {
+ return mDictBuffer;
+ }
+
+ @Override
+ public FileHeader readHeader() throws IOException, UnsupportedFormatException {
+ if (mDictBuffer == null) {
+ openDictBuffer();
+ }
+ final FileHeader header = super.readHeader(mDictBuffer);
+ final int version = header.mFormatOptions.mVersion;
+ if (version != 4) {
+ throw new UnsupportedFormatException("File header has a wrong version : " + version);
+ }
+ return header;
+ }
+
+ protected static class PtNodeReader extends DictDecoder.PtNodeReader {
+ protected static int readFrequency(final DictBuffer frequencyBuffer, final int terminalId) {
+ frequencyBuffer.position(terminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE + 1);
+ return frequencyBuffer.readUnsignedByte();
+ }
+
+ protected static int readTerminalId(final DictBuffer dictBuffer) {
+ return dictBuffer.readInt();
+ }
+ }
+
+ // TODO: Make this buffer thread safe.
+ // TODO: Support words longer than FormatSpec.MAX_WORD_LENGTH.
+ private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH];
+ @Override
+ public PtNodeInfo readPtNode(int ptNodePos, FormatOptions options) {
+ int addressPointer = ptNodePos;
+ final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_FLAGS_SIZE;
+
+ final int parentAddress = PtNodeReader.readParentAddress(mDictBuffer, options);
+ if (BinaryDictIOUtils.supportsDynamicUpdate(options)) {
+ addressPointer += FormatSpec.PARENT_ADDRESS_SIZE;
+ }
+
+ final int characters[];
+ if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) {
+ int index = 0;
+ int character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ while (FormatSpec.INVALID_CHARACTER != character
+ && index < FormatSpec.MAX_WORD_LENGTH) {
+ mCharacterBuffer[index++] = character;
+ character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ }
+ characters = Arrays.copyOfRange(mCharacterBuffer, 0, index);
+ } else {
+ final int character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ characters = new int[] { character };
+ }
+ final int terminalId;
+ if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
+ terminalId = PtNodeReader.readTerminalId(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+ } else {
+ terminalId = PtNode.NOT_A_TERMINAL;
+ }
+
+ final int frequency;
+ if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
+ frequency = PtNodeReader.readFrequency(mFrequencyBuffer, terminalId);
+ } else {
+ frequency = PtNode.NOT_A_TERMINAL;
+ }
+ int childrenAddress = PtNodeReader.readChildrenAddress(mDictBuffer, flags, options);
+ if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ childrenAddress += addressPointer;
+ }
+ addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags, options);
+ final ArrayList<WeightedString> shortcutTargets;
+ if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) {
+ // readShortcut will add shortcuts to shortcutTargets.
+ shortcutTargets = new ArrayList<WeightedString>();
+ addressPointer += PtNodeReader.readShortcut(mDictBuffer, shortcutTargets);
+ } else {
+ shortcutTargets = null;
+ }
+
+ final ArrayList<PendingAttribute> bigrams;
+ if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
+ bigrams = new ArrayList<PendingAttribute>();
+ addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams,
+ addressPointer);
+ if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ MakedictLog.d("too many bigrams in a node.");
+ }
+ } else {
+ bigrams = null;
+ }
+ return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, frequency,
+ parentAddress, childrenAddress, shortcutTargets, bigrams);
+ }
+
+ private void deleteDictFiles() {
+ final File[] files = mDictDirectory.listFiles();
+ for (int i = 0; i < files.length; ++i) {
+ files[i].delete();
+ }
+ }
+
+ @Override
+ public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
+ final boolean deleteDictIfBroken)
+ throws FileNotFoundException, IOException, UnsupportedFormatException {
+ if (mDictBuffer == null) {
+ openDictBuffer();
+ }
+ try {
+ return BinaryDictDecoderUtils.readDictionaryBinary(this, dict);
+ } catch (IOException e) {
+ Log.e(TAG, "The dictionary " + mDictDirectory.getName() + " is broken.", e);
+ if (deleteDictIfBroken) {
+ deleteDictFiles();
+ }
+ throw e;
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "The dictionary " + mDictDirectory.getName() + " is broken.", e);
+ if (deleteDictIfBroken) {
+ deleteDictFiles();
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void setPosition(int newPos) {
+ mDictBuffer.position(newPos);
+ }
+
+ @Override
+ public int getPosition() {
+ return mDictBuffer.position();
+ }
+
+ @Override
+ public int readPtNodeCount() {
+ return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer);
+ }
+
+ @Override
+ public boolean readAndFollowForwardLink() {
+ final int nextAddress = mDictBuffer.readUnsignedInt24();
+ if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
+ mDictBuffer.position(nextAddress);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasNextPtNodeArray() {
+ return mDictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
new file mode 100644
index 000000000..75b75ae2e
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
@@ -0,0 +1,269 @@
+/*
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * An implementation of DictEncoder for version 4 binary dictionary.
+ */
+@UsedForTesting
+public class Ver4DictEncoder implements DictEncoder {
+ private final File mDictPlacedDir;
+ private byte[] mTrieBuf;
+ private byte[] mFreqBuf;
+ private int mTriePos;
+ private OutputStream mTrieOutStream;
+ private OutputStream mFreqOutStream;
+
+ @UsedForTesting
+ public Ver4DictEncoder(final File dictPlacedDir) {
+ mDictPlacedDir = dictPlacedDir;
+ }
+
+ private void openStreams(final FormatOptions formatOptions, final DictionaryOptions dictOptions)
+ throws FileNotFoundException, IOException {
+ final FileHeader header = new FileHeader(0, dictOptions, formatOptions);
+ final String filename = header.getId() + "." + header.getVersion();
+ final File mDictDir = new File(mDictPlacedDir, filename);
+ final File trieFile = new File(mDictDir, filename + FormatSpec.TRIE_FILE_EXTENSION);
+ final File freqFile = new File(mDictDir, filename + FormatSpec.FREQ_FILE_EXTENSION);
+ if (!mDictDir.isDirectory()) {
+ if (mDictDir.exists()) mDictDir.delete();
+ mDictDir.mkdirs();
+ }
+ if (!trieFile.exists()) trieFile.createNewFile();
+ if (!freqFile.exists()) freqFile.createNewFile();
+ mTrieOutStream = new FileOutputStream(trieFile);
+ mFreqOutStream = new FileOutputStream(freqFile);
+ }
+
+ private void close() throws IOException {
+ try {
+ if (mTrieOutStream != null) {
+ mTrieOutStream.close();
+ }
+ if (mFreqOutStream != null) {
+ mFreqOutStream.close();
+ }
+ } finally {
+ mTrieOutStream = null;
+ mFreqOutStream = null;
+ }
+ }
+
+ @Override
+ public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions)
+ throws IOException, UnsupportedFormatException {
+ if (formatOptions.mVersion != FormatSpec.VERSION4) {
+ throw new UnsupportedFormatException("File header has a wrong version number : "
+ + formatOptions.mVersion);
+ }
+ if (!mDictPlacedDir.isDirectory()) {
+ throw new UnsupportedFormatException("Given path is not a directory.");
+ }
+
+ if (mTrieOutStream == null) {
+ openStreams(formatOptions, dict.mOptions);
+ }
+
+ BinaryDictEncoderUtils.writeDictionaryHeader(mTrieOutStream, dict, formatOptions);
+
+ MakedictLog.i("Flattening the tree...");
+ ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray);
+ int terminalCount = 0;
+ for (final PtNodeArray array : flatNodes) {
+ for (final PtNode node : array.mData) {
+ if (node.isTerminal()) node.mTerminalId = terminalCount++;
+ }
+ }
+
+ MakedictLog.i("Computing addresses...");
+ BinaryDictEncoderUtils.computeAddresses(dict, flatNodes, formatOptions);
+ if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes);
+
+ final PtNodeArray lastNodeArray = flatNodes.get(flatNodes.size() - 1);
+ final int bufferSize = lastNodeArray.mCachedAddressAfterUpdate + lastNodeArray.mCachedSize;
+ mTrieBuf = new byte[bufferSize];
+ mFreqBuf = new byte[terminalCount * FormatSpec.FREQUENCY_AND_FLAGS_SIZE];
+
+ MakedictLog.i("Writing file...");
+ for (PtNodeArray nodeArray : flatNodes) {
+ BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray, formatOptions);
+ }
+ if (MakedictLog.DBG) {
+ BinaryDictEncoderUtils.showStatistics(flatNodes);
+ MakedictLog.i("has " + terminalCount + " terminals.");
+ }
+ mTrieOutStream.write(mTrieBuf);
+ mFreqOutStream.write(mFreqBuf);
+
+ MakedictLog.i("Done");
+ close();
+ }
+
+ @Override
+ public void setPosition(int position) {
+ if (mTrieBuf == null || position < 0 || position >- mTrieBuf.length) return;
+ mTriePos = position;
+ }
+
+ @Override
+ public int getPosition() {
+ return mTriePos;
+ }
+
+ @Override
+ public void writePtNodeCount(int ptNodeCount) {
+ final int countSize = BinaryDictIOUtils.getPtNodeCountSize(ptNodeCount);
+ // ptNodeCount must fit on one byte or two bytes.
+ // Please see comments in FormatSpec
+ if (countSize != 1 && countSize != 2) {
+ throw new RuntimeException("Strange size from getPtNodeCountSize : " + countSize);
+ }
+ mTriePos = BinaryDictEncoderUtils.writeUIntToBuffer(mTrieBuf, mTriePos, ptNodeCount,
+ countSize);
+ }
+
+ private void writePtNodeFlags(final PtNode ptNode, final int parentAddress,
+ final FormatOptions formatOptions) {
+ final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
+ mTriePos = BinaryDictEncoderUtils.writeUIntToBuffer(mTrieBuf, mTriePos,
+ BinaryDictEncoderUtils.makePtNodeFlags(ptNode, mTriePos, childrenPos,
+ formatOptions),
+ FormatSpec.PTNODE_FLAGS_SIZE);
+ }
+
+ private void writeParentPosition(int parentPos, final PtNode ptNode,
+ final FormatOptions formatOptions) {
+ if (parentPos != FormatSpec.NO_PARENT_ADDRESS) {
+ parentPos -= ptNode.mCachedAddressAfterUpdate;
+ }
+ mTriePos = BinaryDictEncoderUtils.writeParentAddress(mTrieBuf, mTriePos, parentPos,
+ formatOptions);
+ }
+
+ private void writeCharacters(final int[] characters, final boolean hasSeveralChars) {
+ mTriePos = CharEncoding.writeCharArray(characters, mTrieBuf, mTriePos);
+ if (hasSeveralChars) {
+ mTrieBuf[mTriePos++] = FormatSpec.PTNODE_CHARACTERS_TERMINATOR;
+ }
+ }
+
+ private void writeTerminalId(final int terminalId) {
+ mTriePos = BinaryDictEncoderUtils.writeUIntToBuffer(mTrieBuf, mTriePos, terminalId,
+ FormatSpec.PTNODE_TERMINAL_ID_SIZE);
+ }
+
+ private void writeFrequency(final int frequency, final int terminalId) {
+ final int freqPos = terminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE;
+ BinaryDictEncoderUtils.writeUIntToBuffer(mFreqBuf, freqPos, frequency,
+ FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
+ }
+
+ private void writeChildrenPosition(PtNode ptNode, FormatOptions formatOptions) {
+ final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
+ if (formatOptions.mSupportsDynamicUpdate) {
+ mTriePos += BinaryDictEncoderUtils.writeSignedChildrenPosition(mTrieBuf,
+ mTriePos, childrenPos);
+ } else {
+ mTriePos += BinaryDictEncoderUtils.writeChildrenPosition(mTrieBuf,
+ mTriePos, childrenPos);
+ }
+ }
+
+ private void writeShortcuts(ArrayList<WeightedString> shortcuts) {
+ if (null == shortcuts || shortcuts.isEmpty()) return;
+
+ final int indexOfShortcutByteSize = mTriePos;
+ mTriePos += FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE;
+ final Iterator<WeightedString> shortcutIterator = shortcuts.iterator();
+ while (shortcutIterator.hasNext()) {
+ final WeightedString target = shortcutIterator.next();
+ final int shortcutFlags = BinaryDictEncoderUtils.makeShortcutFlags(
+ shortcutIterator.hasNext(),
+ target.mFrequency);
+ mTrieBuf[mTriePos++] = (byte)shortcutFlags;
+ final int shortcutShift = CharEncoding.writeString(mTrieBuf, mTriePos,
+ target.mWord);
+ mTriePos += shortcutShift;
+ }
+ final int shortcutByteSize = mTriePos - indexOfShortcutByteSize;
+ if (shortcutByteSize > FormatSpec.MAX_SHORTCUT_LIST_SIZE_IN_A_PTNODE) {
+ throw new RuntimeException("Shortcut list too large : " + shortcutByteSize);
+ }
+ BinaryDictEncoderUtils.writeUIntToBuffer(mTrieBuf, indexOfShortcutByteSize,
+ shortcutByteSize, FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE);
+ }
+
+ private void writeBigrams(ArrayList<WeightedString> bigrams, FusionDictionary dict) {
+ if (bigrams == null) return;
+
+ final Iterator<WeightedString> bigramIterator = bigrams.iterator();
+ while (bigramIterator.hasNext()) {
+ final WeightedString bigram = bigramIterator.next();
+ final PtNode target =
+ FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord);
+ final int addressOfBigram = target.mCachedAddressAfterUpdate;
+ final int unigramFrequencyForThisWord = target.mFrequency;
+ final int offset = addressOfBigram
+ - (mTriePos + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
+ int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(),
+ offset, bigram.mFrequency, unigramFrequencyForThisWord, bigram.mWord);
+ mTrieBuf[mTriePos++] = (byte) bigramFlags;
+ mTriePos += BinaryDictEncoderUtils.writeChildrenPosition(mTrieBuf,
+ mTriePos, Math.abs(offset));
+ }
+ }
+
+ @Override
+ public void writeForwardLinkAddress(int forwardLinkAddress) {
+ mTriePos = BinaryDictEncoderUtils.writeUIntToBuffer(mTrieBuf, mTriePos,
+ forwardLinkAddress, FormatSpec.FORWARD_LINK_ADDRESS_SIZE);
+ }
+
+ @Override
+ public void writePtNode(final PtNode ptNode, final int parentPosition,
+ final FormatOptions formatOptions, final FusionDictionary dict) {
+ writePtNodeFlags(ptNode, parentPosition, formatOptions);
+ writeParentPosition(parentPosition, ptNode, formatOptions);
+ writeCharacters(ptNode.mChars, ptNode.hasSeveralChars());
+ if (ptNode.isTerminal()) {
+ writeTerminalId(ptNode.mTerminalId);
+ writeFrequency(ptNode.mFrequency, ptNode.mTerminalId);
+ }
+ writeChildrenPosition(ptNode, formatOptions);
+ writeShortcuts(ptNode.mShortcutTargets);
+ writeBigrams(ptNode.mBigrams, dict);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
new file mode 100644
index 000000000..0af028a9e
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.personalization;
+
+import android.content.Context;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.compat.ActivityManagerCompatUtils;
+import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.AbstractDictionaryWriter;
+import com.android.inputmethod.latin.ExpandableDictionary;
+import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.ExpandableDictionary.NextWord;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.makedict.DictEncoder;
+import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+// Currently this class is used to implement dynamic prodiction dictionary.
+// TODO: Move to native code.
+public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWriter {
+ private static final String TAG = DynamicPersonalizationDictionaryWriter.class.getSimpleName();
+ /** Maximum number of pairs. Pruning will start when databases goes above this number. */
+ public static final int DEFAULT_MAX_HISTORY_BIGRAMS = 10000;
+ public static final int LOW_MEMORY_MAX_HISTORY_BIGRAMS = 2000;
+
+ /** Any pair being typed or picked */
+ private static final int FREQUENCY_FOR_TYPED = 2;
+
+ private static final int BINARY_DICT_VERSION = 3;
+ private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
+ new FormatSpec.FormatOptions(BINARY_DICT_VERSION, true /* supportsDynamicUpdate */);
+
+ private final UserHistoryDictionaryBigramList mBigramList =
+ new UserHistoryDictionaryBigramList();
+ private final ExpandableDictionary mExpandableDictionary;
+ private final int mMaxHistoryBigrams;
+
+ public DynamicPersonalizationDictionaryWriter(final Context context, final String dictType) {
+ super(context, dictType);
+ mExpandableDictionary = new ExpandableDictionary(dictType);
+ final boolean isLowRamDevice = ActivityManagerCompatUtils.isLowRamDevice(context);
+ mMaxHistoryBigrams = isLowRamDevice ?
+ LOW_MEMORY_MAX_HISTORY_BIGRAMS : DEFAULT_MAX_HISTORY_BIGRAMS;
+ }
+
+ @Override
+ public void clear() {
+ mBigramList.evictAll();
+ mExpandableDictionary.clearDictionary();
+ }
+
+ /**
+ * Adds a word unigram to the fusion dictionary. Call updateBinaryDictionary when all changes
+ * are done to update the binary dictionary.
+ */
+ @Override
+ public void addUnigramWord(final String word, final String shortcutTarget, final int frequency,
+ final boolean isNotAWord) {
+ if (mBigramList.size() > mMaxHistoryBigrams * 2) {
+ // Too many entries: just stop adding new vocabrary and wait next refresh.
+ return;
+ }
+ mExpandableDictionary.addWord(word, shortcutTarget, frequency);
+ mBigramList.addBigram(null, word, (byte)frequency);
+ }
+
+ @Override
+ public void addBigramWords(final String word0, final String word1, final int frequency,
+ final boolean isValid, final long lastModifiedTime) {
+ if (mBigramList.size() > mMaxHistoryBigrams * 2) {
+ // Too many entries: just stop adding new vocabrary and wait next refresh.
+ return;
+ }
+ if (lastModifiedTime > 0) {
+ mExpandableDictionary.setBigramAndGetFrequency(word0, word1,
+ new ForgettingCurveParams(frequency, System.currentTimeMillis(),
+ lastModifiedTime));
+ mBigramList.addBigram(word0, word1, (byte)frequency);
+ } else {
+ mExpandableDictionary.setBigramAndGetFrequency(word0, word1,
+ new ForgettingCurveParams(isValid));
+ mBigramList.addBigram(word0, word1, (byte)frequency);
+ }
+ }
+
+ @Override
+ public void removeBigramWords(final String word0, final String word1) {
+ if (mBigramList.removeBigram(word0, word1)) {
+ mExpandableDictionary.removeBigram(word0, word1);
+ }
+ }
+
+ @Override
+ protected void writeDictionary(final DictEncoder dictEncoder)
+ throws IOException, UnsupportedFormatException {
+ UserHistoryDictIOUtils.writeDictionary(dictEncoder,
+ new FrequencyProvider(mBigramList, mExpandableDictionary, mMaxHistoryBigrams),
+ mBigramList, FORMAT_OPTIONS);
+ }
+
+ private static class FrequencyProvider implements BigramDictionaryInterface {
+ private final UserHistoryDictionaryBigramList mBigramList;
+ private final ExpandableDictionary mExpandableDictionary;
+ private final int mMaxHistoryBigrams;
+
+ public FrequencyProvider(final UserHistoryDictionaryBigramList bigramList,
+ final ExpandableDictionary expandableDictionary, final int maxHistoryBigrams) {
+ mBigramList = bigramList;
+ mExpandableDictionary = expandableDictionary;
+ mMaxHistoryBigrams = maxHistoryBigrams;
+ }
+
+ @Override
+ public int getFrequency(final String word0, final String word1) {
+ final int freq;
+ if (word0 == null) { // unigram
+ freq = FREQUENCY_FOR_TYPED;
+ } else { // bigram
+ final NextWord nw = mExpandableDictionary.getBigramWord(word0, word1);
+ if (nw != null) {
+ final ForgettingCurveParams forgettingCurveParams = nw.getFcParams();
+ final byte prevFc = mBigramList.getBigrams(word0).get(word1);
+ final byte fc = forgettingCurveParams.getFc();
+ final boolean isValid = forgettingCurveParams.isValid();
+ if (prevFc > 0 && prevFc == fc) {
+ freq = fc & 0xFF;
+ } else if (UserHistoryForgettingCurveUtils.
+ needsToSave(fc, isValid, mBigramList.size() <= mMaxHistoryBigrams)) {
+ freq = fc & 0xFF;
+ } else {
+ // Delete this entry
+ freq = -1;
+ }
+ } else {
+ // Delete this entry
+ freq = -1;
+ }
+ }
+ return freq;
+ }
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ return mExpandableDictionary.getSuggestions(composer, prevWord, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions);
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ return mExpandableDictionary.isValidWord(word);
+ }
+
+ @UsedForTesting
+ public boolean isInDictionaryForTests(final String word) {
+ // TODO: Use native method to determine whether the word is in dictionary or not
+ return mBigramList.containsKey(word);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
index bb6ec6b1c..075d7e3c3 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
@@ -18,59 +18,40 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context;
import android.content.SharedPreferences;
-import android.os.AsyncTask;
import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.ExpandableDictionary;
+import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.WordComposer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.DictDecoder;
+import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.settings.Settings;
-import com.android.inputmethod.latin.utils.ByteArrayWrapper;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils;
-import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface;
import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListener;
-import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils;
-import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.concurrent.locks.ReentrantLock;
/**
* This class is a base class of a dictionary for the personalized prediction language model.
*/
-public abstract class DynamicPredictionDictionaryBase extends ExpandableDictionary {
-
+public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDictionary {
private static final String TAG = DynamicPredictionDictionaryBase.class.getSimpleName();
public static final boolean DBG_SAVE_RESTORE = false;
private static final boolean DBG_STRESS_TEST = false;
private static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG;
- private static final FormatOptions VERSION3 = new FormatOptions(3,
- true /* supportsDynamicUpdate */);
-
/** Any pair being typed or picked */
- private static final int FREQUENCY_FOR_TYPED = 2;
-
- /** Maximum number of pairs. Pruning will start when databases goes above this number. */
- private static final int MAX_HISTORY_BIGRAMS = 10000;
+ public static final int FREQUENCY_FOR_TYPED = 2;
/** Locale for which this user history dictionary is storing words */
private final String mLocale;
- private final UserHistoryDictionaryBigramList mBigramList =
- new UserHistoryDictionaryBigramList();
- private final ReentrantLock mBigramListLock = new ReentrantLock();
+ private final String mFileName;
+
private final SharedPreferences mPrefs;
private final ArrayList<PersonalizationDictionaryUpdateSession> mSessions =
@@ -80,41 +61,44 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona
@UsedForTesting boolean mIsTest = false;
/* package */ DynamicPredictionDictionaryBase(final Context context, final String locale,
- final SharedPreferences sp, final String dictionaryType) {
- super(context, dictionaryType);
+ final SharedPreferences sp, final String dictionaryType, final String fileName) {
+ super(context, fileName, dictionaryType, true);
mLocale = locale;
+ mFileName = fileName;
mPrefs = sp;
if (mLocale != null && mLocale.length() > 1) {
- loadDictionary();
+ asyncLoadDictionaryToMemory();
+ reloadDictionaryIfRequired();
}
}
@Override
public void close() {
- flushPendingWrites();
- // Don't close the database as locale changes will require it to be reopened anyway
- // Also, the database is written to somewhat frequently, so it needs to be kept alive
- // throughout the life of the process.
- // mOpenHelper.close();
- // Ignore close because we cache PersonalizationPredictionDictionary for each language.
- // See getInstance() above.
- // super.close();
+ if (!ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ closeBinaryDictionary();
+ }
+ // Flush pending writes.
+ // TODO: Remove after this class become to use a dynamic binary dictionary.
+ asyncFlashAllBinaryDictionary();
+ Settings.writeLastUserHistoryWriteTime(mPrefs, mLocale);
+ }
+
+ @Override
+ protected boolean hasContentChanged() {
+ return false;
}
@Override
- protected ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo) {
- // Inhibit suggestions (not predictions) for user history for now. Removing this method
- // is enough to use it through the standard ExpandableDictionary way.
- return null;
+ protected boolean needsToReloadBeforeWriting() {
+ return false;
}
/**
* Return whether the passed charsequence is in the dictionary.
*/
@Override
- public synchronized boolean isValidWord(final String word) {
- // TODO: figure out what is the correct thing to do here.
+ public boolean isValidWord(final String word) {
+ // Words included only in the user history should be treated as not in dictionary words.
return false;
}
@@ -126,70 +110,29 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona
* context, as in beginning of a sentence for example.
* The second word may not be null (a NullPointerException would be thrown).
*/
- public int addToPersonalizationPredictionDictionary(
- final String word1, final String word2, final boolean isValid) {
- if (word2.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
- (word1 != null && word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
- return -1;
+ public void addToPersonalizationPredictionDictionary(
+ final String word0, final String word1, final boolean isValid) {
+ if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
+ (word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
+ return;
}
- if (mBigramListLock.tryLock()) {
- try {
- super.addWord(
- word2, null /* the "shortcut" parameter is null */, FREQUENCY_FOR_TYPED);
- mBigramList.addBigram(null, word2, (byte)FREQUENCY_FOR_TYPED);
- // Do not insert a word as a bigram of itself
- if (word2.equals(word1)) {
- return 0;
- }
- final int freq;
- if (null == word1) {
- freq = FREQUENCY_FOR_TYPED;
- } else {
- freq = super.setBigramAndGetFrequency(
- word1, word2, new ForgettingCurveParams(isValid));
- }
- mBigramList.addBigram(word1, word2);
- return freq;
- } finally {
- mBigramListLock.unlock();
- }
+ addWordDynamically(word1, null /* the "shortcut" parameter is null */, FREQUENCY_FOR_TYPED,
+ false /* isNotAWord */);
+ // Do not insert a word as a bigram of itself
+ if (word1.equals(word0)) {
+ return;
}
- return -1;
- }
-
- public boolean cancelAddingUserHistory(final String word1, final String word2) {
- if (mBigramListLock.tryLock()) {
- try {
- if (mBigramList.removeBigram(word1, word2)) {
- return super.removeBigram(word1, word2);
- }
- } finally {
- mBigramListLock.unlock();
- }
+ if (null != word0) {
+ addBigramDynamically(word0, word1, FREQUENCY_FOR_TYPED, isValid);
}
- return false;
}
- /**
- * Schedules a background thread to write any pending words to the database.
- */
- private void flushPendingWrites() {
- // Create a background thread to write the pending entries
- new UpdateBinaryTask(mBigramList, mLocale, this, mPrefs, getContext()).execute();
+ public void cancelAddingUserHistory(final String word0, final String word1) {
+ removeBigramDynamically(word0, word1);
}
@Override
- public final void loadDictionaryAsync() {
- // This must be run on non-main thread
- mBigramListLock.lock();
- try {
- loadDictionaryAsyncLocked();
- } finally {
- mBigramListLock.unlock();
- }
- }
-
- private void loadDictionaryAsyncLocked() {
+ protected void loadDictionaryAsync() {
final int[] profTotalCount = { 0 };
final String locale = getLocale();
if (DBG_STRESS_TEST) {
@@ -201,10 +144,8 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona
}
}
final long last = Settings.readLastUserHistoryWriteTime(mPrefs, locale);
- final boolean initializing = last == 0;
final long now = System.currentTimeMillis();
- final String fileName = getDictionaryFileName();
- final ExpandableDictionary dictionary = this;
+ final ExpandableBinaryDictionary dictionary = this;
final OnAddWordListener listener = new OnAddWordListener() {
@Override
public void setUnigram(final String word, final String shortcutTarget,
@@ -212,49 +153,39 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona
if (DBG_SAVE_RESTORE) {
Log.d(TAG, "load unigram: " + word + "," + frequency);
}
- dictionary.addWord(word, shortcutTarget, frequency);
+ addWord(word, shortcutTarget, frequency, false /* isNotAWord */);
++profTotalCount[0];
- addToBigramListLocked(null, word, (byte)frequency);
}
@Override
- public void setBigram(final String word1, final String word2, final int frequency) {
- if (word1.length() < Constants.DICTIONARY_MAX_WORD_LENGTH
- && word2.length() < Constants.DICTIONARY_MAX_WORD_LENGTH) {
+ public void setBigram(final String word0, final String word1, final int frequency) {
+ if (word0.length() < Constants.DICTIONARY_MAX_WORD_LENGTH
+ && word1.length() < Constants.DICTIONARY_MAX_WORD_LENGTH) {
if (DBG_SAVE_RESTORE) {
- Log.d(TAG, "load bigram: " + word1 + "," + word2 + "," + frequency);
+ Log.d(TAG, "load bigram: " + word0 + "," + word1 + "," + frequency);
}
++profTotalCount[0];
- dictionary.setBigramAndGetFrequency(
- word1, word2, initializing ? new ForgettingCurveParams(true)
- : new ForgettingCurveParams(frequency, now, last));
+ addBigram(word0, word1, frequency, last);
}
- addToBigramListLocked(word1, word2, (byte)frequency);
}
};
// Load the dictionary from binary file
- FileInputStream inStream = null;
- try {
- final File file = new File(getContext().getFilesDir(), fileName);
- final byte[] buffer = new byte[(int)file.length()];
- inStream = new FileInputStream(file);
- inStream.read(buffer);
- UserHistoryDictIOUtils.readDictionaryBinary(
- new ByteArrayWrapper(buffer), listener);
- } catch (FileNotFoundException e) {
+ final File dictFile = new File(mContext.getFilesDir(), mFileName);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile,
+ DictDecoder.USE_BYTEARRAY);
+ if (dictDecoder == null) {
// This is an expected condition: we don't have a user history dictionary for this
// language yet. It will be created sometime later.
+ return;
+ }
+
+ try {
+ dictDecoder.openDictBuffer();
+ UserHistoryDictIOUtils.readDictionaryBinary(dictDecoder, listener);
} catch (IOException e) {
- Log.e(TAG, "IOException on opening a bytebuffer", e);
+ Log.d(TAG, "IOException on opening a bytebuffer", e);
} finally {
- if (inStream != null) {
- try {
- inStream.close();
- } catch (IOException e) {
- // do nothing
- }
- }
if (PROFILE_SAVE_RESTORE) {
final long diff = System.currentTimeMillis() - now;
Log.d(TAG, "PROF: Load UserHistoryDictionary: "
@@ -263,146 +194,24 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableDictiona
}
}
- protected abstract String getDictionaryFileName();
-
protected String getLocale() {
return mLocale;
}
- private void addToBigramListLocked(String word0, String word1, byte fcValue) {
- mBigramList.addBigram(word0, word1, fcValue);
- }
-
- /**
- * Async task to write pending words to the binarydicts.
- */
- private static final class UpdateBinaryTask extends AsyncTask<Void, Void, Void>
- implements BigramDictionaryInterface {
- private final UserHistoryDictionaryBigramList mBigramList;
- private final boolean mAddLevel0Bigrams;
- private final String mLocale;
- private final DynamicPredictionDictionaryBase mDynamicPredictionDictionary;
- private final SharedPreferences mPrefs;
- private final Context mContext;
-
- public UpdateBinaryTask(final UserHistoryDictionaryBigramList pendingWrites,
- final String locale, final DynamicPredictionDictionaryBase dict,
- final SharedPreferences prefs, final Context context) {
- mBigramList = pendingWrites;
- mLocale = locale;
- mDynamicPredictionDictionary = dict;
- mPrefs = prefs;
- mContext = context;
- mAddLevel0Bigrams = mBigramList.size() <= MAX_HISTORY_BIGRAMS;
- }
-
- @Override
- protected Void doInBackground(final Void... v) {
- if (mDynamicPredictionDictionary.mIsTest) {
- // If mIsTest == true, wait until the lock is released.
- mDynamicPredictionDictionary.mBigramListLock.lock();
- try {
- doWriteTaskLocked();
- } finally {
- mDynamicPredictionDictionary.mBigramListLock.unlock();
- }
- } else if (mDynamicPredictionDictionary.mBigramListLock.tryLock()) {
- try {
- doWriteTaskLocked();
- } finally {
- mDynamicPredictionDictionary.mBigramListLock.unlock();
- }
- }
- return null;
- }
-
- private void doWriteTaskLocked() {
- if (DBG_STRESS_TEST) {
- try {
- Log.w(TAG, "Start stress in closing: " + mLocale);
- Thread.sleep(15000);
- Log.w(TAG, "End stress in closing");
- } catch (InterruptedException e) {
- Log.e(TAG, "In stress test", e);
- }
- }
-
- final long now = PROFILE_SAVE_RESTORE ? System.currentTimeMillis() : 0;
- final String fileName =
- mDynamicPredictionDictionary.getDictionaryFileName();
- final File file = new File(mContext.getFilesDir(), fileName);
- FileOutputStream out = null;
-
- try {
- out = new FileOutputStream(file);
- UserHistoryDictIOUtils.writeDictionaryBinary(out, this, mBigramList, VERSION3);
- out.flush();
- out.close();
- } catch (IOException e) {
- Log.e(TAG, "IO Exception while writing file", e);
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (IOException e) {
- // ignore
- }
- }
- }
-
- // Save the timestamp after we finish writing the binary dictionary.
- Settings.writeLastUserHistoryWriteTime(mPrefs, mLocale);
- if (PROFILE_SAVE_RESTORE) {
- final long diff = System.currentTimeMillis() - now;
- Log.w(TAG, "PROF: Write User HistoryDictionary: " + mLocale + ", " + diff + "ms.");
- }
- }
-
- @Override
- public int getFrequency(final String word1, final String word2) {
- final int freq;
- if (word1 == null) { // unigram
- freq = FREQUENCY_FOR_TYPED;
- final byte prevFc = mBigramList.getBigrams(word1).get(word2);
- } else { // bigram
- final NextWord nw =
- mDynamicPredictionDictionary.getBigramWord(word1, word2);
- if (nw != null) {
- final ForgettingCurveParams fcp = nw.getFcParams();
- final byte prevFc = mBigramList.getBigrams(word1).get(word2);
- final byte fc = fcp.getFc();
- final boolean isValid = fcp.isValid();
- if (prevFc > 0 && prevFc == fc) {
- freq = fc & 0xFF;
- } else if (UserHistoryForgettingCurveUtils.
- needsToSave(fc, isValid, mAddLevel0Bigrams)) {
- freq = fc & 0xFF;
- } else {
- // Delete this entry
- freq = -1;
- }
- } else {
- // Delete this entry
- freq = -1;
- }
- }
- return freq;
- }
+ public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
+ session.setPredictionDictionary(this);
+ mSessions.add(session);
+ session.onDictionaryReady();
}
- @UsedForTesting
- /* package for test */ void forceAddWordForTest(
- final String word1, final String word2, final boolean isValid) {
- mBigramListLock.lock();
- try {
- addToPersonalizationPredictionDictionary(word1, word2, isValid);
- } finally {
- mBigramListLock.unlock();
- }
+ public void unRegisterUpdateSession(PersonalizationDictionaryUpdateSession session) {
+ mSessions.remove(session);
}
- public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
- session.setDictionary(this);
- mSessions.add(session);
+ public void clearAndFlushDictionary() {
+ // Clear the node structure on memory
+ clear();
+ // Then flush the cleared state of the dictionary on disk.
+ asyncFlashAllBinaryDictionary();
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
index e38a235e9..f257165cb 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
@@ -18,26 +18,32 @@ package com.android.inputmethod.latin.personalization;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
+import com.android.inputmethod.latin.utils.CollectionUtils;
import android.content.Context;
+import android.content.SharedPreferences;
+
+import java.util.ArrayList;
/**
* This class is a dictionary for the personalized language model that uses binary dictionary.
*/
public class PersonalizationDictionary extends ExpandableBinaryDictionary {
private static final String NAME = "personalization";
-
- public static void registerUpdateListener(PersonalizationDictionaryUpdateSession listener) {
- // TODO: Implement
- }
+ private final ArrayList<PersonalizationDictionaryUpdateSession> mSessions =
+ CollectionUtils.newArrayList();
/** Locale for which this user history dictionary is storing words */
private final String mLocale;
- // Singleton
- private PersonalizationDictionary(final Context context, final String locale) {
- super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_PERSONALIZATION);
+ public PersonalizationDictionary(final Context context, final String locale,
+ final SharedPreferences prefs) {
+ // TODO: Make isUpdatable true.
+ super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_PERSONALIZATION,
+ false /* isUpdatable */);
mLocale = locale;
+ // TODO: Restore last updated time
+ loadDictionary();
}
@Override
@@ -47,15 +53,21 @@ public class PersonalizationDictionary extends ExpandableBinaryDictionary {
@Override
protected boolean hasContentChanged() {
- // TODO: Implement
return false;
}
@Override
protected boolean needsToReloadBeforeWriting() {
- // TODO: Implement
return false;
}
- // TODO: Implement
+ public void registerUpdateSession(PersonalizationDictionaryUpdateSession session) {
+ session.setDictionary(this);
+ mSessions.add(session);
+ session.onDictionaryReady();
+ }
+
+ public void unRegisterUpdateSession(PersonalizationDictionaryUpdateSession session) {
+ mSessions.remove(session);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegister.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegister.java
new file mode 100644
index 000000000..c1833ff14
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegister.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.personalization;
+
+import android.content.Context;
+import android.content.res.Configuration;
+
+public class PersonalizationDictionarySessionRegister {
+ public static void init(Context context) {
+ }
+
+ public static void onConfigurationChanged(final Context context, final Configuration conf) {
+ }
+
+ public static void onUpdateData(Context context, String type) {
+ }
+
+ public static void onRemoveData(Context context, String type) {
+ }
+
+ public static void onDestroy(Context context) {
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java
index d62aec19d..ab3de801c 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryUpdateSession.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.latin.personalization;
+import android.content.Context;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -43,18 +45,78 @@ public abstract class PersonalizationDictionaryUpdateSession {
}
// TODO: Use a dynamic binary dictionary instead
- public WeakReference<DynamicPredictionDictionaryBase> mDictionary;
+ public WeakReference<PersonalizationDictionary> mDictionary;
+ public WeakReference<DynamicPredictionDictionaryBase> mPredictionDictionary;
+ public final String mSystemLocale;
+ public PersonalizationDictionaryUpdateSession(String locale) {
+ mSystemLocale = locale;
+ }
public abstract void onDictionaryReady();
- public void setDictionary(DynamicPredictionDictionaryBase dictionary) {
- mDictionary = new WeakReference<DynamicPredictionDictionaryBase>(dictionary);
+ public abstract void onDictionaryClosed(Context context);
+
+ public void setDictionary(PersonalizationDictionary dictionary) {
+ mDictionary = new WeakReference<PersonalizationDictionary>(dictionary);
+ }
+
+ public void setPredictionDictionary(DynamicPredictionDictionaryBase dictionary) {
+ mPredictionDictionary = new WeakReference<DynamicPredictionDictionaryBase>(dictionary);
+ }
+
+ protected PersonalizationDictionary getDictionary() {
+ return mDictionary == null ? null : mDictionary.get();
+ }
+
+ protected DynamicPredictionDictionaryBase getPredictionDictionary() {
+ return mPredictionDictionary == null ? null : mPredictionDictionary.get();
+ }
+
+ private void unsetDictionary() {
+ final PersonalizationDictionary dictionary = getDictionary();
+ if (dictionary == null) {
+ return;
+ }
+ dictionary.unRegisterUpdateSession(this);
+ }
+
+ private void unsetPredictionDictionary() {
+ final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ if (dictionary == null) {
+ return;
+ }
+ dictionary.unRegisterUpdateSession(this);
+ }
+
+ public void clearAndFlushPredictionDictionary(Context context) {
+ final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ if (dictionary == null) {
+ return;
+ }
+ dictionary.clearAndFlushDictionary();
+ }
+
+ public void closeSession(Context context) {
+ unsetDictionary();
+ unsetPredictionDictionary();
+ onDictionaryClosed(context);
+ }
+
+ // TODO: Support multi locale to add bigram
+ public void addBigramToPersonalizationDictionary(String word0, String word1, boolean isValid,
+ int frequency) {
+ final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
+ if (dictionary == null) {
+ return;
+ }
+ dictionary.addToPersonalizationPredictionDictionary(word0, word1, isValid);
}
- public void addToPersonalizationDictionary(
+ // Bulk import
+ // TODO: Support multi locale to add bigram
+ public void addBigramsToPersonalizationDictionary(
final ArrayList<PersonalizationLanguageModelParam> lmParams) {
- final DynamicPredictionDictionaryBase dictionary = mDictionary == null
- ? null : mDictionary.get();
+ final DynamicPredictionDictionaryBase dictionary = getPredictionDictionary();
if (dictionary == null) {
return;
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index da256f827..5f702ee3f 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -26,16 +26,20 @@ import android.util.Log;
import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;
-public class PersonalizationDictionaryHelper {
- private static final String TAG = PersonalizationDictionaryHelper.class.getSimpleName();
+public class PersonalizationHelper {
+ private static final String TAG = PersonalizationHelper.class.getSimpleName();
private static final boolean DEBUG = false;
private static final ConcurrentHashMap<String, SoftReference<UserHistoryPredictionDictionary>>
sLangUserHistoryDictCache = CollectionUtils.newConcurrentHashMap();
+ private static final ConcurrentHashMap<String, SoftReference<PersonalizationDictionary>>
+ sLangPersonalizationDictCache = CollectionUtils.newConcurrentHashMap();
+
private static final ConcurrentHashMap<String,
SoftReference<PersonalizationPredictionDictionary>>
- sLangPersonalizationDictCache = CollectionUtils.newConcurrentHashMap();
+ sLangPersonalizationPredictionDictCache =
+ CollectionUtils.newConcurrentHashMap();
public static UserHistoryPredictionDictionary getUserHistoryPredictionDictionary(
final Context context, final String locale, final SharedPreferences sp) {
@@ -48,6 +52,7 @@ public class PersonalizationDictionaryHelper {
if (DEBUG) {
Log.w(TAG, "Use cached UserHistoryPredictionDictionary for " + locale);
}
+ dict.reloadDictionaryIfRequired();
return dict;
}
}
@@ -59,22 +64,46 @@ public class PersonalizationDictionaryHelper {
}
}
- public static void
- registerPersonalizationDictionaryUpdateSession(final Context context,
- final PersonalizationDictionaryUpdateSession session) {
- final PersonalizationPredictionDictionary dictionary =
- getPersonalizationPredictionDictionary(context,
- context.getResources().getConfiguration().locale.toString(),
+ public static void registerPersonalizationDictionaryUpdateSession(final Context context,
+ final PersonalizationDictionaryUpdateSession session, String locale) {
+ final PersonalizationPredictionDictionary predictionDictionary =
+ getPersonalizationPredictionDictionary(context, locale,
+ PreferenceManager.getDefaultSharedPreferences(context));
+ predictionDictionary.registerUpdateSession(session);
+ final PersonalizationDictionary dictionary =
+ getPersonalizationDictionary(context, locale,
PreferenceManager.getDefaultSharedPreferences(context));
dictionary.registerUpdateSession(session);
}
- public static PersonalizationPredictionDictionary getPersonalizationPredictionDictionary(
+ public static PersonalizationDictionary getPersonalizationDictionary(
final Context context, final String locale, final SharedPreferences sp) {
synchronized (sLangPersonalizationDictCache) {
if (sLangPersonalizationDictCache.containsKey(locale)) {
- final SoftReference<PersonalizationPredictionDictionary> ref =
+ final SoftReference<PersonalizationDictionary> ref =
sLangPersonalizationDictCache.get(locale);
+ final PersonalizationDictionary dict = ref == null ? null : ref.get();
+ if (dict != null) {
+ if (DEBUG) {
+ Log.w(TAG, "Use cached PersonalizationDictCache for " + locale);
+ }
+ return dict;
+ }
+ }
+ final PersonalizationDictionary dict =
+ new PersonalizationDictionary(context, locale, sp);
+ sLangPersonalizationDictCache.put(
+ locale, new SoftReference<PersonalizationDictionary>(dict));
+ return dict;
+ }
+ }
+
+ public static PersonalizationPredictionDictionary getPersonalizationPredictionDictionary(
+ final Context context, final String locale, final SharedPreferences sp) {
+ synchronized (sLangPersonalizationPredictionDictCache) {
+ if (sLangPersonalizationPredictionDictCache.containsKey(locale)) {
+ final SoftReference<PersonalizationPredictionDictionary> ref =
+ sLangPersonalizationPredictionDictCache.get(locale);
final PersonalizationPredictionDictionary dict = ref == null ? null : ref.get();
if (dict != null) {
if (DEBUG) {
@@ -85,7 +114,7 @@ public class PersonalizationDictionaryHelper {
}
final PersonalizationPredictionDictionary dict =
new PersonalizationPredictionDictionary(context, locale, sp);
- sLangPersonalizationDictCache.put(
+ sLangPersonalizationPredictionDictCache.put(
locale, new SoftReference<PersonalizationPredictionDictionary>(dict));
return dict;
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
index 955bd2762..e80953c05 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationPredictionDictionary.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin.personalization;
import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import android.content.Context;
import android.content.SharedPreferences;
@@ -26,11 +27,11 @@ public class PersonalizationPredictionDictionary extends DynamicPredictionDictio
/* package */ PersonalizationPredictionDictionary(final Context context, final String locale,
final SharedPreferences sp) {
- super(context, locale, sp, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA);
+ super(context, locale, sp, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA,
+ getDictionaryFileName(locale));
}
- @Override
- protected String getDictionaryFileName() {
- return NAME + "." + getLocale() + ".dict";
+ private static String getDictionaryFileName(final String locale) {
+ return NAME + "." + locale + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
index f21db25a6..4c1803bdf 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryBigramList.java
@@ -45,6 +45,7 @@ public final class UserHistoryDictionaryBigramList {
/**
* Called when the user typed a word.
*/
+ @UsedForTesting
public void addBigram(String word1, String word2) {
addBigram(word1, word2, FORGETTING_CURVE_INITIAL_VALUE);
}
@@ -53,7 +54,7 @@ public final class UserHistoryDictionaryBigramList {
* Called when loaded from the SQL DB.
*/
public void addBigram(String word1, String word2, byte fcValue) {
- if (UserHistoryPredictionDictionary.DBG_SAVE_RESTORE) {
+ if (DynamicPredictionDictionaryBase.DBG_SAVE_RESTORE) {
Log.d(TAG, "--- add bigram: " + word1 + ", " + word2 + ", " + fcValue);
}
final HashMap<String, Byte> map;
@@ -73,7 +74,7 @@ public final class UserHistoryDictionaryBigramList {
* Called when inserted to the SQL DB.
*/
public void updateBigram(String word1, String word2, byte fcValue) {
- if (UserHistoryPredictionDictionary.DBG_SAVE_RESTORE) {
+ if (DynamicPredictionDictionaryBase.DBG_SAVE_RESTORE) {
Log.d(TAG, "--- update bigram: " + word1 + ", " + word2 + ", " + fcValue);
}
final HashMap<String, Byte> map;
@@ -96,6 +97,10 @@ public final class UserHistoryDictionaryBigramList {
return mBigramMap.isEmpty();
}
+ public boolean containsKey(String word) {
+ return mBigramMap.containsKey(word);
+ }
+
public Set<String> keySet() {
return mBigramMap.keySet();
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java
index d11784454..b140c919b 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryPredictionDictionary.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin.personalization;
import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import android.content.Context;
import android.content.SharedPreferences;
@@ -26,14 +27,14 @@ import android.content.SharedPreferences;
* cancellation or manual picks. This allows the keyboard to adapt to the typist over time.
*/
public class UserHistoryPredictionDictionary extends DynamicPredictionDictionaryBase {
- private static final String NAME = UserHistoryPredictionDictionary.class.getSimpleName();
+ /* package for tests */ static final String NAME =
+ UserHistoryPredictionDictionary.class.getSimpleName();
/* package */ UserHistoryPredictionDictionary(final Context context, final String locale,
final SharedPreferences sp) {
- super(context, locale, sp, Dictionary.TYPE_USER_HISTORY);
+ super(context, locale, sp, Dictionary.TYPE_USER_HISTORY, getDictionaryFileName(locale));
}
- @Override
- protected String getDictionaryFileName() {
- return NAME + "." + getLocale() + ".dict";
+ private static String getDictionaryFileName(final String locale) {
+ return NAME + "." + locale + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java b/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
index 139f5e290..6543003e8 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
@@ -40,8 +40,4 @@ public class AdditionalFeaturesSettingUtils {
final SharedPreferences prefs, final int[] additionalFeaturesPreferences) {
// do nothing.
}
-
- public static int[] getAdditionalNativeSuggestOptions() {
- return Settings.getInstance().getCurrent().mAdditionalFeaturesSettingValues;
- }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index b1cd88729..1b592b565 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -39,6 +39,8 @@ public final class DebugSettings extends PreferenceFragment
public static final String PREF_STATISTICS_LOGGING = "enable_logging";
public static final String PREF_USE_ONLY_PERSONALIZATION_DICTIONARY_FOR_DEBUG =
"use_only_personalization_dictionary_for_debug";
+ public static final String PREF_BOOST_PERSONALIZATION_DICTIONARY_FOR_DEBUG =
+ "boost_personalization_dictionary_for_debug";
private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary";
private static final boolean SHOW_STATISTICS_LOGGING = false;
diff --git a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
index 878c505bd..cd726c969 100644
--- a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
+++ b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
@@ -34,6 +34,9 @@ public class NativeSuggestOptions {
}
public void setAdditionalFeaturesOptions(final int[] additionalOptions) {
+ if (additionalOptions == null) {
+ return;
+ }
for (int i = 0; i < additionalOptions.length; i++) {
setIntegerOption(OPTIONS_SIZE + i, additionalOptions[i]);
}
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index d432087d3..1a0fecc62 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -27,10 +27,10 @@ import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
import com.android.inputmethod.latin.InputAttributes;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
-import com.android.inputmethod.latin.utils.DebugLogUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.RunInLocale;
+import com.android.inputmethod.latin.utils.StringUtils;
import java.util.HashMap;
import java.util.Locale;
@@ -44,7 +44,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_VIBRATE_ON = "vibrate_on";
public static final String PREF_SOUND_ON = "sound_on";
public static final String PREF_POPUP_ON = "popup_on";
- public static final String PREF_VOICE_MODE = "voice_mode";
+ // PREF_VOICE_MODE_OBSOLETE is obsolete. Use PREF_VOICE_INPUT_KEY instead.
+ public static final String PREF_VOICE_MODE_OBSOLETE = "voice_mode";
+ public static final String PREF_VOICE_INPUT_KEY = "pref_voice_input_key";
public static final String PREF_CORRECTION_SETTINGS = "correction_settings";
public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary";
public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
@@ -79,6 +81,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT =
"pref_gesture_floating_preview_text";
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
+ public static final String PREF_PHRASE_GESTURE_ENABLED = "pref_gesture_space_aware";
public static final String PREF_INPUT_LANGUAGE = "input_language";
public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
@@ -90,9 +93,15 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
"pref_suppress_language_switch_key";
+ private static final String PREF_LAST_USED_PERSONALIZATION_TOKEN =
+ "pref_last_used_personalization_token";
public static final String PREF_SEND_FEEDBACK = "send_feedback";
public static final String PREF_ABOUT_KEYBOARD = "about_keyboard";
+ // Emoji
+ public static final String PREF_EMOJI_RECENT_KEYS = "emoji_recent_keys";
+ public static final String PREF_EMOJI_CATEGORY_LAST_TYPED_ID = "emoji_category_last_typed_id";
+
private Resources mRes;
private SharedPreferences mPrefs;
private SettingsValues mSettingsValues;
@@ -212,6 +221,12 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
&& prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true);
}
+ public static boolean readPhraseGestureEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ return prefs.getBoolean(Settings.PREF_PHRASE_GESTURE_ENABLED,
+ res.getBoolean(R.bool.config_default_phrase_gesture_enabled));
+ }
+
public static boolean readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(
final Resources res) {
return res.getBoolean(R.bool.config_enable_show_option_of_key_preview_popup);
@@ -343,4 +358,40 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return prefs.getBoolean(
DebugSettings.PREF_USE_ONLY_PERSONALIZATION_DICTIONARY_FOR_DEBUG, false);
}
+
+ public static boolean readBoostPersonalizationDictionaryForDebug(
+ final SharedPreferences prefs) {
+ return prefs.getBoolean(
+ DebugSettings.PREF_BOOST_PERSONALIZATION_DICTIONARY_FOR_DEBUG, false);
+ }
+
+ public void writeLastUsedPersonalizationToken(byte[] token) {
+ final String tokenStr = StringUtils.byteArrayToHexString(token);
+ mPrefs.edit().putString(PREF_LAST_USED_PERSONALIZATION_TOKEN, tokenStr).apply();
+ }
+
+ public byte[] readLastUsedPersonalizationToken() {
+ final String tokenStr = mPrefs.getString(PREF_LAST_USED_PERSONALIZATION_TOKEN, null);
+ return StringUtils.hexStringToByteArray(tokenStr);
+ }
+
+ public static void writeEmojiRecentKeys(final SharedPreferences prefs, String str) {
+ prefs.edit().putString(PREF_EMOJI_RECENT_KEYS, str).apply();
+ }
+
+ public static String readEmojiRecentKeys(final SharedPreferences prefs) {
+ return prefs.getString(PREF_EMOJI_RECENT_KEYS, "");
+ }
+
+ public static void writeEmojiCategoryLastTypedId(
+ final SharedPreferences prefs, final int category, final int id) {
+ final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + category;
+ prefs.edit().putInt(key, id).apply();
+ }
+
+ public static int readEmojiCategoryLastTypedId(
+ final SharedPreferences prefs, final int category) {
+ final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + category;
+ return prefs.getInt(key, 0);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 446777704..cb7dda655 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -61,7 +61,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment
DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS
|| Build.VERSION.SDK_INT <= 18 /* Build.VERSION.JELLY_BEAN_MR2 */;
- private ListPreference mVoicePreference;
+ private CheckBoxPreference mVoiceInputKeyPreference;
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThresholdPreference;
private ListPreference mKeyPreviewPopupDismissDelay;
@@ -107,7 +107,8 @@ public final class SettingsFragment extends InputMethodSettingsFragment
SubtypeLocaleUtils.init(context);
AudioAndHapticFeedbackManager.init(context);
- mVoicePreference = (ListPreference) findPreference(Settings.PREF_VOICE_MODE);
+ mVoiceInputKeyPreference =
+ (CheckBoxPreference) findPreference(Settings.PREF_VOICE_INPUT_KEY);
mShowCorrectionSuggestionsPreference =
(ListPreference) findPreference(Settings.PREF_SHOW_SUGGESTIONS_SETTING);
final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
@@ -166,7 +167,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment
final boolean showVoiceKeyOption = res.getBoolean(
R.bool.config_enable_show_voice_key_option);
if (!showVoiceKeyOption) {
- generalSettings.removePreference(mVoicePreference);
+ generalSettings.removePreference(mVoiceInputKeyPreference);
}
final PreferenceGroup advancedSettings =
@@ -229,10 +230,10 @@ public final class SettingsFragment extends InputMethodSettingsFragment
if (!Settings.readFromBuildConfigIfGestureInputEnabled(res)) {
removePreference(Settings.PREF_GESTURE_SETTINGS, getPreferenceScreen());
- } else {
- AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(context, this);
}
+ AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(context, this);
+
setupKeyLongpressTimeoutSettings(prefs, res);
setupKeypressVibrationDurationSettings(prefs, res);
setupKeypressSoundVolumeSettings(prefs, res);
@@ -243,10 +244,8 @@ public final class SettingsFragment extends InputMethodSettingsFragment
public void onResume() {
super.onResume();
final boolean isShortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
- if (isShortcutImeEnabled) {
- updateVoiceModeSummary();
- } else {
- getPreferenceScreen().removePreference(mVoicePreference);
+ if (!isShortcutImeEnabled) {
+ getPreferenceScreen().removePreference(mVoiceInputKeyPreference);
}
final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
final CheckBoxPreference showSetupWizardIcon =
@@ -287,7 +286,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
LauncherIconVisibilityManager.updateSetupWizardIconVisibility(getActivity());
}
ensureConsistencyOfAutoCorrectionSettings();
- updateVoiceModeSummary();
updateShowCorrectionSuggestionsSummary();
updateKeyPreviewPopupDelaySummary();
refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources());
@@ -330,12 +328,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
lp.setSummary(entries[lp.findIndexOfValue(lp.getValue())]);
}
- private void updateVoiceModeSummary() {
- mVoicePreference.setSummary(
- getResources().getStringArray(R.array.voice_input_modes_summary)
- [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]);
- }
-
private void refreshEnablingsOfKeypressSoundAndVibrationSettings(
final SharedPreferences sp, final Resources res) {
setPreferenceEnabled(Settings.PREF_VIBRATION_DURATION_SETTINGS,
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index a25cf620c..ee322e91b 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -22,6 +22,7 @@ import android.content.res.Resources;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.internal.KeySpecParser;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.InputAttributes;
@@ -56,13 +57,14 @@ public final class SettingsValues {
public final SuggestedWords mSuggestPuncList;
public final String mWordSeparators;
public final CharSequence mHintToSaveText;
+ public final boolean mCurrentLanguageHasSpaces;
// From preferences, in the same order as xml/prefs.xml:
public final boolean mAutoCap;
public final boolean mVibrateOn;
public final boolean mSoundOn;
public final boolean mKeyPreviewPopupOn;
- private final String mVoiceMode;
+ private final boolean mShowsVoiceInputKey;
public final boolean mIncludesOtherImesInLanguageSwitchList;
public final boolean mShowsLanguageSwitchKey;
public final boolean mUseContactsDict;
@@ -74,6 +76,7 @@ public final class SettingsValues {
public final boolean mGestureTrailEnabled;
public final boolean mGestureFloatingPreviewTextEnabled;
public final boolean mSlidingKeyInputPreviewEnabled;
+ public final boolean mPhraseGestureEnabled;
public final int mKeyLongpressTimeout;
public final Locale mLocale;
@@ -88,8 +91,8 @@ public final class SettingsValues {
public final float mAutoCorrectionThreshold;
public final boolean mCorrectionEnabled;
public final int mSuggestionVisibility;
- private final boolean mVoiceKeyEnabled;
- private final boolean mVoiceKeyOnMain;
+ public final boolean mBoostPersonalizationDictionaryForDebug;
+ public final boolean mUseOnlyPersonalizationDictionaryForDebug;
// Setting values for additional features
public final int[] mAdditionalFeaturesSettingValues =
@@ -117,6 +120,7 @@ public final class SettingsValues {
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
mWordSeparators = res.getString(R.string.symbols_word_separators);
mHintToSaveText = res.getText(R.string.hint_add_to_dictionary);
+ mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces);
// Store the input attributes
if (null == inputAttributes) {
@@ -132,9 +136,7 @@ public final class SettingsValues {
mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res);
mSlidingKeyInputPreviewEnabled = prefs.getBoolean(
Settings.PREF_SLIDING_KEY_INPUT_PREVIEW, true);
- final String voiceModeMain = res.getString(R.string.voice_mode_main);
- final String voiceModeOff = res.getString(R.string.voice_mode_off);
- mVoiceMode = prefs.getString(Settings.PREF_VOICE_MODE, voiceModeMain);
+ mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res);
final String autoCorrectionThresholdRawValue = prefs.getString(
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
res.getString(R.string.auto_correction_threshold_mode_index_modest));
@@ -154,12 +156,11 @@ public final class SettingsValues {
mKeyPreviewPopupDismissDelay = Settings.readKeyPreviewPopupDismissDelay(prefs, res);
mAutoCorrectionThreshold = readAutoCorrectionThreshold(res,
autoCorrectionThresholdRawValue);
- mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
- mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
+ mPhraseGestureEnabled = Settings.readPhraseGestureEnabled(prefs, res);
mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
final String showSuggestionsSetting = prefs.getString(
Settings.PREF_SHOW_SUGGESTIONS_SETTING,
@@ -168,6 +169,61 @@ public final class SettingsValues {
AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray(
prefs, mAdditionalFeaturesSettingValues);
mIsInternal = Settings.isInternal(prefs);
+ mBoostPersonalizationDictionaryForDebug =
+ Settings.readBoostPersonalizationDictionaryForDebug(prefs);
+ mUseOnlyPersonalizationDictionaryForDebug =
+ Settings.readUseOnlyPersonalizationDictionaryForDebug(prefs);
+ }
+
+ // Only for tests
+ private SettingsValues(final Locale locale) {
+ // TODO: locale is saved, but not used yet. May have to change this if tests require.
+ mLocale = locale;
+ mDelayUpdateOldSuggestions = 0;
+ mSymbolsPrecededBySpace = new int[] { '(', '[', '{', '&' };
+ Arrays.sort(mSymbolsPrecededBySpace);
+ mSymbolsFollowedBySpace = new int[] { '.', ',', ';', ':', '!', '?', ')', ']', '}', '&' };
+ Arrays.sort(mSymbolsFollowedBySpace);
+ mWordConnectors = new int[] { '\'', '-' };
+ Arrays.sort(mWordConnectors);
+ final String[] suggestPuncsSpec = new String[] { "!", "?", ",", ":", ";" };
+ mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+ mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\"";
+ mHintToSaveText = "Touch again to save";
+ mCurrentLanguageHasSpaces = true;
+ mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
+ mAutoCap = true;
+ mVibrateOn = true;
+ mSoundOn = true;
+ mKeyPreviewPopupOn = true;
+ mSlidingKeyInputPreviewEnabled = true;
+ mShowsVoiceInputKey = true;
+ mIncludesOtherImesInLanguageSwitchList = false;
+ mShowsLanguageSwitchKey = true;
+ mUseContactsDict = true;
+ mUseDoubleSpacePeriod = true;
+ mBlockPotentiallyOffensive = true;
+ mAutoCorrectEnabled = true;
+ mBigramPredictionEnabled = true;
+ mKeyLongpressTimeout = 300;
+ mKeypressVibrationDuration = 5;
+ mKeypressSoundVolume = 1;
+ mKeyPreviewPopupDismissDelay = 70;
+ mAutoCorrectionThreshold = 1;
+ mGestureInputEnabled = true;
+ mGestureTrailEnabled = true;
+ mGestureFloatingPreviewTextEnabled = true;
+ mPhraseGestureEnabled = true;
+ mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
+ mSuggestionVisibility = 0;
+ mIsInternal = false;
+ mBoostPersonalizationDictionaryForDebug = false;
+ mUseOnlyPersonalizationDictionaryForDebug = false;
+ }
+
+ @UsedForTesting
+ public static SettingsValues makeDummySettingsValuesForTest(final Locale locale) {
+ return new SettingsValues(locale);
}
public boolean isApplicationSpecifiedCompletionsOn() {
@@ -194,6 +250,10 @@ public final class SettingsValues {
return Arrays.binarySearch(mWordConnectors, code) >= 0;
}
+ public boolean isWordCodePoint(final int code) {
+ return Character.isLetter(code) || isWordConnector(code);
+ }
+
public boolean isUsuallyPrecededBySpace(final int code) {
return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
}
@@ -209,14 +269,10 @@ public final class SettingsValues {
public boolean isVoiceKeyEnabled(final EditorInfo editorInfo) {
final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
- return shortcutImeEnabled && mVoiceKeyEnabled
+ return shortcutImeEnabled && mShowsVoiceInputKey
&& !InputTypeUtils.isPasswordInputType(inputType);
}
- public boolean isVoiceKeyOnMain() {
- return mVoiceKeyOnMain;
- }
-
public boolean isLanguageSwitchKeyEnabled() {
if (!mShowsLanguageSwitchKey) {
return false;
@@ -241,7 +297,9 @@ public final class SettingsValues {
// TODO: Stop using KeySpceParser.getLabel().
puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec),
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED,
- Dictionary.TYPE_HARDCODED));
+ Dictionary.DICTIONARY_HARDCODED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
}
}
return new SuggestedWords(puncList,
@@ -306,4 +364,18 @@ public final class SettingsValues {
}
return autoCorrectionThreshold;
}
+
+ private static boolean needsToShowVoiceInputKey(SharedPreferences prefs, Resources res) {
+ final String voiceModeMain = res.getString(R.string.voice_mode_main);
+ final String voiceMode = prefs.getString(Settings.PREF_VOICE_MODE_OBSOLETE, voiceModeMain);
+ final boolean showsVoiceInputKey = voiceMode == null || voiceMode.equals(voiceModeMain);
+ if (!showsVoiceInputKey) {
+ // Migrate settings from PREF_VOICE_MODE_OBSOLETE to PREF_VOICE_INPUT_KEY
+ // Set voiceModeMain as a value of obsolete voice mode settings.
+ prefs.edit().putString(Settings.PREF_VOICE_MODE_OBSOLETE, voiceModeMain).apply();
+ // Disable voice input key.
+ prefs.edit().putBoolean(Settings.PREF_VOICE_INPUT_KEY, false).apply();
+ }
+ return prefs.getBoolean(Settings.PREF_VOICE_INPUT_KEY, true);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 6719e98da..69f9a467f 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -301,12 +301,14 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
// TODO: make a spell checker option to block offensive words or not
final ArrayList<SuggestedWordInfo> suggestions =
dictInfo.mDictionary.getSuggestions(composer, prevWord,
- dictInfo.getProximityInfo(),
- true /* blockOffensiveWords */);
- for (final SuggestedWordInfo suggestion : suggestions) {
- final String suggestionStr = suggestion.mWord;
- suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
- suggestionStr.length(), suggestion.mScore);
+ dictInfo.getProximityInfo(), true /* blockOffensiveWords */,
+ null /* additionalFeaturesOptions */);
+ if (suggestions != null) {
+ for (final SuggestedWordInfo suggestion : suggestions) {
+ final String suggestionStr = suggestion.mWord;
+ suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
+ suggestionStr.length(), suggestion.mScore);
+ }
}
isInDict = isInDictForAnyCapitalization(dictInfo.mDictionary, text, capitalizeType);
} finally {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index ac8f68781..a0aed2829 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -52,7 +52,7 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> {
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
return noSuggestions;
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index e97069dff..acd47450b 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -210,7 +210,8 @@ public final class MoreSuggestions extends Keyboard {
final int indexInMoreSuggestions = index + SUGGESTION_CODE_BASE;
final Key key = new Key(
params, word, info, KeyboardIconsSet.ICON_UNDEFINED, indexInMoreSuggestions,
- null, x, y, width, params.mDefaultRowHeight, 0);
+ null /* outputText */, x, y, width, params.mDefaultRowHeight,
+ 0 /* labelFlags */, Key.BACKGROUND_TYPE_NORMAL);
params.markAsEdgeKey(key, index);
params.onAddKey(key);
final int columnNumber = params.getColumnNumber(index);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index d585b5c7f..0ebe37782 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -34,7 +34,7 @@ public final class MoreSuggestionsView extends MoreKeysKeyboardView {
private static final String TAG = MoreSuggestionsView.class.getSimpleName();
public MoreSuggestionsView(final Context context, final AttributeSet attrs) {
- this(context, attrs, R.attr.moreSuggestionsViewStyle);
+ this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
public MoreSuggestionsView(final Context context, final AttributeSet attrs,
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 1dd04fc4d..8d2689a7d 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -122,27 +122,15 @@ final class SuggestionStripLayoutHelper {
mSuggestionsStripHeight = res.getDimensionPixelSize(R.dimen.suggestions_strip_height);
final TypedArray a = context.obtainStyledAttributes(attrs,
- R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripViewStyle);
+ R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripView);
mSuggestionStripOption = a.getInt(
R.styleable.SuggestionStripView_suggestionStripOption, 0);
- final float alphaValidTypedWord = ResourceUtils.getFraction(a,
- R.styleable.SuggestionStripView_alphaValidTypedWord, 1.0f);
- final float alphaTypedWord = ResourceUtils.getFraction(a,
- R.styleable.SuggestionStripView_alphaTypedWord, 1.0f);
- final float alphaAutoCorrect = ResourceUtils.getFraction(a,
- R.styleable.SuggestionStripView_alphaAutoCorrect, 1.0f);
- final float alphaSuggested = ResourceUtils.getFraction(a,
- R.styleable.SuggestionStripView_alphaSuggested, 1.0f);
mAlphaObsoleted = ResourceUtils.getFraction(a,
- R.styleable.SuggestionStripView_alphaSuggested, 1.0f);
- mColorValidTypedWord = applyAlpha(a.getColor(
- R.styleable.SuggestionStripView_colorValidTypedWord, 0), alphaValidTypedWord);
- mColorTypedWord = applyAlpha(a.getColor(
- R.styleable.SuggestionStripView_colorTypedWord, 0), alphaTypedWord);
- mColorAutoCorrect = applyAlpha(a.getColor(
- R.styleable.SuggestionStripView_colorAutoCorrect, 0), alphaAutoCorrect);
- mColorSuggested = applyAlpha(a.getColor(
- R.styleable.SuggestionStripView_colorSuggested, 0), alphaSuggested);
+ R.styleable.SuggestionStripView_alphaObsoleted, 1.0f);
+ mColorValidTypedWord = a.getColor(R.styleable.SuggestionStripView_colorValidTypedWord, 0);
+ mColorTypedWord = a.getColor(R.styleable.SuggestionStripView_colorTypedWord, 0);
+ mColorAutoCorrect = a.getColor(R.styleable.SuggestionStripView_colorAutoCorrect, 0);
+ mColorSuggested = a.getColor(R.styleable.SuggestionStripView_colorSuggested, 0);
mSuggestionsCountInStrip = a.getInt(
R.styleable.SuggestionStripView_suggestionsCountInStrip,
DEFAULT_SUGGESTIONS_COUNT_IN_STRIP);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index a8a14a825..75f17c559 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -198,7 +198,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override
public boolean onLongClick(final View view) {
- AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(
+ AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
Constants.NOT_A_CODE, this);
return showMoreSuggestions();
}
diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
index 215faa0c7..44b201642 100644
--- a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
@@ -25,6 +25,7 @@ import android.os.Build;
import android.text.TextUtils;
import android.view.inputmethod.InputMethodSubtype;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import java.util.ArrayList;
@@ -60,9 +61,10 @@ public final class AdditionalSubtypeUtils {
StringUtils.appendToCommaSplittableTextIfNotExists(
IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue);
final int nameId = SubtypeLocaleUtils.getSubtypeNameId(localeString, keyboardLayoutSetName);
- return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
- localeString, KEYBOARD_MODE,
- layoutExtraValue + "," + additionalSubtypeExtraValue, false, false);
+ return new InputMethodSubtype(nameId, R.drawable.ic_ime_switcher_dark,
+ localeString, KEYBOARD_MODE, layoutExtraValue + "," + additionalSubtypeExtraValue
+ + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+ + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE, false, false);
}
public static String getPrefSubtype(final InputMethodSubtype subtype) {
diff --git a/java/src/com/android/inputmethod/latin/utils/AsyncResultHolder.java b/java/src/com/android/inputmethod/latin/utils/AsyncResultHolder.java
new file mode 100644
index 000000000..c2e97a36f
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/AsyncResultHolder.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class is a holder of a result of asynchronous computation.
+ *
+ * @param <E> the type of the result.
+ */
+public class AsyncResultHolder<E> {
+
+ private final Object mLock = new Object();
+
+ private E mResult;
+ private final CountDownLatch mLatch;
+
+ public AsyncResultHolder() {
+ mLatch = new CountDownLatch(1);
+ }
+
+ /**
+ * Sets the result value to this holder.
+ *
+ * @param result the value which is set.
+ */
+ public void set(final E result) {
+ synchronized(mLock) {
+ if (mLatch.getCount() > 0) {
+ mResult = result;
+ mLatch.countDown();
+ }
+ }
+ }
+
+ /**
+ * Gets the result value held in this holder.
+ * Causes the current thread to wait unless the value is set or the specified time is elapsed.
+ *
+ * @param defaultValue the default value.
+ * @param timeOut the time to wait.
+ * @return if the result is set until the time limit then the result, otherwise defaultValue.
+ */
+ public E get(final E defaultValue, final long timeOut) {
+ try {
+ if(mLatch.await(timeOut, TimeUnit.MILLISECONDS)) {
+ return mResult;
+ } else {
+ return defaultValue;
+ }
+ } catch (InterruptedException e) {
+ return defaultValue;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/ByteArrayWrapper.java b/java/src/com/android/inputmethod/latin/utils/ByteArrayDictBuffer.java
index 1bb27aa2b..2028298f2 100644
--- a/java/src/com/android/inputmethod/latin/utils/ByteArrayWrapper.java
+++ b/java/src/com/android/inputmethod/latin/utils/ByteArrayDictBuffer.java
@@ -16,17 +16,17 @@
package com.android.inputmethod.latin.utils;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
/**
* This class provides an implementation for the FusionDictionary buffer interface that is backed
* by a simpled byte array. It allows to create a binary dictionary in memory.
*/
-public final class ByteArrayWrapper implements FusionDictionaryBufferInterface {
+public final class ByteArrayDictBuffer implements DictBuffer {
private byte[] mBuffer;
private int mPosition;
- public ByteArrayWrapper(final byte[] buffer) {
+ public ByteArrayDictBuffer(final byte[] buffer) {
mBuffer = buffer;
mPosition = 0;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
index 2f91c5743..60b24d5d5 100644
--- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
@@ -60,6 +60,11 @@ public final class CapsModeUtils {
|| WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode;
}
+ private static boolean isPeriod(final int codePoint) {
+ // TODO: make this a resource.
+ return codePoint == Constants.CODE_PERIOD || codePoint == Constants.CODE_ARMENIAN_PERIOD;
+ }
+
/**
* Determine what caps mode should be in effect at the current offset in
* the text. Only the mode bits set in <var>reqModes</var> will be
@@ -190,7 +195,7 @@ public final class CapsModeUtils {
if (c == Constants.CODE_QUESTION_MARK || c == Constants.CODE_EXCLAMATION_MARK) {
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_SENTENCES) & reqModes;
}
- if (c != Constants.CODE_PERIOD || j <= 0) {
+ if (!isPeriod(c) || j <= 0) {
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
}
@@ -240,7 +245,7 @@ public final class CapsModeUtils {
case WORD:
if (Character.isLetter(c)) {
state = WORD;
- } else if (c == Constants.CODE_PERIOD) {
+ } else if (isPeriod(c)) {
state = PERIOD;
} else {
return caps;
@@ -256,7 +261,7 @@ public final class CapsModeUtils {
case LETTER:
if (Character.isLetter(c)) {
state = LETTER;
- } else if (c == Constants.CODE_PERIOD) {
+ } else if (isPeriod(c)) {
state = PERIOD;
} else {
return noCaps;
diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
index 98f0d8b68..cc25102ce 100644
--- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.utils;
import android.util.SparseArray;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -94,6 +95,10 @@ public final class CollectionUtils {
return new CopyOnWriteArrayList<E>(array);
}
+ public static <E> ArrayDeque<E> newArrayDeque() {
+ return new ArrayDeque<E>();
+ }
+
public static <E> SparseArray<E> newSparseArray() {
return new SparseArray<E>();
}
diff --git a/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java b/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java
index c4ead0ad1..ac654fa65 100644
--- a/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java
@@ -65,12 +65,12 @@ public final class DebugLogUtils {
/**
* Get the stack trace contained in an exception as a human-readable string.
- * @param e the exception
+ * @param t the throwable
* @return the human-readable stack trace
*/
- public static String getStackTrace(final Exception e) {
+ public static String getStackTrace(final Throwable t) {
final StringBuilder sb = new StringBuilder();
- final StackTraceElement[] frames = e.getStackTrace();
+ final StackTraceElement[] frames = t.getStackTrace();
for (int j = 0; j < frames.length; ++j) {
sb.append(frames[j].toString() + "\n");
}
diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index 34eccd65b..021bf0825 100644
--- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -27,10 +27,8 @@ import com.android.inputmethod.latin.BinaryDictionaryGetter;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
-import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
@@ -281,13 +279,7 @@ public class DictionaryInfoUtils {
}
public static FileHeader getDictionaryFileHeaderOrNull(final File file) {
- try {
- return BinaryDictIOUtils.getDictionaryFileHeader(file, 0, file.length());
- } catch (UnsupportedFormatException e) {
- return null;
- } catch (IOException e) {
- return null;
- }
+ return BinaryDictIOUtils.getDictionaryFileHeaderOrNull(file, 0, file.length());
}
private static DictionaryInfo createDictionaryInfoFromFileAddress(
diff --git a/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java b/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
deleted file mode 100644
index 1fc7eccc6..000000000
--- a/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.view.inputmethod.EditorInfo;
-
-import com.android.inputmethod.latin.RichInputConnection;
-
-import java.util.Locale;
-
-/**
- * Holder class for data about a word already committed but that may still be edited.
- *
- * When the user chooses to add a word to the user dictionary by pressing the appropriate
- * suggestion, a dialog is presented to give a chance to edit the word before it is actually
- * registered as a user dictionary word. If the word is actually modified, the IME needs to
- * go back and replace the word that was committed with the amended version.
- * The word we need to replace with will only be known after it's actually committed, so
- * the IME needs to take a note of what it has to replace and where it is.
- * This class encapsulates this data.
- */
-public final class PositionalInfoForUserDictPendingAddition {
- final private String mOriginalWord;
- final private int mCursorPos; // Position of the cursor after the word
- final private EditorInfo mEditorInfo; // On what binding this has been added
- final private int mCapitalizedMode;
- private String mActualWordBeingAdded;
-
- public PositionalInfoForUserDictPendingAddition(final String word, final int cursorPos,
- final EditorInfo editorInfo, final int capitalizedMode) {
- mOriginalWord = word;
- mCursorPos = cursorPos;
- mEditorInfo = editorInfo;
- mCapitalizedMode = capitalizedMode;
- }
-
- public void setActualWordBeingAdded(final String actualWordBeingAdded) {
- mActualWordBeingAdded = actualWordBeingAdded;
- }
-
- /**
- * Try to replace the string at the remembered position with the actual word being added.
- *
- * After the user validated the word being added, the IME has to replace the old version
- * (which has been committed in the text view) with the amended version if it's different.
- * This method tries to do that, but may fail because the IME is not yet ready to do so -
- * for example, it is still waiting for the new string, or it is waiting to return to the text
- * view in which the amendment should be made. In these cases, we should keep the data
- * and wait until all conditions are met.
- * This method returns true if the replacement has been successfully made and this data
- * can be forgotten; it returns false if the replacement can't be made yet and we need to
- * keep this until a later time.
- * The IME knows about the actual word being added through a callback called by the
- * user dictionary facility of the device. When this callback comes, the keyboard may still
- * be connected to the edition dialog, or it may have already returned to the original text
- * field. Replacement has to work in both cases.
- * Accordingly, this method is called at two different points in time : upon getting the
- * event that a new word was added to the user dictionary, and upon starting up in a
- * new text field.
- * @param connection The RichInputConnection through which to contact the editor.
- * @param editorInfo Information pertaining to the editor we are currently in.
- * @param currentCursorPosition The current cursor position, for checking purposes.
- * @param locale The locale for changing case, if necessary
- * @return true if the edit has been successfully made, false if we need to try again later
- */
- public boolean tryReplaceWithActualWord(final RichInputConnection connection,
- final EditorInfo editorInfo, final int currentCursorPosition, final Locale locale) {
- // If we still don't know the actual word being added, we need to try again later.
- if (null == mActualWordBeingAdded) return false;
- // The entered text and the registered text were the same anyway : we can
- // return success right away even if focus has not returned yet to the text field we
- // want to amend.
- if (mActualWordBeingAdded.equals(mOriginalWord)) return true;
- // Not the same text field : we need to try again later. This happens when the addition
- // is reported by the user dictionary provider before the focus has moved back to the
- // original text view, so the IME is still in the text view of the dialog and has no way to
- // edit the original text view at this time.
- if (!mEditorInfo.packageName.equals(editorInfo.packageName)
- || mEditorInfo.fieldId != editorInfo.fieldId) {
- return false;
- }
- // Same text field, but not the same cursor position : we give up, so we return success
- // so that it won't be tried again
- if (currentCursorPosition != mCursorPos) return true;
- // We have made all the checks : do the replacement and report success
- // If this was auto-capitalized, we need to restore the case before committing
- final String wordWithCaseFixed = CapsModeUtils.applyAutoCapsMode(mActualWordBeingAdded,
- mCapitalizedMode, locale);
- connection.setComposingRegion(currentCursorPosition - mOriginalWord.length(),
- currentCursorPosition);
- connection.commitText(wordWithCaseFixed, wordWithCaseFixed.length());
- return true;
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
new file mode 100644
index 000000000..5dc0b5893
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * An object that executes submitted tasks using a thread.
+ */
+public class PrioritizedSerialExecutor {
+ public static final String TAG = PrioritizedSerialExecutor.class.getSimpleName();
+
+ private final Object mLock = new Object();
+
+ // The default value of capacities of task queues.
+ private static final int TASK_QUEUE_CAPACITY = 1000;
+ private final Queue<Runnable> mTasks;
+ private final Queue<Runnable> mPrioritizedTasks;
+ private boolean mIsShutdown;
+
+ // The task which is running now.
+ private Runnable mActive;
+
+ public PrioritizedSerialExecutor() {
+ mTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY);
+ mPrioritizedTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY);
+ mIsShutdown = false;
+ }
+
+ /**
+ * Clears all queued tasks.
+ */
+ public void clearAllTasks() {
+ synchronized(mLock) {
+ mTasks.clear();
+ mPrioritizedTasks.clear();
+ }
+ }
+
+ /**
+ * Enqueues the given task into the task queue.
+ * @param r the enqueued task
+ */
+ public void execute(final Runnable r) {
+ synchronized(mLock) {
+ if (!mIsShutdown) {
+ mTasks.offer(r);
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+ }
+ }
+
+ /**
+ * Enqueues the given task into the prioritized task queue.
+ * @param r the enqueued task
+ */
+ public void executePrioritized(final Runnable r) {
+ synchronized(mLock) {
+ if (!mIsShutdown) {
+ mPrioritizedTasks.offer(r);
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+ }
+ }
+
+ private boolean fetchNextTasks() {
+ synchronized(mLock) {
+ mActive = mPrioritizedTasks.poll();
+ if (mActive == null) {
+ mActive = mTasks.poll();
+ }
+ return mActive != null;
+ }
+ }
+
+ private void scheduleNext() {
+ synchronized(mLock) {
+ if (!fetchNextTasks()) {
+ return;
+ }
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ do {
+ synchronized(mLock) {
+ if (mActive != null) {
+ mActive.run();
+ }
+ }
+ } while (fetchNextTasks());
+ } finally {
+ scheduleNext();
+ }
+ }
+ }).start();
+ }
+ }
+
+ public void remove(final Runnable r) {
+ synchronized(mLock) {
+ mTasks.remove(r);
+ mPrioritizedTasks.remove(r);
+ }
+ }
+
+ public void replaceAndExecute(final Runnable oldTask, final Runnable newTask) {
+ synchronized(mLock) {
+ if (oldTask != null) remove(oldTask);
+ execute(newTask);
+ }
+ }
+
+ public void shutdown() {
+ synchronized(mLock) {
+ mIsShutdown = true;
+ }
+ }
+
+ public boolean isTerminated() {
+ synchronized(mLock) {
+ if (!mIsShutdown) {
+ return false;
+ }
+ return mPrioritizedTasks.isEmpty() && mTasks.isEmpty() && mActive == null;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java b/java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java
index 4c7739a7a..7c6fe93ac 100644
--- a/java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java
+++ b/java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java
@@ -132,6 +132,15 @@ public final class ResizableIntArray {
}
}
+ /**
+ * Shift to the left by elementCount, discarding elementCount pointers at the start.
+ * @param elementCount how many elements to shift.
+ */
+ public void shift(final int elementCount) {
+ System.arraycopy(mArray, elementCount, mArray, 0, mLength - elementCount);
+ mLength -= elementCount;
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index 7406d855a..327780ad0 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -16,14 +16,30 @@
package com.android.inputmethod.latin.utils;
-import android.text.TextUtils;
-
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.settings.SettingsValues;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.SpannedString;
+import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Locale;
public final class StringUtils {
+ private static final String TAG = StringUtils.class.getSimpleName();
public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
public static final int CAPITALIZE_FIRST = 1; // First only
public static final int CAPITALIZE_ALL = 2; // All caps
@@ -193,27 +209,56 @@ public final class StringUtils {
}
public static boolean isIdenticalAfterUpcase(final String text) {
- final int len = text.length();
- for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
+ final int length = text.length();
+ int i = 0;
+ while (i < length) {
final int codePoint = text.codePointAt(i);
if (Character.isLetter(codePoint) && !Character.isUpperCase(codePoint)) {
return false;
}
+ i += Character.charCount(codePoint);
}
return true;
}
public static boolean isIdenticalAfterDowncase(final String text) {
- final int len = text.length();
- for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
+ final int length = text.length();
+ int i = 0;
+ while (i < length) {
final int codePoint = text.codePointAt(i);
if (Character.isLetter(codePoint) && !Character.isLowerCase(codePoint)) {
return false;
}
+ i += Character.charCount(codePoint);
}
return true;
}
+ @UsedForTesting
+ public static boolean looksValidForDictionaryInsertion(final CharSequence text,
+ final SettingsValues settings) {
+ if (TextUtils.isEmpty(text)) return false;
+ final int length = text.length();
+ int i = 0;
+ int digitCount = 0;
+ while (i < length) {
+ final int codePoint = Character.codePointAt(text, i);
+ final int charCount = Character.charCount(codePoint);
+ i += charCount;
+ if (Character.isDigit(codePoint)) {
+ // Count digits: see below
+ digitCount += charCount;
+ continue;
+ }
+ if (!settings.isWordCodePoint(codePoint)) return false;
+ }
+ // We reject strings entirely comprised of digits to avoid using PIN codes or credit
+ // card numbers. It would come in handy for word prediction though; a good example is
+ // when writing one's address where the street number is usually quite discriminative,
+ // as well as the postal code.
+ return digitCount < length;
+ }
+
public static boolean isIdenticalAfterCapitalizeEachWord(final String text,
final String separators) {
boolean needCapsNext = true;
@@ -316,4 +361,194 @@ public final class StringUtils {
// Otherwise, it doesn't look like an URL.
return false;
}
+
+ public static boolean isEmptyStringOrWhiteSpaces(String s) {
+ final int N = codePointCount(s);
+ for (int i = 0; i < N; ++i) {
+ if (!Character.isWhitespace(s.codePointAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @UsedForTesting
+ public static String byteArrayToHexString(byte[] bytes) {
+ if (bytes == null || bytes.length == 0) {
+ return "";
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b & 0xff));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convert hex string to byte array. The string length must be an even number.
+ */
+ @UsedForTesting
+ public static byte[] hexStringToByteArray(String hexString) {
+ if (TextUtils.isEmpty(hexString)) {
+ return null;
+ }
+ final int N = hexString.length();
+ if (N % 2 != 0) {
+ throw new NumberFormatException("Input hex string length must be an even number."
+ + " Length = " + N);
+ }
+ final byte[] bytes = new byte[N / 2];
+ for (int i = 0; i < N; i += 2) {
+ bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ + Character.digit(hexString.charAt(i + 1), 16));
+ }
+ return bytes;
+ }
+
+ public static List<Object> jsonStrToList(String s) {
+ final ArrayList<Object> retval = CollectionUtils.newArrayList();
+ final JsonReader reader = new JsonReader(new StringReader(s));
+ try {
+ reader.beginArray();
+ while(reader.hasNext()) {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ final String name = reader.nextName();
+ if (name.equals(Integer.class.getSimpleName())) {
+ retval.add(reader.nextInt());
+ } else if (name.equals(String.class.getSimpleName())) {
+ retval.add(reader.nextString());
+ } else {
+ Log.w(TAG, "Invalid name: " + name);
+ reader.skipValue();
+ }
+ }
+ reader.endObject();
+ }
+ reader.endArray();
+ return retval;
+ } catch (IOException e) {
+ } finally {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ }
+ return Collections.<Object>emptyList();
+ }
+
+ public static String listToJsonStr(List<Object> list) {
+ if (list == null || list.isEmpty()) {
+ return "";
+ }
+ final StringWriter sw = new StringWriter();
+ final JsonWriter writer = new JsonWriter(sw);
+ try {
+ writer.beginArray();
+ for (final Object o : list) {
+ writer.beginObject();
+ if (o instanceof Integer) {
+ writer.name(Integer.class.getSimpleName()).value((Integer)o);
+ } else if (o instanceof String) {
+ writer.name(String.class.getSimpleName()).value((String)o);
+ }
+ writer.endObject();
+ }
+ writer.endArray();
+ return sw.toString();
+ } catch (IOException e) {
+ } finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ } catch (IOException e) {
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Copies the spans from the region <code>start...end</code> in
+ * <code>source</code> to the region
+ * <code>destoff...destoff+end-start</code> in <code>dest</code>.
+ * Spans in <code>source</code> that begin before <code>start</code>
+ * or end after <code>end</code> but overlap this range are trimmed
+ * as if they began at <code>start</code> or ended at <code>end</code>.
+ * Only SuggestionSpans that don't have the SPAN_PARAGRAPH span are copied.
+ *
+ * This code is almost entirely taken from {@link TextUtils#copySpansFrom}, except for the
+ * kind of span that is copied.
+ *
+ * @throws IndexOutOfBoundsException if any of the copied spans
+ * are out of range in <code>dest</code>.
+ */
+ public static void copyNonParagraphSuggestionSpansFrom(Spanned source, int start, int end,
+ Spannable dest, int destoff) {
+ Object[] spans = source.getSpans(start, end, SuggestionSpan.class);
+
+ for (int i = 0; i < spans.length; i++) {
+ int fl = source.getSpanFlags(spans[i]);
+ if (0 != (fl & Spannable.SPAN_PARAGRAPH)) continue;
+
+ int st = source.getSpanStart(spans[i]);
+ int en = source.getSpanEnd(spans[i]);
+
+ if (st < start)
+ st = start;
+ if (en > end)
+ en = end;
+
+ dest.setSpan(spans[i], st - start + destoff, en - start + destoff,
+ fl);
+ }
+ }
+
+ /**
+ * Returns a CharSequence concatenating the specified CharSequences, retaining their
+ * SuggestionSpans that don't have the PARAGRAPH flag, but not other spans.
+ *
+ * This code is almost entirely taken from {@link TextUtils#concat(CharSequence...)}, except
+ * it calls copyNonParagraphSuggestionSpansFrom instead of {@link TextUtils#copySpansFrom}.
+ */
+ public static CharSequence concatWithNonParagraphSuggestionSpansOnly(CharSequence... text) {
+ if (text.length == 0) {
+ return "";
+ }
+
+ if (text.length == 1) {
+ return text[0];
+ }
+
+ boolean spanned = false;
+ for (int i = 0; i < text.length; i++) {
+ if (text[i] instanceof Spanned) {
+ spanned = true;
+ break;
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < text.length; i++) {
+ sb.append(text[i]);
+ }
+
+ if (!spanned) {
+ return sb.toString();
+ }
+
+ SpannableString ss = new SpannableString(sb);
+ int off = 0;
+ for (int i = 0; i < text.length; i++) {
+ int len = text[i].length();
+
+ if (text[i] instanceof Spanned) {
+ copyNonParagraphSuggestionSpansFrom((Spanned) text[i], 0, len, ss, off);
+ }
+
+ off += len;
+ }
+
+ return new SpannedString(ss);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 16728092d..102a41b4e 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -40,6 +40,7 @@ public final class SubtypeLocaleUtils {
// Special language code to represent "no language".
public static final String NO_LANGUAGE = "zz";
public static final String QWERTY = "qwerty";
+ public static final String EMOJI = "emoji";
public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic;
private static boolean sInitialized = false;
diff --git a/java/src/com/android/inputmethod/latin/utils/TextRange.java b/java/src/com/android/inputmethod/latin/utils/TextRange.java
index 5793e4170..48b443ddd 100644
--- a/java/src/com/android/inputmethod/latin/utils/TextRange.java
+++ b/java/src/com/android/inputmethod/latin/utils/TextRange.java
@@ -40,6 +40,10 @@ public final class TextRange {
return mWordAtCursorEndIndex - mCursorIndex;
}
+ public int length() {
+ return mWord.length();
+ }
+
/**
* Gets the suggestion spans that are put squarely on the word, with the exact start
* and end of the span matching the boundaries of the word.
diff --git a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
index 544e4d201..47ea1ea75 100644
--- a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
@@ -66,6 +66,11 @@ public final class TypefaceUtils {
}
}
+ public static float getStringWidth(final String string, final Paint paint) {
+ paint.getTextBounds(string, 0, string.length(), sTextWidthBounds);
+ return sTextWidthBounds.width();
+ }
+
private static int getCharGeometryCacheKey(final char referenceChar, final Paint paint) {
final int labelSize = (int)paint.getTextSize();
final Typeface face = paint.getTypeface();
diff --git a/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
index d02f7187e..ea32a74ff 100644
--- a/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
@@ -20,20 +20,21 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
+import com.android.inputmethod.latin.makedict.DictDecoder;
+import com.android.inputmethod.latin.makedict.DictEncoder;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import com.android.inputmethod.latin.makedict.PendingAttribute;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.personalization.UserHistoryDictionaryBigramList;
import java.io.IOException;
-import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
/**
* Reads and writes Binary files for a UserHistoryDictionary.
@@ -43,6 +44,9 @@ import java.util.Map;
public final class UserHistoryDictIOUtils {
private static final String TAG = UserHistoryDictIOUtils.class.getSimpleName();
private static final boolean DEBUG = false;
+ private static final String USES_FORGETTING_CURVE_KEY = "USES_FORGETTING_CURVE";
+ private static final String USES_FORGETTING_CURVE_VALUE = "1";
+ private static final String LAST_UPDATED_TIME_KEY = "date";
public interface OnAddWordListener {
public void setUnigram(final String word, final String shortcutTarget, final int frequency);
@@ -57,12 +61,15 @@ public final class UserHistoryDictIOUtils {
/**
* Writes dictionary to file.
*/
- public static void writeDictionaryBinary(final OutputStream destination,
+ public static void writeDictionary(final DictEncoder dictEncoder,
final BigramDictionaryInterface dict, final UserHistoryDictionaryBigramList bigrams,
final FormatOptions formatOptions) {
final FusionDictionary fusionDict = constructFusionDictionary(dict, bigrams);
+ fusionDict.addOptionAttribute(USES_FORGETTING_CURVE_KEY, USES_FORGETTING_CURVE_VALUE);
+ fusionDict.addOptionAttribute(LAST_UPDATED_TIME_KEY,
+ String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
try {
- BinaryDictInputOutput.writeDictionaryBinary(destination, fusionDict, formatOptions);
+ dictEncoder.writeDictionary(fusionDict, formatOptions);
Log.d(TAG, "end writing");
} catch (IOException e) {
Log.e(TAG, "IO exception while writing file", e);
@@ -77,7 +84,7 @@ public final class UserHistoryDictIOUtils {
@UsedForTesting
static FusionDictionary constructFusionDictionary(
final BigramDictionaryInterface dict, final UserHistoryDictionaryBigramList bigrams) {
- final FusionDictionary fusionDict = new FusionDictionary(new Node(),
+ final FusionDictionary fusionDict = new FusionDictionary(new PtNodeArray(),
new FusionDictionary.DictionaryOptions(new HashMap<String, String>(), false,
false));
int profTotal = 0;
@@ -101,7 +108,7 @@ public final class UserHistoryDictIOUtils {
if (word1 == null) { // unigram
fusionDict.add(word2, freq, null, false /* isNotAWord */);
} else { // bigram
- if (FusionDictionary.findWordInTree(fusionDict.mRoot, word1) == null) {
+ if (FusionDictionary.findWordInTree(fusionDict.mRootNodeArray, word1) == null) {
fusionDict.add(word1, 2, null, false /* isNotAWord */);
}
fusionDict.setBigram(word1, word2, freq);
@@ -118,14 +125,13 @@ public final class UserHistoryDictIOUtils {
/**
* Reads dictionary from file.
*/
- public static void readDictionaryBinary(final FusionDictionaryBufferInterface buffer,
+ public static void readDictionaryBinary(final DictDecoder dictDecoder,
final OnAddWordListener dict) {
- final Map<Integer, String> unigrams = CollectionUtils.newTreeMap();
- final Map<Integer, Integer> frequencies = CollectionUtils.newTreeMap();
- final Map<Integer, ArrayList<PendingAttribute>> bigrams = CollectionUtils.newTreeMap();
+ final TreeMap<Integer, String> unigrams = CollectionUtils.newTreeMap();
+ final TreeMap<Integer, Integer> frequencies = CollectionUtils.newTreeMap();
+ final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams = CollectionUtils.newTreeMap();
try {
- BinaryDictIOUtils.readUnigramsAndBigramsBinary(buffer, unigrams, frequencies,
- bigrams);
+ dictDecoder.readUnigramsAndBigramsBinary(unigrams, frequencies, bigrams);
} catch (IOException e) {
Log.e(TAG, "IO exception while reading file", e);
} catch (UnsupportedFormatException e) {
@@ -140,10 +146,11 @@ public final class UserHistoryDictIOUtils {
* Adds all unigrams and bigrams in maps to OnAddWordListener.
*/
@UsedForTesting
- static void addWordsFromWordMap(final Map<Integer, String> unigrams,
- final Map<Integer, Integer> frequencies,
- final Map<Integer, ArrayList<PendingAttribute>> bigrams, final OnAddWordListener to) {
- for (Map.Entry<Integer, String> entry : unigrams.entrySet()) {
+ static void addWordsFromWordMap(final TreeMap<Integer, String> unigrams,
+ final TreeMap<Integer, Integer> frequencies,
+ final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams,
+ final OnAddWordListener to) {
+ for (Entry<Integer, String> entry : unigrams.entrySet()) {
final String word1 = entry.getValue();
final int unigramFrequency = frequencies.get(entry.getKey());
to.setUnigram(word1, null, unigramFrequency);
@@ -156,7 +163,7 @@ public final class UserHistoryDictIOUtils {
continue;
}
to.setBigram(word1, word2,
- BinaryDictInputOutput.reconstructBigramFrequency(unigramFrequency,
+ BinaryDictIOUtils.reconstructBigramFrequency(unigramFrequency,
attr.mFrequency));
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java b/java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java
index 713a45bda..1992b2f5d 100644
--- a/java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java
@@ -23,7 +23,9 @@ import java.util.concurrent.TimeUnit;
public final class UserHistoryForgettingCurveUtils {
private static final String TAG = UserHistoryForgettingCurveUtils.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final int FC_FREQ_MAX = 127;
+ private static final int DEFAULT_FC_FREQ = 127;
+ private static final int BOOSTED_FC_FREQ = 200;
+ private static int FC_FREQ_MAX = DEFAULT_FC_FREQ;
/* package */ static final int COUNT_MAX = 3;
private static final int FC_LEVEL_MAX = 3;
/* package */ static final int ELAPSED_TIME_MAX = 15;
@@ -33,6 +35,14 @@ public final class UserHistoryForgettingCurveUtils {
private static final int HALF_LIFE_HOURS = 48;
private static final int MAX_PUSH_ELAPSED = (FC_LEVEL_MAX + 1) * (ELAPSED_TIME_MAX + 1);
+ public static void boostMaxFreqForDebug() {
+ FC_FREQ_MAX = BOOSTED_FC_FREQ;
+ }
+
+ public static void resetMaxFreqForDebug() {
+ FC_FREQ_MAX = DEFAULT_FC_FREQ;
+ }
+
private UserHistoryForgettingCurveUtils() {
// This utility class is not publicly instantiable.
}
diff --git a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java
index 161386e2e..a75d353c9 100644
--- a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java
+++ b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.utils;
import android.inputmethodservice.InputMethodService;
import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.settings.Settings;
public final class UserLogRingCharBuffer {
@@ -64,6 +65,9 @@ public final class UserLogRingCharBuffer {
if (!mEnabled) {
return;
}
+ if (LatinImeLogger.sUsabilityStudy) {
+ UsabilityStudyLogUtils.getInstance().writeChar(c, x, y);
+ }
mCharBuf[mEnd] = c;
mXBuf[mEnd] = x;
mYBuf[mEnd] = y;
diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java
index 63d524df7..2beebdfae 100644
--- a/java/src/com/android/inputmethod/research/JsonUtils.java
+++ b/java/src/com/android/inputmethod/research/JsonUtils.java
@@ -75,12 +75,12 @@ import java.util.Map;
private static void writeJson(final Key key, final JsonWriter jsonWriter) throws IOException {
jsonWriter.beginObject();
- jsonWriter.name("code").value(key.mCode);
+ jsonWriter.name("code").value(key.getCode());
jsonWriter.name("altCode").value(key.getAltCode());
- jsonWriter.name("x").value(key.mX);
- jsonWriter.name("y").value(key.mY);
- jsonWriter.name("w").value(key.mWidth);
- jsonWriter.name("h").value(key.mHeight);
+ jsonWriter.name("x").value(key.getX());
+ jsonWriter.name("y").value(key.getY());
+ jsonWriter.name("w").value(key.getWidth());
+ jsonWriter.name("h").value(key.getHeight());
jsonWriter.endObject();
}
@@ -103,7 +103,7 @@ import java.util.Map;
jsonWriter.name("word").value(wordInfo.toString());
jsonWriter.name("score").value(wordInfo.mScore);
jsonWriter.name("kind").value(wordInfo.mKind);
- jsonWriter.name("sourceDict").value(wordInfo.mSourceDict);
+ jsonWriter.name("sourceDict").value(wordInfo.mSourceDict.mDictType);
jsonWriter.endObject();
}
jsonWriter.endArray();
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 3a3408266..da9c61103 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -1427,7 +1427,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
kid.navigateNext(), kid.navigatePrevious(), kid.mClobberSettingsKey,
isPasswordView, kid.mShortcutKeyEnabled, kid.mHasShortcutKey,
kid.mLanguageSwitchKeyEnabled, kid.isMultiLine(), keyboard.mOccupiedWidth,
- keyboard.mOccupiedHeight, keyboard.mKeys);
+ keyboard.mOccupiedHeight, keyboard.getKeys());
}
/**