diff options
Diffstat (limited to 'java')
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 Binary files differdeleted file mode 100644 index 4f5f01cb8..000000000 --- a/java/res/drawable-hdpi/btn_center_default.9.png +++ /dev/null diff --git a/java/res/drawable-hdpi/btn_center_pressed.9.png b/java/res/drawable-hdpi/btn_center_pressed.9.png Binary files differdeleted file mode 100644 index 213b482d4..000000000 --- a/java/res/drawable-hdpi/btn_center_pressed.9.png +++ /dev/null diff --git a/java/res/drawable-hdpi/btn_center_selected.9.png b/java/res/drawable-hdpi/btn_center_selected.9.png Binary files differdeleted file mode 100644 index 213b482d4..000000000 --- a/java/res/drawable-hdpi/btn_center_selected.9.png +++ /dev/null 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index 116329016..000000000 --- a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_normal.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 207c90d6c..000000000 --- a/java/res/drawable-hdpi/btn_keyboard_key_fulltrans_pressed.9.png +++ /dev/null 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index cdd6c8b79..000000000 --- a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_stone.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index d8421746a..000000000 --- a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_stone.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 671d4e5d6..000000000 --- a/java/res/drawable-hdpi/btn_keyboard_key_normal_stone.9.png +++ /dev/null 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 Binary files differindex 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 diff --git a/java/res/drawable-hdpi/ic_emoji_dark.png b/java/res/drawable-hdpi/ic_emoji_dark.png Binary files differdeleted file mode 100644 index a9f18cde0..000000000 --- a/java/res/drawable-hdpi/ic_emoji_dark.png +++ /dev/null diff --git a/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png Binary files differnew file mode 100644 index 000000000..5525df2f7 --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png diff --git a/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png Binary files differnew file mode 100644 index 000000000..34e16b9de --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png diff --git a/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png Binary files differnew file mode 100644 index 000000000..c3c7ec1b8 --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png diff --git a/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png Binary files differnew file mode 100644 index 000000000..f012d7707 --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png diff --git a/java/res/drawable-hdpi/ic_emoji_people_light_activated.png b/java/res/drawable-hdpi/ic_emoji_people_light_activated.png Binary files differnew file mode 100644 index 000000000..cfacbc2e7 --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_people_light_activated.png diff --git a/java/res/drawable-hdpi/ic_emoji_light.png b/java/res/drawable-hdpi/ic_emoji_people_light_normal.png Binary files differindex 2e3638bf3..c54dbc1f5 100644 --- a/java/res/drawable-hdpi/ic_emoji_light.png +++ b/java/res/drawable-hdpi/ic_emoji_people_light_normal.png diff --git a/java/res/drawable-hdpi/ic_emoji_places_light_activated.png b/java/res/drawable-hdpi/ic_emoji_places_light_activated.png Binary files differnew file mode 100644 index 000000000..959dfdfd5 --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_places_light_activated.png diff --git a/java/res/drawable-hdpi/ic_emoji_places_light_normal.png b/java/res/drawable-hdpi/ic_emoji_places_light_normal.png Binary files differnew file mode 100644 index 000000000..fc0d9711d --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_places_light_normal.png diff --git a/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png Binary files differnew file mode 100644 index 000000000..de570a185 --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png diff --git a/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png Binary files differnew file mode 100644 index 000000000..b2562088d --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png diff --git a/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png Binary files differnew file mode 100644 index 000000000..af1fd27ec --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png diff --git a/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png Binary files differnew file mode 100644 index 000000000..02b84d51b --- /dev/null +++ b/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png diff --git a/java/res/drawable-hdpi/ic_ime_switcher_dark.png b/java/res/drawable-hdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..7506af5a3 --- /dev/null +++ b/java/res/drawable-hdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-hdpi/ic_settings_language.png b/java/res/drawable-hdpi/ic_settings_language.png Binary files differdeleted file mode 100644 index f635b2e7a..000000000 --- a/java/res/drawable-hdpi/ic_settings_language.png +++ /dev/null diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index 484305655..000000000 --- a/java/res/drawable-hdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-hdpi/ic_subtype_mic_dark.png b/java/res/drawable-hdpi/ic_subtype_mic_dark.png Binary files differnew file mode 100644 index 000000000..eacbcd255 --- /dev/null +++ b/java/res/drawable-hdpi/ic_subtype_mic_dark.png diff --git a/java/res/drawable-hdpi/keyboard_background.9.png b/java/res/drawable-hdpi/keyboard_background.9.png Binary files differdeleted file mode 100644 index d57463fb6..000000000 --- a/java/res/drawable-hdpi/keyboard_background.9.png +++ /dev/null diff --git a/java/res/drawable-hdpi/keyboard_dark_background.9.png b/java/res/drawable-hdpi/keyboard_background_gb.9.png Binary files differindex fa3d449f7..fa3d449f7 100644 --- a/java/res/drawable-hdpi/keyboard_dark_background.9.png +++ b/java/res/drawable-hdpi/keyboard_background_gb.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip_gb.9.png Binary files differindex 7cab5a899..7cab5a899 100644 --- a/java/res/drawable-hdpi/keyboard_suggest_strip.9.png +++ b/java/res/drawable-hdpi/keyboard_suggest_strip_gb.9.png diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png Binary files differindex 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 diff --git a/java/res/drawable-hdpi/sym_bkeyboard_delete.png b/java/res/drawable-hdpi/sym_bkeyboard_delete.png Binary files differdeleted file mode 100644 index 1d24cc85c..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png Binary files differdeleted file mode 100644 index 25702cf73..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_mic.png Binary files differdeleted file mode 100644 index 512f46080..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_return.png b/java/res/drawable-hdpi/sym_bkeyboard_return.png Binary files differdeleted file mode 100644 index 426e1599e..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_return.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_search.png b/java/res/drawable-hdpi/sym_bkeyboard_search.png Binary files differdeleted file mode 100644 index 1b6f884fa..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_search.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_settings.png b/java/res/drawable-hdpi/sym_bkeyboard_settings.png Binary files differdeleted file mode 100644 index 08ba18f28..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift.png b/java/res/drawable-hdpi/sym_bkeyboard_shift.png Binary files differdeleted file mode 100644 index 5a22dd309..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png Binary files differdeleted file mode 100644 index 566449126..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_space.png b/java/res/drawable-hdpi/sym_bkeyboard_space.png Binary files differdeleted file mode 100644 index cd0ebe2f4..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_space.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_tab.png b/java/res/drawable-hdpi/sym_bkeyboard_tab.png Binary files differdeleted file mode 100644 index 3466e1271..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-hdpi/sym_bkeyboard_voice_off.png Binary files differdeleted file mode 100644 index 081a13096..000000000 --- a/java/res/drawable-hdpi/sym_bkeyboard_voice_off.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png Binary files differdeleted file mode 100644 index 0591b82cd..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index d3e108846..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..d2d3560a3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic.png b/java/res/drawable-hdpi/sym_keyboard_label_mic.png Binary files differdeleted file mode 100644 index 4e0a8ed8e..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index f8df44741..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch.png b/java/res/drawable-hdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index 7b980a0c8..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..78d3a1fc5 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png Binary files differdeleted file mode 100644 index 520a40f09..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..3c5469403 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png Binary files differdeleted file mode 100644 index 9743c7f2f..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_return.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo.png b/java/res/drawable-hdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index 8978934b8..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..60d893cf3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png Binary files differdeleted file mode 100644 index 8cd28c64a..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_search.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-hdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index b987a20f1..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..fa0d1bde1 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png Binary files differdeleted file mode 100644 index 1e5bf939e..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 5af09ad8c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..c76008ab3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png Binary files differdeleted file mode 100644 index 8e3d0320c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index c58f9ab5c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..544b7e141 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png Binary files differdeleted file mode 100644 index d345634a6..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index 7a5c03713..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..9b1d6a015 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-hdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index e8bc3902d..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..12e27ade7 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png 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 Binary files differindex 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 diff --git a/java/res/drawable-hdpi/sym_keyboard_tab.png b/java/res/drawable-hdpi/sym_keyboard_tab.png Binary files differdeleted file mode 100644 index 3d1c5c0ea..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index 8d10d057c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..2e5f811f3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index 8a6336a57..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..c1e16a651 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index edf1379ab..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..26d068490 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 5fa30ceb8..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..9f9bc173b --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index 91367f3d2..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..f0f832e13 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png diff --git a/java/res/drawable-hdpi/tab_selected.9.png b/java/res/drawable-hdpi/tab_selected.9.png Binary files differnew file mode 100644 index 000000000..84e63df17 --- /dev/null +++ b/java/res/drawable-hdpi/tab_selected.9.png diff --git a/java/res/drawable-hdpi/tab_unselected.9.png b/java/res/drawable-hdpi/tab_unselected.9.png Binary files differnew file mode 100644 index 000000000..bbcfb2c64 --- /dev/null +++ b/java/res/drawable-hdpi/tab_unselected.9.png diff --git a/java/res/drawable-mdpi/btn_center_default.9.png b/java/res/drawable-mdpi/btn_center_default.9.png Binary files differdeleted file mode 100644 index d5ec36ba4..000000000 --- a/java/res/drawable-mdpi/btn_center_default.9.png +++ /dev/null diff --git a/java/res/drawable-mdpi/btn_center_pressed.9.png b/java/res/drawable-mdpi/btn_center_pressed.9.png Binary files differdeleted file mode 100644 index 593a679d0..000000000 --- a/java/res/drawable-mdpi/btn_center_pressed.9.png +++ /dev/null diff --git a/java/res/drawable-mdpi/btn_center_selected.9.png b/java/res/drawable-mdpi/btn_center_selected.9.png Binary files differdeleted file mode 100644 index f1914a886..000000000 --- a/java/res/drawable-mdpi/btn_center_selected.9.png +++ /dev/null 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index 4b1a78cfb..000000000 --- a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_normal.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 697683e29..000000000 --- a/java/res/drawable-mdpi/btn_keyboard_key_fulltrans_pressed.9.png +++ /dev/null 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index cdd6c8b79..000000000 --- a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_stone.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index d8421746a..000000000 --- a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_stone.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 73cf35df0..000000000 --- a/java/res/drawable-mdpi/btn_keyboard_key_normal_stone.9.png +++ /dev/null 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 Binary files differindex 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 diff --git a/java/res/drawable-mdpi/ic_emoji_dark.png b/java/res/drawable-mdpi/ic_emoji_dark.png Binary files differdeleted file mode 100644 index d0047a437..000000000 --- a/java/res/drawable-mdpi/ic_emoji_dark.png +++ /dev/null diff --git a/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png Binary files differnew file mode 100644 index 000000000..d4c8d8da8 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png diff --git a/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png Binary files differnew file mode 100644 index 000000000..1555aa7a9 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png diff --git a/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png Binary files differnew file mode 100644 index 000000000..081dc66c2 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png diff --git a/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png Binary files differnew file mode 100644 index 000000000..58e6f6e75 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png diff --git a/java/res/drawable-mdpi/ic_emoji_people_light_activated.png b/java/res/drawable-mdpi/ic_emoji_people_light_activated.png Binary files differnew file mode 100644 index 000000000..067ad5496 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_people_light_activated.png diff --git a/java/res/drawable-mdpi/ic_emoji_light.png b/java/res/drawable-mdpi/ic_emoji_people_light_normal.png Binary files differindex a3195041a..d835d4ec7 100644 --- a/java/res/drawable-mdpi/ic_emoji_light.png +++ b/java/res/drawable-mdpi/ic_emoji_people_light_normal.png diff --git a/java/res/drawable-mdpi/ic_emoji_places_light_activated.png b/java/res/drawable-mdpi/ic_emoji_places_light_activated.png Binary files differnew file mode 100644 index 000000000..1aecec598 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_places_light_activated.png diff --git a/java/res/drawable-mdpi/ic_emoji_places_light_normal.png b/java/res/drawable-mdpi/ic_emoji_places_light_normal.png Binary files differnew file mode 100644 index 000000000..c70e484e1 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_places_light_normal.png diff --git a/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png Binary files differnew file mode 100644 index 000000000..8009e932f --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png diff --git a/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png Binary files differnew file mode 100644 index 000000000..c2e598dfb --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png diff --git a/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png Binary files differnew file mode 100644 index 000000000..caea87191 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png diff --git a/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png Binary files differnew file mode 100644 index 000000000..0edada626 --- /dev/null +++ b/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png diff --git a/java/res/drawable-mdpi/ic_ime_switcher_dark.png b/java/res/drawable-mdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..152f65300 --- /dev/null +++ b/java/res/drawable-mdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-mdpi/ic_settings_language.png b/java/res/drawable-mdpi/ic_settings_language.png Binary files differdeleted file mode 100644 index f8aca679b..000000000 --- a/java/res/drawable-mdpi/ic_settings_language.png +++ /dev/null diff --git a/java/res/drawable-mdpi/ic_subtype_keyboard.png b/java/res/drawable-mdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index d28efc106..000000000 --- a/java/res/drawable-mdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-mdpi/keyboard_background.9.png b/java/res/drawable-mdpi/keyboard_background.9.png Binary files differdeleted file mode 100644 index 2bd4b628d..000000000 --- a/java/res/drawable-mdpi/keyboard_background.9.png +++ /dev/null diff --git a/java/res/drawable-mdpi/keyboard_dark_background.9.png b/java/res/drawable-mdpi/keyboard_background_gb.9.png Binary files differindex 4f81704c4..4f81704c4 100644 --- a/java/res/drawable-mdpi/keyboard_dark_background.9.png +++ b/java/res/drawable-mdpi/keyboard_background_gb.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-mdpi/keyboard_suggest_strip.9.png b/java/res/drawable-mdpi/keyboard_suggest_strip_gb.9.png Binary files differindex fa6c0feff..fa6c0feff 100644 --- a/java/res/drawable-mdpi/keyboard_suggest_strip.9.png +++ b/java/res/drawable-mdpi/keyboard_suggest_strip_gb.9.png diff --git a/java/res/drawable-mdpi/suggestions_strip_divider.png b/java/res/drawable-mdpi/suggestions_strip_divider.png Binary files differindex 2dbe2f94b..21e904939 100644 --- a/java/res/drawable-mdpi/suggestions_strip_divider.png +++ b/java/res/drawable-mdpi/suggestions_strip_divider.png diff --git a/java/res/drawable-mdpi/sym_bkeyboard_delete.png b/java/res/drawable-mdpi/sym_bkeyboard_delete.png Binary files differdeleted file mode 100644 index 1a5ff439e..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png Binary files differdeleted file mode 100644 index 7f0b1355f..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_mic.png b/java/res/drawable-mdpi/sym_bkeyboard_mic.png Binary files differdeleted file mode 100644 index a6cb1cc01..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_return.png b/java/res/drawable-mdpi/sym_bkeyboard_return.png Binary files differdeleted file mode 100644 index e76225d0f..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_return.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_search.png b/java/res/drawable-mdpi/sym_bkeyboard_search.png Binary files differdeleted file mode 100644 index 1f180155d..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_search.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_settings.png b/java/res/drawable-mdpi/sym_bkeyboard_settings.png Binary files differdeleted file mode 100644 index 08ba18f28..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_shift.png b/java/res/drawable-mdpi/sym_bkeyboard_shift.png Binary files differdeleted file mode 100644 index c981188dd..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png Binary files differdeleted file mode 100644 index b8cebd060..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_space.png b/java/res/drawable-mdpi/sym_bkeyboard_space.png Binary files differdeleted file mode 100644 index 4da7ee86e..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_space.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_tab.png b/java/res/drawable-mdpi/sym_bkeyboard_tab.png Binary files differdeleted file mode 100644 index 2cb991cbf..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-mdpi/sym_bkeyboard_voice_off.png Binary files differdeleted file mode 100644 index 081a13096..000000000 --- a/java/res/drawable-mdpi/sym_bkeyboard_voice_off.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_delete.png b/java/res/drawable-mdpi/sym_keyboard_delete.png Binary files differdeleted file mode 100644 index 1b0f3f836..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index 86be35185..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..edd9d164e --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic.png b/java/res/drawable-mdpi/sym_keyboard_label_mic.png Binary files differdeleted file mode 100644 index a354d5321..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index 15606e95f..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..537f39b02 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch.png b/java/res/drawable-mdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index f840a631d..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..828929bc8 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_mic.png b/java/res/drawable-mdpi/sym_keyboard_mic.png Binary files differdeleted file mode 100644 index e926b3fa6..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..5e58866a7 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png Binary files differnew file mode 100644 index 000000000..84a63dc7f --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png diff --git a/java/res/drawable-mdpi/sym_keyboard_return.png b/java/res/drawable-mdpi/sym_keyboard_return.png Binary files differdeleted file mode 100644 index 0c10f004a..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_return.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-mdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index bfcb91328..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..e10103caf --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_search.png b/java/res/drawable-mdpi/sym_keyboard_search.png Binary files differdeleted file mode 100644 index 614f85f5e..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_search.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-mdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index dd3c83a84..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..290cde41b --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_settings.png b/java/res/drawable-mdpi/sym_keyboard_settings.png Binary files differdeleted file mode 100644 index ad7618fa0..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 36c8c9623..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..a76a976c5 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_shift.png b/java/res/drawable-mdpi/sym_keyboard_shift.png Binary files differdeleted file mode 100644 index 5109b0471..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index 621946455..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..37375d935 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png Binary files differdeleted file mode 100644 index 244179c2d..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index fb3a020d8..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..3654868dc --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png Binary files differnew file mode 100644 index 000000000..71272bb88 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-mdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 1f787d573..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..a38f99496 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png 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 Binary files differindex 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 diff --git a/java/res/drawable-mdpi/sym_keyboard_tab.png b/java/res/drawable-mdpi/sym_keyboard_tab.png Binary files differdeleted file mode 100644 index eddb9a592..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index 8d20153ee..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..f883807f2 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index 0795fcc9b..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..16be37d05 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index f76da5797..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..95d718a46 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 70370d83d..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..8957e282b --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index a69eade17..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..5f49e64aa --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png diff --git a/java/res/drawable-mdpi/tab_selected.9.png b/java/res/drawable-mdpi/tab_selected.9.png Binary files differnew file mode 100644 index 000000000..4b00f350a --- /dev/null +++ b/java/res/drawable-mdpi/tab_selected.9.png diff --git a/java/res/drawable-mdpi/tab_unselected.9.png b/java/res/drawable-mdpi/tab_unselected.9.png Binary files differnew file mode 100644 index 000000000..bb45ab960 --- /dev/null +++ b/java/res/drawable-mdpi/tab_unselected.9.png diff --git a/java/res/drawable-xhdpi/btn_center_default.9.png b/java/res/drawable-xhdpi/btn_center_default.9.png Binary files differdeleted file mode 100644 index e847425f8..000000000 --- a/java/res/drawable-xhdpi/btn_center_default.9.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/btn_center_pressed.9.png b/java/res/drawable-xhdpi/btn_center_pressed.9.png Binary files differdeleted file mode 100644 index facfd4323..000000000 --- a/java/res/drawable-xhdpi/btn_center_pressed.9.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/btn_center_selected.9.png b/java/res/drawable-xhdpi/btn_center_selected.9.png Binary files differdeleted file mode 100644 index facfd4323..000000000 --- a/java/res/drawable-xhdpi/btn_center_selected.9.png +++ /dev/null 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index f7e32f764..000000000 --- a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_normal.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index df3b5ba2d..000000000 --- a/java/res/drawable-xhdpi/btn_keyboard_key_fulltrans_pressed.9.png +++ /dev/null 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differdeleted file mode 100644 index dec219304..000000000 --- a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_stone.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 3c77b3ccd..000000000 --- a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_stone.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 5cdfc4201..000000000 --- a/java/res/drawable-xhdpi/btn_keyboard_key_normal_stone.9.png +++ /dev/null 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 Binary files differindex 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 diff --git a/java/res/drawable-xhdpi/ic_emoji_dark.png b/java/res/drawable-xhdpi/ic_emoji_dark.png Binary files differdeleted file mode 100644 index 22daec22e..000000000 --- a/java/res/drawable-xhdpi/ic_emoji_dark.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png Binary files differnew file mode 100644 index 000000000..3e6744343 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png diff --git a/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png Binary files differnew file mode 100644 index 000000000..5344a9ee9 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png diff --git a/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png Binary files differnew file mode 100644 index 000000000..75695d43d --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png diff --git a/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png Binary files differnew file mode 100644 index 000000000..2adb186e6 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png diff --git a/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png Binary files differnew file mode 100644 index 000000000..e6baa2e59 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png diff --git a/java/res/drawable-xhdpi/ic_emoji_light.png b/java/res/drawable-xhdpi/ic_emoji_people_light_normal.png Binary files differindex 21bc9090d..c26aa4efb 100644 --- a/java/res/drawable-xhdpi/ic_emoji_light.png +++ b/java/res/drawable-xhdpi/ic_emoji_people_light_normal.png diff --git a/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png Binary files differnew file mode 100644 index 000000000..eaa3b86cf --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png diff --git a/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png Binary files differnew file mode 100644 index 000000000..d6e1eaa35 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png diff --git a/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png Binary files differnew file mode 100644 index 000000000..06003b82d --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png diff --git a/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png Binary files differnew file mode 100644 index 000000000..da2effedb --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png diff --git a/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png Binary files differnew file mode 100644 index 000000000..438fde2b4 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png diff --git a/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png Binary files differnew file mode 100644 index 000000000..757863233 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png diff --git a/java/res/drawable-xhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..c567077e5 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-xhdpi/ic_settings_language.png b/java/res/drawable-xhdpi/ic_settings_language.png Binary files differdeleted file mode 100644 index 2c42db3aa..000000000 --- a/java/res/drawable-xhdpi/ic_settings_language.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/ic_subtype_keyboard.png b/java/res/drawable-xhdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index a79bb3458..000000000 --- a/java/res/drawable-xhdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png Binary files differnew file mode 100644 index 000000000..17581ba89 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png diff --git a/java/res/drawable-xhdpi/keyboard_background.9.png b/java/res/drawable-xhdpi/keyboard_background.9.png Binary files differdeleted file mode 100644 index 263996322..000000000 --- a/java/res/drawable-xhdpi/keyboard_background.9.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/keyboard_dark_background.9.png b/java/res/drawable-xhdpi/keyboard_background_gb.9.png Binary files differindex 27b7a108c..27b7a108c 100644 --- a/java/res/drawable-xhdpi/keyboard_dark_background.9.png +++ b/java/res/drawable-xhdpi/keyboard_background_gb.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png b/java/res/drawable-xhdpi/keyboard_suggest_strip_gb.9.png Binary files differindex 1b568df03..1b568df03 100644 --- a/java/res/drawable-xhdpi/keyboard_suggest_strip.9.png +++ b/java/res/drawable-xhdpi/keyboard_suggest_strip_gb.9.png diff --git a/java/res/drawable-xhdpi/suggestions_strip_divider.png b/java/res/drawable-xhdpi/suggestions_strip_divider.png Binary files differindex 0d8b98437..4101ebc59 100644 --- a/java/res/drawable-xhdpi/suggestions_strip_divider.png +++ b/java/res/drawable-xhdpi/suggestions_strip_divider.png diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_delete.png b/java/res/drawable-xhdpi/sym_bkeyboard_delete.png Binary files differdeleted file mode 100644 index b84ee76dc..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png Binary files differdeleted file mode 100644 index 9bd1d65b4..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_mic.png Binary files differdeleted file mode 100644 index 8c3f11dd4..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_return.png b/java/res/drawable-xhdpi/sym_bkeyboard_return.png Binary files differdeleted file mode 100644 index 1632ecd8e..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_return.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_search.png b/java/res/drawable-xhdpi/sym_bkeyboard_search.png Binary files differdeleted file mode 100644 index 69d8b22d1..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_search.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_settings.png b/java/res/drawable-xhdpi/sym_bkeyboard_settings.png Binary files differdeleted file mode 100644 index 050154a3a..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_shift.png b/java/res/drawable-xhdpi/sym_bkeyboard_shift.png Binary files differdeleted file mode 100644 index d15d11a50..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png Binary files differdeleted file mode 100644 index 83b287fea..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_space.png b/java/res/drawable-xhdpi/sym_bkeyboard_space.png Binary files differdeleted file mode 100644 index 5ca62c7b7..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_space.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_tab.png b/java/res/drawable-xhdpi/sym_bkeyboard_tab.png Binary files differdeleted file mode 100644 index 6ca199755..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png b/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png Binary files differdeleted file mode 100644 index fc6a4eb59..000000000 --- a/java/res/drawable-xhdpi/sym_bkeyboard_voice_off.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete.png b/java/res/drawable-xhdpi/sym_keyboard_delete.png Binary files differdeleted file mode 100644 index 3c0b8b186..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index 354c09ee6..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..e3e37d5ff --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic.png Binary files differdeleted file mode 100644 index 49810a02f..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index 8eeb179f5..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index 6c2fb53ec..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..b8687f550 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic.png b/java/res/drawable-xhdpi/sym_keyboard_mic.png Binary files differdeleted file mode 100644 index 1323b6d1e..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..566ba1fcd --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_return.png b/java/res/drawable-xhdpi/sym_keyboard_return.png Binary files differdeleted file mode 100644 index ad061227e..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_return.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index ba424adfd..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..7b7ad1747 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_search.png b/java/res/drawable-xhdpi/sym_keyboard_search.png Binary files differdeleted file mode 100644 index aa785a221..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_search.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index f2fb2a2b5..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..36b1646bb --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings.png b/java/res/drawable-xhdpi/sym_keyboard_settings.png Binary files differdeleted file mode 100644 index 50704255d..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 99ee97dbf..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..05eaffe2e --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift.png b/java/res/drawable-xhdpi/sym_keyboard_shift.png Binary files differdeleted file mode 100644 index 290170619..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index 1046b4545..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..5ab549114 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png Binary files differdeleted file mode 100644 index a5deb60e9..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index 6acb565d9..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..b820eaabb --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png Binary files differnew file mode 100644 index 000000000..686831fd3 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 504a3ed45..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..7114b740f --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png 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 Binary files differindex 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 diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab.png b/java/res/drawable-xhdpi/sym_keyboard_tab.png Binary files differdeleted file mode 100644 index 0ef2ab5b9..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index ff380eeab..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..73ebfe525 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index b2bb9b803..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..944a8524d --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index 23e75bfe7..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..2016caf40 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 26694274e..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..2f9607add --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index 75a22b65f..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..ab07f7549 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png diff --git a/java/res/drawable-xhdpi/tab_selected.9.png b/java/res/drawable-xhdpi/tab_selected.9.png Binary files differnew file mode 100644 index 000000000..95e5f4341 --- /dev/null +++ b/java/res/drawable-xhdpi/tab_selected.9.png diff --git a/java/res/drawable-xhdpi/tab_unselected.9.png b/java/res/drawable-xhdpi/tab_unselected.9.png Binary files differnew file mode 100644 index 000000000..8cede8d5e --- /dev/null +++ b/java/res/drawable-xhdpi/tab_unselected.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png Binary files differnew file mode 100644 index 000000000..470fd695c --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png Binary files differnew file mode 100644 index 000000000..a7fde0ec5 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png Binary files differnew file mode 100644 index 000000000..c582b704a --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png Binary files differnew file mode 100644 index 000000000..acc95d725 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png Binary files differnew file mode 100644 index 000000000..5973ac355 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png Binary files differnew file mode 100644 index 000000000..22e06f808 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png Binary files differnew file mode 100644 index 000000000..690e95fd5 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png Binary files differnew file mode 100644 index 000000000..ced4b08cf --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png Binary files differnew file mode 100644 index 000000000..25e847ef3 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png Binary files differnew file mode 100644 index 000000000..c86368d73 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png Binary files differnew file mode 100644 index 000000000..29dfc7118 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png diff --git a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png Binary files differnew file mode 100644 index 000000000..0570567cf --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png diff --git a/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..f99f7d0c7 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png b/java/res/drawable-xxhdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index 0bb4283b0..000000000 --- a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png Binary files differnew file mode 100644 index 000000000..811103a56 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index be3cb7ce7..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..92be79241 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index b6d4477bd..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index 7cd0684a0..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..88b55bb37 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..f55af308c --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index 7d9580796..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..46ee50eba --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index 6b09d8e57..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..f518748ce --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 7041bb6ce..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..e4358463b --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index 2b4fbbba6..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..523286e6e --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index 91c8603fd..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..87926d9a6 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png Binary files differnew file mode 100644 index 000000000..04b721617 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 65aa5ea9b..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..1dab1f431 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index 1f4ae3df7..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..6eb3eb0b3 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index f04cadf6f..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..6809f0711 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index e74d523bc..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..6bd506a11 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 85289b2a3..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..5e225b837 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index e610678b1..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..cdfc0295b --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png diff --git a/java/res/drawable-xxhdpi/tab_selected.9.png b/java/res/drawable-xxhdpi/tab_selected.9.png Binary files differnew file mode 100644 index 000000000..e5efc5828 --- /dev/null +++ b/java/res/drawable-xxhdpi/tab_selected.9.png diff --git a/java/res/drawable-xxhdpi/tab_unselected.9.png b/java/res/drawable-xxhdpi/tab_unselected.9.png Binary files differnew file mode 100644 index 000000000..389188695 --- /dev/null +++ b/java/res/drawable-xxhdpi/tab_unselected.9.png 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 Binary files differindex 31fb2af85..10adad092 100644 --- a/java/res/raw/main_fr.dict +++ b/java/res/raw/main_fr.dict diff --git a/java/res/raw/main_pt_br.dict b/java/res/raw/main_pt_br.dict Binary files differindex 557d46e89..f9ae9b561 100644 --- a/java/res/raw/main_pt_br.dict +++ b/java/res/raw/main_pt_br.dict diff --git a/java/res/raw/main_ru.dict b/java/res/raw/main_ru.dict Binary files differindex 86c368eb9..7dec62425 100644 --- a/java/res/raw/main_ru.dict +++ b/java/res/raw/main_ru.dict 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.<br/> Teksti mugavamaks sisestamiseks soovitame <b>alla laadida</b> <xliff:g id="LANGUAGE">%1$s</xliff:g> keele sõnastiku.<br/> <br/> 3G kaudu allalaadimisele võib kuluda minut või paar. Kehtida võivad tasud, kui te ei kasuta <b>piiramatut andmepaketti</b>.<br/> Kui te ei tea, millist andmepaketti kasutate, soovitame allalaadimise automaatseks käivitamiseks leida WiFi-ühenduse.<br/> <br/> Nõuanne: sõnastikke saate alla laadida ja eemaldada, tehes valiku <b>Keel ja sisestamine</b> mobiilseadme menüüs <b>Seaded</b>."</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">([{&:</string> + <!-- Symbols that are normally followed by a space (used to add an auto-space after these) --> + <string name="symbols_followed_by_space">.,;:!?)]}&</string> + <!-- Symbols that separate words --> + <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) --> + <string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</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">"आपके मोबाइल उपकरण पर चयनित भाषा में डिक्शनरी उपलब्ध है.<br/> आपके लेखन अनुभव को बेहतर बनाने के लिए हम <xliff:g id="LANGUAGE">%1$s</xliff:g> डिक्शनरी को <b>डाउनलोड करने</b> की अनुशंसा करते हैं.<br/> <br/> 3G पर डाउनलोड होने में एक या दो मिनट लग सकते हैं. यदि आपके पास <b>असीमित डेटा प्लान</b> नहीं है, तो शुल्क लग सकते हैं.<br/> यदि आप अपने डेटा प्लान के बारे में सुनिश्चित नहीं हैं, तो हम अपने आप डाउनलोड प्रारंभ करने के लिए Wi-Fi कनेक्शन ढूंढने की अनुशंसा करते हैं.<br/> <br/> युक्ति: आप अपने मोबाइल उपकरण पर <b>सेटिंग</b> मेनू में <b>भाषा और इनपुट</b> पर जाकर डिक्शनरी डाउनलोड कर सकते हैं और निकाल सकते हैं."</string> + <string name="should_download_over_metered_prompt" msgid="2878629598667658845">"आपके मोबाइल उपकरण पर चयनित भाषा में डिक्शनरी उपलब्ध है.<br/> आपके लेखन अनुभव को बेहतर बनाने के लिए हम <xliff:g id="LANGUAGE">%1$s</xliff:g> डिक्शनरी को <b>डाउनलोड करने</b> की अनुशंसा करते हैं.<br/> <br/> 3G पर डाउनलोड होने में एक या दो मिनट लग सकते हैं. यदि आपके पास <b>असीमित डेटा प्लान</b> नहीं है, तो शुल्क लग सकते हैं.<br/> यदि आप अपने डेटा प्लान के बारे में सुनिश्चित नहीं हैं, तो हम अपने आप डाउनलोड प्रारंभ करने के लिए Wi-Fi कनेक्शन ढूंढने की अनुशंसा करते हैं.<br/> <br/> युक्ति: आप अपने मोबाइल उपकरण पर <b>सेटिंग</b> मेनू में <b>भाषा और अक्षर</b> पर जाकर डिक्शनरी डाउनलोड कर सकते हैं और निकाल सकते हैं."</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">.,;:!?)]}&։՝</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">"	 \n"()[]{}*&<>+=|.,;:!?/_\"։՝</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">"თქვენ მიერ მობილურ მოწყობილობაზე არჩეული ენისათვის ხელმისაწვდომია ლექსიკონი.<br/> გირჩევთ, <b>ჩამოტვირთოთ</b> <xliff:g id="LANGUAGE">%1$s</xliff:g> ლექსიკონი, რათა გაიმარტივოთ ტექსტის შეყვანა.<br/> <br/> ჩამოტვირთვას შესაძლოა დაჭირდეს ერთი ან ორი წუთი 3G სისწრაფეზე. თუ ულიმიტო არ გაქვთ <b> მობილური ინტერნეტის ტარიფი</b>.<br/&gt, შესაძლოა ჩამოტვირთვა დამატებით გადასახადებთან იყოს დაკავშირებული; თუ არ ხართ დარწმუნებული მობილური ინტერნეტის აქტიური ტარიფის შესახებ, გირჩევთ იპოვოთ Wi-Fi კავშირი და ავტომატურად დაიწყოთ ჩამოტვირთვა.<br/> <br/> რჩევა: ლექსიკონების ჩამოტვირთვა და ამოშლა შესაძლებელია სექციიდან <b>ენა და შეყვანა</b> სექციიდან, თქვენი მობილური მოწყობილობის <b>პარამეტრების</b> მენიუში."</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">"Өөрийн Хэл & оруулах тохиргоон дотроос \"<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 оруулах тохиргоонд аль хэдийн идэвхжүүлсэн байгаа учир энэ алхам хийгдсэн. Дараагийн алхам руу!"</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">"Таны мобайль төхөөрөмж дээр сонгосон хэлэнд толь бичиг байна.<br/> Тус <xliff:g id="LANGUAGE">%1$s</xliff:g> толь бичгийг <b>татаж аван</b> зөв бичилтээ сайжруулахыг бид зөвлөж байна.<br/> <br/> Татаж авахад 3G сүлжээгээр нэг хоёр минут болно. Танд <b>хязгааргүй дата эрх</b> байхгүй бол нэмэлт төлбөр гарч болно.<br/> Та дата эрхийнхээ талаар сайн мэдэхгүй байгаа бол Wi-Fi холболттой газар очин автоматаар татаж авахыг зөвлөж байна.<br/> <br/> Зөвлөмж: Та өөрийн мобайль төхөөрөмжийн <b>Тохиргоо</b> цэсний <b>Хэл & оруулах</b> руу очиж толь бичиг татаж авах буюу устгаж болно."</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 & 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 & 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.<br/> Kami mengesyorkan <b>memuat turun</b> kamus <xliff:g id="LANGUAGE">%1$s</xliff:g> untuk memperbaik pengalaman menaip anda.<br/> <br/> Muat turun boleh mengambil masa seminit atau dua melalui 3G. Caj mungkin dikenakan jika anda tidak mempunyai <b>pelan data tanpa had</b>.<br/> Jika anda tidak pasti jenis pelan data yang anda miliki, kami mengesyorkan agar anda mencari sambungan Wi-Fi untuk mula memuat turun secara automatik.<br/> <br/> Petua: Anda boleh memuat turun dan mengalih keluar kamus dengan pergi ke menu <b>Bahasa & input</b> dalam <b>Tetapan</b> 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">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</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="\\|,¦" /> - </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="\\|,¦" + 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=""" + latin:additionalMoreKeys=""" + 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=""" - latin:moreKeys="!fixedColumnOrder!4,!text/double_quotes,",!text/single_quotes" - latin:keyStyle="hasShiftedLetterHintStyle" /> + latin:keyLabel=""" + 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="<" latin:additionalMoreKeys="<" - latin:moreKeys="!fixedColumnOrder!4,‹,⁤,«" /> + latin:keyStyle="hasShiftedLetterHintStyle" /> <Key latin:keyLabel="." + latin:keyHintLabel=">" latin:additionalMoreKeys=">" - latin:moreKeys="!fixedColumnOrder!4,›,⁥,»" /> - <!-- U+00BF: "¿" INVERTED QUESTION MARK --> + latin:keyStyle="hasShiftedLetterHintStyle" /> <Key latin:keyLabel="/" + latin:keyHintLabel="\?" latin:additionalMoreKeys="\?" - latin:moreKeys="¿" /> + 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="<" - latin:additionalMoreKeys="<" - latin:moreKeys="!fixedColumnOrder!4,‹,≤,«" - latin:keyStyle="hasShiftedLetterHintStyle" /> + latin:keyLabel="<" + latin:moreKeys="!fixedColumnOrder!3,‹,≤,«" /> <Key - latin:keyLabel="." - latin:keyHintLabel=">" - latin:additionalMoreKeys=">" - latin:moreKeys="!fixedColumnOrder!4,›,≥,»" - latin:keyStyle="hasShiftedLetterHintStyle" /> - <!-- U+00BF: "¿" INVERTED QUESTION MARK --> + latin:keyLabel=">" + latin:moreKeys="!fixedColumnOrder!3,›,≥,»" /> <Key - latin:keyLabel="/" - latin:keyHintLabel="\?" - latin:additionalMoreKeys="\?" - latin:moreKeys="¿" - 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=""" - 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="¬" - latin:keyStyle="hasShiftedLetterHintStyle" /> - <!-- U+00A1: "¡" NVERTED EXCLAMATION MARK --> - <Key - latin:keyLabel="1" - latin:keyHintLabel="!" - latin:additionalMoreKeys="!" - latin:moreKeys="¡,!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="&" - latin:additionalMoreKeys="&" - 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="&" + latin:additionalMoreKeys="&" + 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="–,—,·" /> + <!-- 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="∞,≠,≈" /> </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="٬" - latin:keyHintLabel="&" - latin:keyLabelFlags="hasPopupHint|hasShiftedLetterHint" - latin:moreKeys="&" /> - </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="٫" - latin:keyHintLabel="\#" - latin:keyLabelFlags="hasPopupHint|hasShiftedLetterHint" - latin:moreKeys="\#" /> - </case> - <default> - <Key - latin:keyLabel="&" /> - </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="_,–,—,·" /> - <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="≠,≈" /> - <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="•" - latin:moreKeys="!text/more_keys_for_bullet" /> - <!-- U+221A: "√" SQUARE ROOT --> - <Key - latin:keyLabel="√" /> - <!-- U+03C0: "π" GREEK SMALL LETTER PI - U+03A0: "Π" GREEK CAPITAL LETTER PI --> - <Key - latin:keyLabel="π" - latin:moreKeys="Π" /> - <!-- U+00F7: "÷" DIVISION SIGN --> - <Key - latin:keyLabel="÷" /> - <!-- U+00D7: "×" MULTIPLICATION SIGN --> - <Key - latin:keyLabel="×" /> - <!-- U+00A7: "§" SECTION SIGN - U+00B6: "¶" PILCROW SIGN --> - <Key - latin:keyLabel="§" - latin:moreKeys="¶" /> - <!-- U+0394: "Δ" GREEK CAPITAL LETTER DELTA --> - <Key - latin:keyLabel="Δ" /> -</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="↑,↓,←,→" /> - <!-- U+00B0: "°" DEGREE SIGN - U+2032: "′" PRIME - U+2033: "″" DOUBLE PRIME --> - <Key - latin:keyLabel="°" - latin:moreKeys="′,″" /> - <!-- U+00B1: "±" PLUS-MINUS SIGN - U+221E: "∞" INFINITY --> - <Key - latin:keyLabel="±" - latin:moreKeys="∞" /> - <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="©" /> - <!-- U+00AE: "®" REGISTERED SIGN --> - <Key - latin:keyLabel="®" /> - <!-- U+2122: "™" TRADE MARK SIGN --> - <Key - latin:keyLabel="™" /> - <!-- U+2105: "℅" CARE OF --> - <Key - latin:keyLabel="℅" /> - <include - latin:keyboardLayout="@xml/keys_square_brackets" /> - <!-- U+00A1: "¡" INVERTED EXCLAMATION MARK --> - <Key - latin:keyLabel="¡" /> - <!-- U+00BF: "¿" INVERTED QUESTION MARK --> - <Key - latin:keyLabel="¿" /> -</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="¡" /> + <!-- U+00BF: "¿" INVERTED QUESTION MARK --> + <Key + latin:keyLabel="¿" /> <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|‍" - 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=""" - 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="ँ" - latin:moreKeys="ॅ" + latin:keyLabel="ं" 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="ॅ" /> + </case> + <default> + <key-style + latin:styleName="moreKeysDevanagariSignCandrabindu" /> + </default> + </switch> + <!-- U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU --> + <Key + latin:keyStyle="moreKeysDevanagariSignCandrabindu" + latin:keyLabel="ँ" + 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="ॽ,॰,ऽ" /> + </case> + <default> + <key-style + latin:styleName="moreKeysDevanagariSignNukta" /> + </default> + </switch> + <!-- U+093C: "़" DEVANAGARI SIGN NUKTA --> <Key + latin:keyStyle="moreKeysDevanagariSignNukta" latin:keyLabel="़" - latin:moreKeys="ॽ,॰,ऽ" 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="ॉ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0902: "ं" DEVANAGARI SIGN ANUSVARA --> - <Key - latin:keyLabel="ं" - 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="ॄ" /> + </case> + <case + latin:keyboardLayoutSet="nepali_traditional" + > + <!-- U+0913: "ओ" DEVANAGARI LETTER O --> + <key-style + latin:styleName="moreKeysDevanagariVowelSignVocalicR" + latin:moreKeys="ओ" /> + </case> + <default> + <key-style + latin:styleName="moreKeysDevanagariVowelSignVocalicR" /> + </default> + </switch> + <!-- U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R --> + <Key + latin:keyStyle="moreKeysDevanagariVowelSignVocalicR" + latin:keyLabel="ृ" + 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="ौ" - latin:moreKeys="ौं,%" - latin:keyHintLabel="1" - latin:additionalMoreKeys="१,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="ै" - latin:moreKeys="ैं,%" - latin:keyHintLabel="2" - latin:additionalMoreKeys="२,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="ा" - latin:moreKeys="ां,ाँ,%" - latin:keyHintLabel="3" - latin:additionalMoreKeys="३,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="ी" - latin:moreKeys="ीं,%" - latin:keyHintLabel="4" - latin:additionalMoreKeys="४,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="ू" - latin:moreKeys="ूं,ूँ,%" - latin:keyHintLabel="5" - latin:additionalMoreKeys="५,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="ो" - latin:moreKeys="ों,ॉ,ॊ" - latin:keyLabelFlags="fontNormal" /> - <!-- U+0947: "े" DEVANAGARI VOWEL SIGN E - U+0947/U+0902: "ें" DEVANAGARI VOWEL SIGN E/DEVANAGARI SIGN ANUSVARA --> - <Key - latin:keyLabel="े" - latin:moreKeys="ें" - latin:keyLabelFlags="fontNormal" /> - <!-- U+094D: "्" DEVANAGARI SIGN VIRAMA --> - <Key - latin:keyLabel="्" - latin:keyLabelFlags="fontNormal" /> - <!-- U+093F: "ि" DEVANAGARI VOWEL SIGN I - U+093F/U+0902: "िं" DEVANAGARI VOWEL SIGN I/DEVANAGARI SIGN ANUSVARA --> - <Key - latin:keyLabel="ि" - latin:moreKeys="िं" - 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="ु" - latin:moreKeys="ुं,ुँ" - 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="ृ" - latin:moreKeys="ॄ" + <!-- U+094D: "्" DEVANAGARI SIGN VIRAMA --> + <key-style + latin:styleName="baseKeyDevanagariSignVirama" + latin:keyLabel="्" 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="ः" 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="ां,ाँ,%" /> + </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="ा" + 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="ैं,%" /> + </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="श्र" /> + </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="ै" + 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="ौं,%" /> + </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="ौ" + 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="ें" /> + </case> + <case + latin:keyboardLayoutSet="nepali_traditional" + > + <!-- U+0903: "ः" DEVANAGARI SIGN VISARGA + U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA --> + <key-style + latin:styleName="moreKeysDevanagariVowelSignE" + latin:moreKeys="ः,ऽ" /> + </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="े" + 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="िं" /> + </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="ि" + 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="ीं,%" /> + </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="ी" + 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="ों,ॉ,ॊ" /> + </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="ो" + 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="ुं,ुँ" /> + </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="ु" + 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="ूं,ूँ,%" /> + </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="ू" + 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="շ" + 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="խ" + 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="◌ँ" - latin:code="0x0901" - latin:moreKeys="◌ॅ|ॅ" + latin:keyLabel="◌ं" + 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="◌ॅ|ॅ" /> + </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="◌़" - latin:code="0x093C" - latin:moreKeys="◌ॽ|ॽ,◌॰|॰,◌ऽ|ऽ" + latin:keyStyle="moreKeysDevanagariSignCandrabindu" + latin:keyLabel="◌ँ" + 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="◌ॽ|ॽ,◌॰|॰,◌ऽ|ऽ" /> + </case> + <default> + <key-style + latin:styleName="moreKeysDevanagariSignNukta" /> + </default> + </switch> + <!-- U+25CC: "◌" DOTTED CIRCLE + U+093C: "़" DEVANAGARI SIGN NUKTA --> + <Key + latin:keyStyle="moreKeysDevanagariSignNukta" + latin:keyLabel="◌़" + 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="◌ॉ" latin:code="0x0949" latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> - <!-- U+25CC: "◌" DOTTED CIRCLE - U+0902: "ं" DEVANAGARI SIGN ANUSVARA --> - <Key - latin:keyLabel="◌ं" - 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="◌ॄ|ॄ" /> + </case> + <case + latin:keyboardLayoutSet="nepali_traditional" + > + <!-- U+0913: "ओ" DEVANAGARI LETTER O --> + <key-style + latin:styleName="moreKeysDevanagariVowelSignVocalicR" + latin:moreKeys="ओ" /> + </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="◌ृ" + 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="£" /> 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,℅,™,®,©,§,¶,\\,,•,°,′,″,↑,↓,←,→,…,!text/more_keys_for_bullet,Δ,Π,π" /> +</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="։" + latin:keyLabelFlags="hasPopupHint" + latin:backgroundType="functional" + latin:moreKeys="!text/more_keys_for_punctuation" /> + <!-- U+055D: "՝" ARMENIAN COMMA --> + <Key + latin:keyLabel="՝" + 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="◌ौ" - latin:code="0x094C" - latin:moreKeys="◌ौं|ौं,%" - latin:keyHintLabel="1" - latin:additionalMoreKeys="१,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="◌ै" - latin:code="0x0948" - latin:moreKeys="◌ैं|ैं,%" - latin:keyHintLabel="2" - latin:additionalMoreKeys="२,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="◌ा" - latin:code="0x093E" - latin:moreKeys="◌ां|ां,◌ाँ|ाँ,%" - latin:keyHintLabel="3" - latin:additionalMoreKeys="३,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="◌ी" - latin:code="0x0940" - latin:moreKeys="◌ीं|ीं,%" - latin:keyHintLabel="4" - latin:additionalMoreKeys="४,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="◌ू" - latin:code="0x0942" - latin:moreKeys="◌ूं|ूं,◌ूँ|ूँ,%" - latin:keyHintLabel="5" - latin:additionalMoreKeys="५,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="◌ो" - latin:code="0x094B" - latin:moreKeys="◌ों|ों,◌ॉ,ॊ|ॉ,ॊ" - 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="◌े" - latin:code="0x0947" - latin:moreKeys="◌ें|ें" - latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> - <!-- U+25CC: "◌" DOTTED CIRCLE - U+094D: "्" DEVANAGARI SIGN VIRAMA --> - <Key - latin:keyLabel="◌्" - 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="ि◌" - latin:code="0x093F" - latin:moreKeys="ि◌ं|िं" - 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="◌ु" - latin:code="0x0941" - latin:moreKeys="◌ुं|ुं,◌ुँ|ुँ" - 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="«" latin:code="0x00BB" + latin:backgroundType="functional" latin:moreKeys="!text/more_keys_for_less_than" /> <Key latin:keyLabel="»" latin:code="0x00AB" + latin:backgroundType="functional" latin:moreKeys="!text/more_keys_for_greater_than" /> </case> <default> <Key latin:keyLabel="<" latin:code="!code/key_less_than" + latin:backgroundType="functional" latin:moreKeys="!text/more_keys_for_less_than" /> <Key latin:keyLabel=">" 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="\\|,¦" /> + 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="¦" /> + 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,",!text/single_quotes" /> + latin:additionalMoreKeys=""" + 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="<" /> + latin:additionalMoreKeys="<" /> <Key latin:keyLabel="." - latin:moreKeys=">" /> - <!-- U+00BF: "¿" INVERTED QUESTION MARK --> + latin:additionalMoreKeys=">" /> <Key latin:keyLabel="/" - latin:moreKeys="\?,¿" /> + 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=">" latin:moreKeys="!fixedColumnOrder!3,›,≥,»" /> - <!-- U+00BF: "¿" INVERTED QUESTION MARK --> <Key latin:keyLabel="\?" - latin:moreKeys="¿" /> + 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="•" - latin:moreKeys="!text/more_keys_for_bullet" /> - <!-- U+00B1: "±" PLUS-MINUS SIGN --> - <Key - latin:keyLabel="±" /> - <!-- U+00AC: "¬" NOT SIGN --> - <Key - latin:keyLabel="¬" /> - <!-- U+00A6: "¦" BROKEN BAR --> - <Key - latin:keyLabel="¦" /> - <!-- U+221A: "√" SQUARE ROOT --> - <Key - latin:keyLabel="√" /> - <!-- U+03C0: "π" GREEK SMALL LETTER PI - U+03A0: "Π" GREEK CAPITAL LETTER PI --> - <Key - latin:keyLabel="π" - latin:moreKeys="Π" /> - <!-- U+03CC: "σ" GREEK SMALL LETTER SIGMA - U+03A3: "Σ" GREEK CAPITAL LETTER SIGMA --> - <Key - latin:keyLabel="σ" - latin:moreKeys="Σ" /> - <!-- U+00B5: "µ" MICRO SIGN --> - <Key - latin:keyLabel="µ" /> - <!-- U+00F7: "÷" DIVISION SIGN --> - <Key - latin:keyLabel="÷" /> - <!-- U+00D7: "×" MULTIPLICATION SIGN --> - <Key - latin:keyLabel="×" /> -</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="£" /> - <!-- U+00A2: "¢" CENT SIGN --> - <Key - latin:keyLabel="¢" /> - <!-- U+20AC: "€" EURO SIGN --> - <Key - latin:keyLabel="€" /> - <!-- U+00A5: "¥" YEN SIGN --> - <Key - latin:keyLabel="¥" /> - <!-- U+00A4: "¤" CURRENCY SIGN --> - <Key - latin:keyLabel="¤" /> - <!-- U+00B0: "°" DEGREE SIGN - U+2032: "′" PRIME - U+2033: "″" DOUBLE PRIME --> - <Key - latin:keyLabel="°" - latin:moreKeys="′,″" /> - <!-- U+2260: "≠" NOT EQUAL TO --> - <Key - latin:keyLabel="≠" /> - <!-- U+2248: "≈" ALMOST EQUAL TO --> - <Key - latin:keyLabel="≈" /> - <!-- U+221E: "∞" INFINITY --> - <Key - latin:keyLabel="∞" /> -</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="™" /> - <!-- U+00AE: "®" REGISTERED SIGN --> - <Key - latin:keyLabel="®" /> - <!-- U+00A9: "©" COPYRIGHT SIGN --> - <Key - latin:keyLabel="©" /> - <!-- U+00B6: "¶" PILCROW SIGN --> - <Key - latin:keyLabel="¶" /> - <!-- U+00A7: "§" SECTION SIGN --> - <Key - latin:keyLabel="§" /> - <!-- U+2191: "↑" UPWARDS ARROW - U+2193: "↓" DOWNWARDS ARROW - U+2190: "←" LEFTWARDS ARROW - U+2192: "→" RIGHTWARDS ARROW --> - <Key - latin:keyLabel="↑" - latin:moreKeys="↓" /> - <Key - latin:keyLabel="←" - latin:moreKeys="→" /> -</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="◌ृ" - latin:code="0x0943" - latin:moreKeys="◌ॄ|ॄ" + U+094D: "्" DEVANAGARI SIGN VIRAMA --> + <key-style + latin:styleName="baseKeyDevanagariSignVirama" + latin:keyLabel="◌्" + 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="◌ः" 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="◌ां|ां,◌ाँ|ाँ,%" /> + </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="◌ा" + 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="◌ैं|ैं,%" /> + </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="श्र" /> + </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="◌ै" + 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="◌ौं|ौं,%" /> + </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="◌ौ" + 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="◌ें|ें" /> + </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="◌ः|ः,ऽ" /> + </case> + <default> + <key-style + latin:styleName="moreKeysDevanagariVowelSignE" /> + </default> + </switch> + <key-style + latin:styleName="baseKeyDevanagariVowelSignE" + latin:parentStyle="moreKeysDevanagariVowelSignE" + latin:keyLabel="◌े" + 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="ि◌ं|िं" /> + </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="◌ि" + 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="◌ीं|ीं,%" /> + </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="◌ी" + 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="◌ों|ों,◌ॉ|ॉ,◌ॊ|ॊ" /> + </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="◌ो" + 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="◌ुं|ुं,◌ुँ|ुँ" /> + </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="◌ु" + 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="◌ूं|ूं,◌ूँ|ूँ,%" /> + </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="◌ू" + 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="։" + 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="„" - latin:moreKeys="‚" - latin:backgroundType="functional" /> - <include - latin:keyXPos="25%p" - latin:keyboardLayout="@xml/key_space" /> - <!-- U+2026: "…" HORIZONTAL ELLIPSIS --> - <Key - latin:keyLabel="…" - 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="է" + latin:keyHintLabel="1" + latin:additionalMoreKeys="1" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0569: "թ" ARMENIAN SMALL LETTER TO --> + <Key + latin:keyLabel="թ" + latin:keyHintLabel="2" + latin:additionalMoreKeys="2" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0583: "փ" ARMENIAN SMALL LETTER PIWR --> + <Key + latin:keyLabel="փ" + latin:keyHintLabel="3" + latin:additionalMoreKeys="3" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0571: "ձ" ARMENIAN SMALL LETTER JA --> + <Key + latin:keyLabel="ձ" + latin:keyHintLabel="4" + latin:additionalMoreKeys="4" + latin:keyLabelFlags="fontNormal" /> + <!-- U+057B: "ջ" ARMENIAN SMALL LETTER JHEH --> + <Key + latin:keyLabel="ջ" + latin:keyHintLabel="5" + latin:additionalMoreKeys="5" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0580: "ր" ARMENIAN SMALL LETTER REH --> + <Key + latin:keyLabel="ր" + latin:keyHintLabel="6" + latin:additionalMoreKeys="6" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0579: "չ" ARMENIAN SMALL LETTER CHA --> + <Key + latin:keyLabel="չ" + latin:keyHintLabel="7" + latin:additionalMoreKeys="7" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0573: "ճ" ARMENIAN SMALL LETTER CHEH --> + <Key + latin:keyLabel="ճ" + latin:keyHintLabel="8" + latin:additionalMoreKeys="8" + latin:keyLabelFlags="fontNormal" /> + <!-- U+056A: "ժ" ARMENIAN SMALL LETTER ZHE --> + <Key + latin:keyLabel="ժ" + latin:keyHintLabel="9" + latin:additionalMoreKeys="9" + latin:keyLabelFlags="fontNormal" /> + <!-- U+056E: "ծ" ARMENIAN SMALL LETTER CA --> + <Key + latin:keyLabel="ծ" + 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="ք" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0578: "ո" ARMENIAN SMALL LETTER VO --> + <Key + latin:keyLabel="ո" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0565: "ե" ARMENIAN SMALL LETTER ECH + U+0587: "և" ARMENIAN SMALL LIGATURE ECH YIWN --> + <Key + latin:keyLabel="ե" + latin:moreKeys="և" + latin:keyLabelFlags="fontNormal" /> + <!-- U+057C: "ռ" ARMENIAN SMALL LETTER RA --> + <Key + latin:keyLabel="ռ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+057F: "տ" ARMENIAN SMALL LETTER TIWN --> + <Key + latin:keyLabel="տ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0568: "ը" ARMENIAN SMALL LETTER ET --> + <Key + latin:keyLabel="ը" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0582: "ւ" ARMENIAN SMALL LETTER YIWN --> + <Key + latin:keyLabel="ւ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+056B: "ի" ARMENIAN SMALL LETTER INI --> + <Key + latin:keyLabel="ի" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0585: "օ" ARMENIAN SMALL LETTER OH --> + <Key + latin:keyLabel="օ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+057A: "պ" ARMENIAN SMALL LETTER PEH --> + <Key + latin:keyLabel="պ" + 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="๑" + latin:keyLabel="ա" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E52: "๒" THAI DIGIT TWO --> + <!-- U+057D: "ս" ARMENIAN SMALL LETTER SEH --> <Key - latin:keyLabel="๒" + latin:keyLabel="ս" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E53: "๓" THAI DIGIT THREE --> + <!-- U+0564: "դ" ARMENIAN SMALL LETTER DA --> <Key - latin:keyLabel="๓" + latin:keyLabel="դ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E54: "๔" THAI DIGIT FOUR --> + <!-- U+0586: "ֆ" ARMENIAN SMALL LETTER FEH --> <Key - latin:keyLabel="๔" + latin:keyLabel="ֆ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E55: "๕" THAI DIGIT FIVE --> + <!-- U+0563: "գ" ARMENIAN SMALL LETTER GIM --> <Key - latin:keyLabel="๕" + latin:keyLabel="գ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E56: "๖" THAI DIGIT SIX --> + <!-- U+0570: "հ" ARMENIAN SMALL LETTER HO --> <Key - latin:keyLabel="๖" + latin:keyLabel="հ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E57: "๗" THAI DIGIT SEVEN --> + <!-- U+0575: "յ" ARMENIAN SMALL LETTER YI --> <Key - latin:keyLabel="๗" + latin:keyLabel="յ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E58: "๘" THAI DIGIT EIGHT --> + <!-- U+056F: "կ" ARMENIAN SMALL LETTER KEN --> <Key - latin:keyLabel="๘" + latin:keyLabel="կ" latin:keyLabelFlags="fontNormal" /> - <!-- U+0E59: "๙" THAI DIGIT NINE --> + <!-- U+056C: "լ" ARMENIAN SMALL LETTER LIWN --> <Key - latin:keyLabel="๙" - latin:keyLabelFlags="fontNormal" /> - <!-- U+0E50: "๐" THAI DIGIT ZERO --> - <Key - latin:keyLabel="๐" + latin:keyLabel="լ" 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="զ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0572: "ղ" ARMENIAN SMALL LETTER GHAD --> + <Key + latin:keyLabel="ղ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0581: "ց" ARMENIAN SMALL LETTER CO --> + <Key + latin:keyLabel="ց" + latin:keyLabelFlags="fontNormal" /> + <!-- U+057E: "վ" ARMENIAN SMALL LETTER VEW --> + <Key + latin:keyLabel="վ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0562: "բ" ARMENIAN SMALL LETTER BEN --> + <Key + latin:keyLabel="բ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0576: "ն" ARMENIAN SMALL LETTER NOW --> + <Key + latin:keyLabel="ն" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0574: "մ" ARMENIAN SMALL LETTER MEN --> + <Key + latin:keyLabel="մ" + 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="भ" 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="घ" @@ -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="१,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="२,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="३,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="४,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="५,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="ब" 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="प" 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="ऑ" 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="ण" @@ -56,10 +56,10 @@ latin:keyLabel="ष" 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="ञ" @@ -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="य़" 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|‍" /> + <!-- U+17D7: "ៗ" KHMER SIGN LEK TOO + U+200C: ZERO WIDTH NON-JOINER --> + <Key + latin:keyLabel="ៗ" + latin:moreKeys="!icon/zwnj_key|‌" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D1: "៑" KHMER SIGN VIRIAM --> + <Key + latin:keyLabel=""" + latin:keyHintLabel="៑" + latin:moreKeys="៑" /> + <!-- U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL + U+20AC: "€" EURO SIGN --> + <Key + latin:keyLabel="៛" + latin:keyHintLabel="$" + latin:moreKeys="$,€" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D6: "៖" KHMER SIGN CAMNUC PII KUUH --> + <Key + latin:keyLabel="%" + latin:keyHintLabel="៖" + latin:moreKeys="៖" /> + <!-- U+17CD: "៍" KHMER SIGN TOANDAKHIAT + U+17D9: "៙" KHMER SIGN PHNAEK MUAN --> + <Key + latin:keyLabel="៍" + latin:keyHintLabel="៙" + latin:moreKeys="៙" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D0: "័" KHMER SIGN SAMYOK SANNYA + U+17DA: "៚" KHMER SIGN KOOMUUT --> + <Key + latin:keyLabel="័" + latin:keyHintLabel="៚" + latin:moreKeys="៚" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CF: "៏" KHMER SIGN AHSDA --> + <Key + latin:keyLabel="៏" + latin:keyHintLabel="*" + latin:moreKeys="*" + latin:keyLabelFlags="fontNormal" /> + <!-- U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK --> + <Key + latin:keyLabel="(" + latin:keyHintLabel="{" + latin:moreKeys="{,«" /> + <!-- U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK --> + <Key + latin:keyLabel=")" + latin:keyHintLabel="}" + latin:moreKeys="},»" /> + <!-- U+17CC: "៌" KHMER SIGN ROBAT + U+00D7: "×" MULTIPLICATION SIGN --> + <Key + latin:keyLabel="៌" + latin:keyHintLabel="×" + latin:moreKeys="×" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CE: "៎" KHMER SIGN KAKABAT --> + <Key + latin:keyLabel="៎" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+17E1: "១" KHMER DIGIT ONE + U+17F1: "៱" KHMER SYMBOL LEK ATTAK MUOY --> + <Key + latin:keyLabel="១" + latin:keyHintLabel="1" + latin:additionalMoreKeys="1" + latin:moreKeys="៱" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E2: "២" KHMER DIGIT TWO + U+17F2: "៲" KHMER SYMBOL LEK ATTAK PII --> + <Key + latin:keyLabel="២" + latin:keyHintLabel="2" + latin:additionalMoreKeys="2" + latin:moreKeys="៲" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E3: "៣" KHMER DIGIT THREE + U+17F3: "៳" KHMER SYMBOL LEK ATTAK BEI --> + <Key + latin:keyLabel="៣" + latin:keyHintLabel="3" + latin:additionalMoreKeys="3" + latin:moreKeys="៳" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E4: "៤" KHMER DIGIT FOUR + U+17F4: "៴" KHMER SYMBOL LEK ATTAK BUON --> + <Key + latin:keyLabel="៤" + latin:keyHintLabel="4" + latin:additionalMoreKeys="4" + latin:moreKeys="៴" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E5: "៥" KHMER DIGIT FIVE + U+17F5: "៵" KHMER SYMBOL LEK ATTAK PRAM --> + <Key + latin:keyLabel="៥" + latin:keyHintLabel="5" + latin:additionalMoreKeys="5" + latin:moreKeys="៵" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E6: "៦" KHMER DIGIT SIX + U+17F6: "៶" KHMER SYMBOL LEK ATTAK PRAM-MUOY --> + <Key + latin:keyLabel="៦" + latin:keyHintLabel="6" + latin:additionalMoreKeys="6" + latin:moreKeys="៶" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E7: "៧" KHMER DIGIT SEVEN + U+17F7: "៷" KHMER SYMBOL LEK ATTAK PRAM-PII --> + <Key + latin:keyLabel="៧" + latin:keyHintLabel="7" + latin:additionalMoreKeys="7" + latin:moreKeys="៷" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E8: "៨" KHMER DIGIT EIGHT + U+17F8: "៸" KHMER SYMBOL LEK ATTAK PRAM-BEI --> + <Key + latin:keyLabel="៨" + latin:keyHintLabel="8" + latin:additionalMoreKeys="8" + latin:moreKeys="៸" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E9: "៩" KHMER DIGIT NINE + U+17F9: "៹" KHMER SYMBOL LEK ATTAK PRAM-BUON --> + <Key + latin:keyLabel="៩" + latin:keyHintLabel="9" + latin:additionalMoreKeys="9" + latin:moreKeys="៹" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E0: "០" KHMER DIGIT ZERO + U+17F0: "៰" KHMER SYMBOL LEK ATTAK SON --> + <Key + latin:keyLabel="០" + latin:keyHintLabel="0" + latin:additionalMoreKeys="0" + latin:moreKeys="៰" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A5: "ឥ" KHMER INDEPENDENT VOWEL QI + U+17A6: "ឦ" KHMER INDEPENDENT VOWEL QII --> + <Key + latin:keyLabel="ឥ" + latin:keyHintLabel="ឦ" + latin:moreKeys=",ឦ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B2: "ឲ" KHMER INDEPENDENT VOWEL QOO TYPE TWO + U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE --> + <Key + latin:keyLabel="ឲ" + latin:keyHintLabel="ឱ" + latin:moreKeys="ឱ" + 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="ឈ" + latin:keyHintLabel="ៜ" + latin:moreKeys="ៜ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BA: "ឺ" KHMER VOWEL SIGN YY + U+17DD: "៝" KHMER SIGN ATTHACAN --> + <Key + latin:keyLabel="ឺ" + latin:keyHintLabel="៝" + latin:moreKeys="៝" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C2: "ែ" KHMER VOWEL SIGN AE --> + <Key + latin:keyLabel="ែ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17AC: "ឬ" KHMER INDEPENDENT VOWEL RYY + U+17AB: "ឫ" KHMER INDEPENDENT VOWEL RY --> + <Key + latin:keyLabel="ឬ" + latin:keyHintLabel="ឫ" + latin:moreKeys="ឫ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1791: "ទ" KHMER LETTER TO --> + <Key + latin:keyLabel="ទ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BD: "ួ" KHMER VOWEL SIGN UA --> + <Key + latin:keyLabel="ួ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BC: "ូ" KHMER VOWEL SIGN UU --> + <Key + latin:keyLabel="ូ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B8: "ី" KHMER VOWEL SIGN II --> + <Key + latin:keyLabel="ី" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C5: "ៅ" KHMER VOWEL SIGN AU --> + <Key + latin:keyLabel="ៅ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1797: "ភ" KHMER LETTER PHO --> + <Key + latin:keyLabel="ភ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BF: "ឿ" KHMER VOWEL SIGN YA --> + <Key + latin:keyLabel="ឿ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI --> + <Key + latin:keyLabel="ឰ" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+1786: "ឆ" KHMER LETTER CHA --> + <Key + latin:keyLabel="ឆ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B9: "ឹ" KHMER VOWEL SIGN Y --> + <Key + latin:keyLabel="ឹ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C1: "េ" KHMER VOWEL SIGN E --> + <Key + latin:keyLabel="េ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179A: "រ" KHMER LETTER RO --> + <Key + latin:keyLabel="រ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178F: "ត" KHMER LETTER TA --> + <Key + latin:keyLabel="ត" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1799: "យ" KHMER LETTER YO --> + <Key + latin:keyLabel="យ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BB: "ុ" KHMER VOWEL SIGN U --> + <Key + latin:keyLabel="ុ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B7: "ិ" KHMER VOWEL SIGN I --> + <Key + latin:keyLabel="ិ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C4: "ោ" KHMER VOWEL SIGN OO --> + <Key + latin:keyLabel="ោ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1795: "ផ" KHMER LETTER PHA --> + <Key + latin:keyLabel="ផ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C0: "ៀ" KHMER VOWEL SIGN IE --> + <Key + latin:keyLabel="ៀ" + 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="ឪ" + latin:keyHintLabel="ឧ" + latin:moreKeys="ឧ,ឱ,ឳ,ឩ,ឨ" + 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="ាំ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+17C3: "ៃ" KHMER VOWEL SIGN AI --> + <Key + latin:keyLabel="ៃ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178C: "ឌ" KHMER LETTER DO --> + <Key + latin:keyLabel="ឌ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1792: "ធ" KHMER LETTER THO --> + <Key + latin:keyLabel="ធ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A2: "អ" KHMER LETTER QA --> + <Key + latin:keyLabel="អ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C7: "ះ" KHMER SIGN REAHMUK + U+17C8: "ៈ" KHMER SIGN YUUKALEAPINTU;--> + <Key + latin:keyLabel="ះ" + latin:keyHintLabel="ៈ" + latin:moreKeys="ៈ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1789: "ញ" KHMER LETTER NYO --> + <Key + latin:keyLabel="ញ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1782: "គ" KHMER LETTER KO + U+179D: "ឝ" KHMER LETTER SHA --> + <Key + latin:keyLabel="គ" + latin:keyHintLabel="ឝ" + latin:moreKeys="ឝ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A1: "ឡ" KHMER LETTER LA --> + <Key + latin:keyLabel="ឡ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C4/U+17C7: "ោះ" KHMER VOWEL SIGN OO/KHMER SIGN REAHMUK --> + <Key + latin:keyLabel="ោះ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C9: "៉" KHMER SIGN MUUSIKATOAN --> + <Key + latin:keyLabel="៉" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17AF: "ឯ" KHMER INDEPENDENT VOWEL QE --> + <Key + latin:keyLabel="ឯ" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+17B6: "ា" KHMER VOWEL SIGN AA --> + <Key + latin:keyLabel="ា" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179F: "ស" KHMER LETTER SA --> + <Key + latin:keyLabel="ស" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178A: "ដ" KHMER LETTER DA --> + <Key + latin:keyLabel="ដ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1790: "ថ" KHMER LETTER THA --> + <Key + latin:keyLabel="ថ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1784: "ង" KHMER LETTER NGO --> + <Key + latin:keyLabel="ង" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A0: "ហ" KHMER LETTER HA --> + <Key + latin:keyLabel="ហ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D2: "្" KHMER SIGN COENG --> + <Key + latin:keyLabel="្" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1780: "ក" KHMER LETTER KA --> + <Key + latin:keyLabel="ក" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179B: "ល" KHMER LETTER LO --> + <Key + latin:keyLabel="ល" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BE: "ើ" KHMER VOWEL SIGN OE --> + <Key + latin:keyLabel="ើ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CB: "់" KHMER SIGN BANTOC --> + <Key + latin:keyLabel="់" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17AE: "ឮ" KHMER INDEPENDENT VOWEL LYY + U+17AD: "ឭ" KHMER INDEPENDENT VOWEL LY + U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI --> + <Key + latin:keyLabel="ឮ" + latin:keyHintLabel="ឭ" + latin:moreKeys="ឭ,ឰ" + 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="ឍ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1783: "ឃ" KHMER LETTER KHO --> + <Key + latin:keyLabel="ឃ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1787: "ជ" KHMER LETTER CO --> + <Key + latin:keyLabel="ជ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C1/U+17C7: "េះ" KHMER VOWEL SIGN E/KHMER SIGN REAHMUK --> + <Key + latin:keyLabel="េះ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1796: "ព" KHMER LETTER PO + U+179E: "ឞ" KHMER LETTER SSO --> + <Key + latin:keyLabel="ព" + latin:keyHintLabel="ឞ" + latin:moreKeys="ឞ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178E: "ណ" KHMER LETTER NNO --> + <Key + latin:keyLabel="ណ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C6: "ំ" KHMER SIGN NIKAHIT --> + <Key + latin:keyLabel="ំ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BB/U+17C7: "ុះ" KHMER VOWEL SIGN U/KHMER SIGN REAHMUK --> + <Key + latin:keyLabel="ុះ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+17D5: "៕" KHMER SIGN BARIYOOSAN --> + <Key + latin:keyLabel="៕" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="\?" /> + </case> + <default> + <!-- U+178B: "ឋ" KHMER LETTER TTHA --> + <Key + latin:keyLabel="ឋ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1781: "ខ" KHMER LETTER KHA --> + <Key + latin:keyLabel="ខ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1785: "ច" KHMER LETTER CA --> + <Key + latin:keyLabel="ច" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179C: "វ" KHMER LETTER VO --> + <Key + latin:keyLabel="វ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1794: "ប" KHMER LETTER BA --> + <Key + latin:keyLabel="ប" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1793: "ន" KHMER LETTER NO --> + <Key + latin:keyLabel="ន" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1798: "ម" KHMER LETTER MO --> + <Key + latin:keyLabel="ម" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BB/U+17C6: "ុំ" KHMER VOWEL SIGN U/KHMER SIGN NIKAHIT --> + <Key + latin:keyLabel="ុំ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+17D4: "។" KHMER SIGN KHAN --> + <Key + latin:keyLabel="។" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CA: "៊" KHMER SIGN TRIISAP --> + <Key + latin:keyLabel="៊" + 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="໑" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED2: "໒" LAO DIGIT TWO --> + <Key + latin:keyLabel="໒" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED3: "໓" LAO DIGIT THREE --> + <Key + latin:keyLabel="໓" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED4: "໔" LAO DIGIT FOUR --> + <Key + latin:keyLabel="໔" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECC: "໌" LAO CANCELLATION MARK --> + <Key + latin:keyLabel="໌" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EBC: "ຼ" LAO SEMIVOWEL SIGN LO --> + <Key + latin:keyLabel="ຼ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED5: "໕" LAO DIGIT FIVE --> + <Key + latin:keyLabel="໕" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED6: "໖" LAO DIGIT SIX --> + <Key + latin:keyLabel="໖" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED7: "໗" LAO DIGIT SEVEN --> + <Key + latin:keyLabel="໗" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED8: "໘" LAO DIGIT EIGHT --> + <Key + latin:keyLabel="໘" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED9: "໙" LAO DIGIT NINE --> + <Key + latin:keyLabel="໙" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECD/U+0EC8: "ໍ່" LAO NIGGAHITA/LAO TONE MAI EK --> + <Key + latin:keyLabel="ໍ່" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + </case> + <default> + <!-- U+0EA2: "ຢ" LAO LETTER YO + U+0ED1: "໑" LAO DIGIT ONE --> + <Key + latin:keyLabel="ຢ" + latin:keyHintLabel="1" + latin:additionalMoreKeys="1" + latin:moreKeys="໑" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9F: "ຟ" LAO LETTER FO SUNG + U+0ED2: "໒" LAO DIGIT TWO --> + <Key + latin:keyLabel="ຟ" + latin:keyHintLabel="2" + latin:additionalMoreKeys="2" + latin:moreKeys="໒" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC2: "ໂ" LAO VOWEL SIGN O + U+0ED3: "໓" LAO DIGIT THREE --> + <Key + latin:keyLabel="ໂ" + latin:keyHintLabel="3" + latin:additionalMoreKeys="3" + latin:moreKeys="໓" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E96: "ຖ" LAO LETTER THO SUNG + U+0ED4: "໔" LAO DIGIT FOUR --> + <Key + latin:keyLabel="ຖ" + latin:keyHintLabel="4" + latin:additionalMoreKeys="4" + latin:moreKeys="໔" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB8: "ຸ" LAO VOWEL SIGN U --> + <Key + latin:keyLabel="ຸ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB9: "ູ" LAO VOWEL SIGN UU --> + <Key + latin:keyLabel="ູ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E84: "ຄ" LAO LETTER KHO TAM + U+0ED5: "໕" LAO DIGIT FIVE --> + <Key + latin:keyLabel="ຄ" + latin:keyHintLabel="5" + latin:additionalMoreKeys="5" + latin:moreKeys="໕" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E95: "ຕ" LAO LETTER TO + U+0ED6: "໖" LAO DIGIT SIX --> + <Key + latin:keyLabel="ຕ" + latin:keyHintLabel="6" + latin:additionalMoreKeys="6" + latin:moreKeys="໖" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E88: "ຈ" LAO LETTER CO + U+0ED7: "໗" LAO DIGIT SEVEN --> + <Key + latin:keyLabel="ຈ" + latin:keyHintLabel="7" + latin:additionalMoreKeys="7" + latin:moreKeys="໗" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E82: "ຂ" LAO LETTER KHO SUNG + U+0ED8: "໘" LAO DIGIT EIGHT --> + <Key + latin:keyLabel="ຂ" + latin:keyHintLabel="8" + latin:additionalMoreKeys="8" + latin:moreKeys="໘" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E8A: "ຊ" LAO LETTER SO TAM + U+0ED9: "໙" LAO DIGIT NINE --> + <Key + latin:keyLabel="ຊ" + latin:keyHintLabel="9" + latin:additionalMoreKeys="9" + latin:moreKeys="໙" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECD: "ໍ" LAO NIGGAHITA --> + <Key + latin:keyLabel="ໍ" + 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="ົ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0ED0: "໐" LAO DIGIT ZERO --> + <Key + latin:keyLabel="໐" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB3/U+0EC9: "ຳ້" LAO VOWEL SIGN AM/LAO TONE MAI THO --> + <Key + latin:keyLabel="ຳ້" + 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="ິ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EB5/U+0EC9: "ີ້" LAO VOWEL SIGN II/LAO TONE MAI THO --> + <Key + latin:keyLabel="ີ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EA3: "ຣ" LAO LETTER LO LING --> + <Key + latin:keyLabel="ຣ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EDC: "ໜ" LAO HO NO --> + <Key + latin:keyLabel="ໜ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EBD: "ຽ" LAO SEMIVOWEL SIGN NYO --> + <Key + latin:keyLabel="ຽ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAB/U+0EBC: "" LAO LETTER HO SUNG/LAO SEMIVOWEL SIGN LO --> + <Key + latin:keyLabel="ຫຼ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+201D: "”" RIGHT DOUBLE QUOTATION MARK --> + <Key + latin:keyLabel="”" /> + </case> + <default> + <!-- U+0EBB: "ົ" LAO VOWEL SIGN MAI KON --> + <Key + latin:keyLabel="ົ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC4: "ໄ" LAO VOWEL SIGN AI + U+0ED0: "໐" LAO DIGIT ZERO --> + <Key + latin:keyLabel="ໄ" + latin:keyHintLabel="0" + latin:additionalMoreKeys="0" + latin:moreKeys="໐" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB3: "ຳ" LAO VOWEL SIGN AM --> + <Key + latin:keyLabel="ຳ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9E: "ພ" LAO LETTER PHO TAM --> + <Key + latin:keyLabel="ພ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB0: "ະ" LAO VOWEL SIGN A --> + <Key + latin:keyLabel="ະ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB4: "ິ" LAO VOWEL SIGN I --> + <Key + latin:keyLabel="ິ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB5: "ີ" LAO VOWEL SIGN II --> + <Key + latin:keyLabel="ີ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAE: "ຮ" LAO LETTER HO TAM --> + <Key + latin:keyLabel="ຮ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E99: "ນ" LAO LETTER NO --> + <Key + latin:keyLabel="ນ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E8D: "ຍ" LAO LETTER NYO --> + <Key + latin:keyLabel="ຍ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9A: "ບ" LAO LETTER BO --> + <Key + latin:keyLabel="ບ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EA5: "ລ" LAO LETTER LO LOOT --> + <Key + latin:keyLabel="ລ" + 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="ັ້" + 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="໊" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECB: "໋" LAO TONE MAI CATAWA --> + <Key + latin:keyLabel="໋" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="!" /> + <Key + latin:keyLabel="\?" /> + <Key + latin:keyLabel="%" /> + <Key + latin:keyLabel="=" /> + <!-- U+201C: "“" LEFT DOUBLE QUOTATION MARK --> + <Key + latin:keyLabel="“" /> + </case> + <default> + <!-- U+0EB1: "ັ" LAO VOWEL SIGN MAI KAN --> + <Key + latin:keyLabel="ັ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAB: "ຫ" LAO LETTER HO SUNG --> + <Key + latin:keyLabel="ຫ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E81: "ກ" LAO LETTER KO --> + <Key + latin:keyLabel="ກ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E94: "ດ" LAO LETTER DO --> + <Key + latin:keyLabel="ດ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC0: "ເ" LAO VOWEL SIGN E --> + <Key + latin:keyLabel="ເ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC9: "້" LAO TONE MAI THO --> + <Key + latin:keyLabel="້" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC8: "່" LAO TONE MAI EK --> + <Key + latin:keyLabel="່" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB2: "າ" LAO VOWEL SIGN AA --> + <Key + latin:keyLabel="າ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAA: "ສ" LAO LETTER SO SUNG --> + <Key + latin:keyLabel="ສ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EA7: "ວ" LAO LETTER WO --> + <Key + latin:keyLabel="ວ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E87: "ງ" LAO LETTER NGO --> + <Key + latin:keyLabel="ງ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+201C: "“" LEFT DOUBLE QUOTATION MARK --> + <Key + latin:keyLabel="“" /> + </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="₭" /> + <Key + latin:keyLabel="(" /> + <!-- U+0EAF: "ຯ" LAO ELLIPSIS --> + <Key + latin:keyLabel="ຯ" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="\@" /> + <!-- U+0EB6/U+0EC9: "ຶ້" LAO VOWEL SIGN Y/LAO TONE MAI THO --> + <Key + latin:keyLabel="ຶ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EB7/U+0EC9: "ື້" LAO VOWEL SIGN YY/LAO TONE MAI THO --> + <Key + latin:keyLabel="ື້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EC6: "ໆ" LAO KO LA --> + <Key + latin:keyLabel="ໆ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EDD: "ໝ" LAO HO MO --> + <Key + latin:keyLabel="ໝ" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="$" /> + <Key + latin:keyLabel=")" /> + </case> + <default> + <!-- U+0E9C: "ຜ" LAO LETTER PHO SUNG --> + <Key + latin:keyLabel="ຜ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9B: "ປ" LAO LETTER PO --> + <Key + latin:keyLabel="ປ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC1: "ແ" LAO VOWEL SIGN EI --> + <Key + latin:keyLabel="ແ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAD: "ອ" LAO LETTER O --> + <Key + latin:keyLabel="ອ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB6: "ຶ" LAO VOWEL SIGN Y --> + <Key + latin:keyLabel="ຶ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB7: "ື" LAO VOWEL SIGN YY --> + <Key + latin:keyLabel="ື" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E97: "ທ" LAO LETTER THO TAM --> + <Key + latin:keyLabel="ທ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EA1: "ມ" LAO LETTER MO --> + <Key + latin:keyLabel="ມ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC3: "ໃ" LAO VOWEL SIGN AY --> + <Key + latin:keyLabel="ໃ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9D: "ຝ" LAO LETTER FO TAM --> + <Key + latin:keyLabel="ຝ" + 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="ठ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0914: "औ" DEVANAGARI LETTER AU --> + <Key + latin:keyLabel="औ" + 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="थ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091E: "ञ" DEVANAGARI LETTER NYA --> + <Key + latin:keyLabel="ञ" + 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="ओ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092B: "फ" DEVANAGARI LETTER PHA --> + <Key + latin:keyLabel="फ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0908: "ई" DEVANAGARI LETTER II --> + <Key + latin:keyLabel="ई" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+091F: "ट" DEVANAGARI LETTER TTA + U+0967: "१" DEVANAGARI DIGIT ONE + U+093C: "़" DEVANAGARI SIGN NUKTA --> + <Key + latin:keyLabel="ट" + latin:keyHintLabel="1" + latin:additionalMoreKeys="१,1" + 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. --> + <!-- U+0968: "२" DEVANAGARI DIGIT TWO --> + <include + latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" /> + <Key + latin:keyStyle="baseKeyDevanagariVowelSignAu" + latin:keyHintLabel="2" + latin:additionalMoreKeys="२,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="३,3" /> + <!-- U+0930: "र" DEVANAGARI LETTER RA + U+096A: "४" DEVANAGARI DIGIT FOUR --> + <Key + latin:keyLabel="र" + latin:keyHintLabel="4" + latin:additionalMoreKeys="४,4" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0924: "त" DEVANAGARI LETTER TA + U+096B: "५" DEVANAGARI DIGIT FIVE --> + <Key + latin:keyLabel="त" + latin:keyHintLabel="5" + latin:additionalMoreKeys="५,5" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092F: "य" DEVANAGARI LETTER YA + U+096C: "६" DEVANAGARI DIGIT SIX --> + <Key + latin:keyLabel="य" + latin:keyHintLabel="6" + latin:additionalMoreKeys="६,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="७,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="८,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="९,9" /> + <!-- U+092A: "प" DEVANAGARI LETTER PA + U+0966: "०" DEVANAGARI DIGIT ZERO --> + <Key + latin:keyLabel="प" + latin:keyHintLabel="0" + latin:additionalMoreKeys="०,0" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0907: "इ" DEVANAGARI LETTER I --> + <Key + latin:keyLabel="इ" + 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="आ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0936: "श" DEVANAGARI LETTER SHA --> + <Key + latin:keyLabel="श" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0927: "ध" DEVANAGARI LETTER DHA --> + <Key + latin:keyLabel="ध" + latin:keyLabelFlags="fontNormal" /> + <!-- U+090A: "ऊ" DEVANAGARI LETTER UU --> + <Key + latin:keyLabel="ऊ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0918: "घ" DEVANAGARI LETTER GHA --> + <Key + latin:keyLabel="घ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0905: "अ" DEVANAGARI LETTER A --> + <Key + latin:keyLabel="अ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091D: "झ" DEVANAGARI LETTER JHA --> + <Key + latin:keyLabel="झ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0916: "ख" DEVANAGARI LETTER KHA --> + <Key + latin:keyLabel="ख" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0965: "॥" DEVANAGARI DOUBLE DANDA --> + <Key + latin:keyLabel="॥" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0910: "ऐ" DEVANAGARI LETTER AI --> + <Key + latin:keyLabel="ऐ" + 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="स" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0926: "द" DEVANAGARI LETTER DA --> + <Key + latin:keyLabel="द" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0909: "उ" DEVANAGARI LETTER U --> + <Key + latin:keyLabel="उ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0917: "ग" DEVANAGARI LETTER GA --> + <Key + latin:keyLabel="ग" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0939: "ह" DEVANAGARI LETTER HA --> + <Key + latin:keyLabel="ह" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091C: "ज" DEVANAGARI LETTER JA --> + <Key + latin:keyLabel="ज" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0915: "क" DEVANAGARI LETTER KA --> + <Key + latin:keyLabel="क" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0932: "ल" DEVANAGARI LETTER LA --> + <Key + latin:keyLabel="ल" + latin:keyLabelFlags="fontNormal" /> + <!-- U+090F: "ए" DEVANAGARI LETTER E --> + <Key + latin:keyLabel="ए" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0950: "ॐ" DEVANAGARI OM --> + <Key + latin:keyLabel="ॐ" + 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="ऋ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0922: "ढ" DEVANAGARI LETTER DDHA --> + <Key + latin:keyLabel="ढ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091B: "छ" DEVANAGARI LETTER CHA --> + <Key + latin:keyLabel="छ" + 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="भ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0923: "ण" DEVANAGARI LETTER NNA --> + <Key + latin:keyLabel="ण" + 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="ङ" + 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="ष" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0921: "ड" DEVANAGARI LETTER DDA --> + <Key + latin:keyLabel="ड" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091A: "च" DEVANAGARI LETTER CA --> + <Key + latin:keyLabel="च" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0935: "व" DEVANAGARI LETTER VA --> + <Key + latin:keyLabel="व" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092C: "ब" DEVANAGARI LETTER BHA --> + <Key + latin:keyLabel="ब" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0928: "न" DEVANAGARI LETTER NA --> + <Key + latin:keyLabel="न" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092E: "म" DEVANAGARI LETTER MA --> + <Key + latin:keyLabel="म" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0964: "।" DEVANAGARI DANDA + U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA --> + <Key + latin:keyLabel="।" + 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" /> + </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="त्त" + latin:moreKeys="ञ,ज्ञ,॥" + 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="ड्ढ" + latin:moreKeys="ई" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0910: "ऐ" DEVANAGARI LETTER AI + U+0918: "घ" DEVANAGARI LETTER GHA --> + <Key + latin:keyLabel="ऐ" + latin:moreKeys="घ" + 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="द्व" + latin:moreKeys="द्ध" + 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="ट्ट" + latin:moreKeys="छ" + 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="ठ्ठ" + latin:moreKeys="ट" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+090A: "ऊ" DEVANAGARI LETTER UU + U+0920: "ठ" DEVANAGARI LETTER TTHA --> + <Key + latin:keyLabel="ऊ" + latin:moreKeys="ठ" + 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="क्ष" + latin:moreKeys="ड" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0907: "इ" DEVANAGARI LETTER I + U+0922: "ढ" DEVANAGARI LETTER DDHA --> + <Key + latin:keyLabel="इ" + latin:moreKeys="ढ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+090F: "ए" DEVANAGARI LETTER E + U+0923: "ण" DEVANAGARI LETTER NNA --> + <Key + latin:keyLabel="ए" + 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/key_devanagari_vowel_sign_vocalic_r" /> + </case> + <default> + <!-- U+091F: "ट" DEVANAGARI LETTER TTA + U+0967: "१" DEVANAGARI DIGIT ONE --> + <Key + latin:keyLabel="ट" + latin:keyHintLabel="1" + latin:additionalMoreKeys="१,1" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0927: "ध" DEVANAGARI LETTER DHA + U+0968: "२" DEVANAGARI DIGIT TWO --> + <Key + latin:keyLabel="ध" + latin:keyHintLabel="2" + latin:additionalMoreKeys="२,2" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092D: "भ" DEVANAGARI LETTER BHA + U+0969: "३" DEVANAGARI DIGIT THREE --> + <Key + latin:keyLabel="भ" + latin:keyHintLabel="3" + latin:additionalMoreKeys="३,3" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091A: "च" DEVANAGARI LETTER CA + U+096A: "४" DEVANAGARI DIGIT FOUR --> + <Key + latin:keyLabel="च" + latin:keyHintLabel="4" + latin:additionalMoreKeys="४,4" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0924: "त" DEVANAGARI LETTER TA + U+096B: "५" DEVANAGARI DIGIT FIVE --> + <Key + latin:keyLabel="त" + latin:keyHintLabel="5" + latin:additionalMoreKeys="५,5" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0925: "थ" DEVANAGARI LETTER THA + U+096C: "६" DEVANAGARI DIGIT SIX --> + <Key + latin:keyLabel="थ" + latin:keyHintLabel="6" + latin:additionalMoreKeys="६,6" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0917: "ग" DEVANAGARI LETTER G + U+096D: "७" DEVANAGARI DIGIT SEVEN --> + <Key + latin:keyLabel="ग" + latin:keyHintLabel="7" + latin:additionalMoreKeys="७,7" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0937: "ष" DEVANAGARI LETTER SSA + U+096E: "८" DEVANAGARI DIGIT EIGHT --> + <Key + latin:keyLabel="ष" + latin:keyHintLabel="8" + latin:additionalMoreKeys="८,8" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092F: "य" DEVANAGARI LETTER YA + U+096F: "९" DEVANAGARI DIGIT NINE --> + <Key + latin:keyLabel="य" + latin:keyHintLabel="9" + latin:additionalMoreKeys="९,9" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0909: "उ" DEVANAGARI LETTER U + U+0966: "०" DEVANAGARI DIGIT ZERO --> + <Key + latin:keyLabel="उ" + latin:keyHintLabel="0" + latin:additionalMoreKeys="०,0" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0907: "इ" DEVANAGARI LETTER I + U+0914: "औ" DEVANAGARI LETTER AU --> + <Key + latin:keyLabel="इ" + latin:moreKeys="औ" + 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="आ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0919/U+094D: "ङ्" DEVANAGARI LETTER NGA/DEVANAGARI SIGN VIRAMA --> + <Key + latin:keyLabel="ङ्" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0921/U+094D/U+0921: "ड्ड" DEVANAGARI LETTER DDA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER DDA --> + <Key + latin:keyLabel="ड्ड" + 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="द्द" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+091D: "झ" DEVANAGARI LETTER JHA --> + <Key + latin:keyLabel="झ" + 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="फ" + 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="ट्ठ" + 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="ब" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0915: "क" DEVANAGARI LETTER KA --> + <Key + latin:keyLabel="क" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092E: "म" DEVANAGARI LETTER MA --> + <Key + latin:keyLabel="म" + 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="न" + latin:keyLabelFlags="fontNormal" /> + <!-- U+091C: "ज" DEVANAGARI LETTER JA --> + <Key + latin:keyLabel="ज" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0935: "व" DEVANAGARI LETTER VA --> + <Key + latin:keyLabel="व" + latin:keyLabelFlags="fontNormal" /> + <!-- U+092A: "प" DEVANAGARI LETTER PA --> + <Key + latin:keyLabel="प" + 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="स" + 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="क्" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0939/U+094D/U+092E: "ह्म" DEVANAGARI LETTER HA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER MA --> + <Key + latin:keyLabel="ह्म" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R --> + <Key + latin:keyLabel="ऋ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0950: "ॐ" DEVANAGARI OM --> + <Key + latin:keyLabel="ॐ" + 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="द्य" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + </case> + <default> + <!-- U+0936: "श" DEVANAGARI LETTER SHA --> + <Key + latin:keyLabel="श" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0939: "ह" DEVANAGARI LETTER HA --> + <Key + latin:keyLabel="ह" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0905: "अ" DEVANAGARI LETTER A --> + <Key + latin:keyLabel="अ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0916: "ख" DEVANAGARI LETTER KHA --> + <Key + latin:keyLabel="ख" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0926: "द" DEVANAGARI LETTER DA --> + <Key + latin:keyLabel="द" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0932: "ल" DEVANAGARI LETTER LA --> + <Key + latin:keyLabel="ल" + 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="ङ" + 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="।" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0930: "र" DEVANAGARI LETTER RA + U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U --> + <Key + latin:keyLabel="र" + latin:moreKeys="रु" + 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="ङ" + 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="रु" + 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="ऽ" /> + <!-- 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="।" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0930: "र" DEVANAGARI LETTER RA --> + <Key + latin:keyLabel="र" + 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="¬" /> - <!-- U+00A1: "¡" NVERTED EXCLAMATION MARK --> - <Key - latin:keyLabel="1" - latin:additionalMoreKeys="!" - 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="&" - 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="&" + 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="–,—,·" /> + <!-- U+221E: "∞" INFINITY + U+2260: "≠" NOT EQUAL TO + U+2248: "≈" ALMOST EQUAL TO --> + <Key + latin:keyLabel="=" + latin:additionalMoreKeys="+" + latin:moreKeys="!fixedColumnOrder!4,∞,≠,≈,%" /> </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="¬" /> - <!-- U+00A1: "¡" NVERTED EXCLAMATION MARK --> + latin:keyLabel="~" /> <Key latin:keyLabel="!" - latin:moreKeys="¡" /> + 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="‰" /> + latin:additionalMoreKeys="!text/more_keys_for_symbols_percent" /> <Key latin:keyLabel="^" /> <Key latin:keyLabel="&" /> <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="±,×,÷,√" /> </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="&" /> - <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="√" /> - <!-- 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="π" - latin:moreKeys="Π" /> + latin:keyLabel="Π" + latin:moreKeys="π" /> <!-- U+00F7: "÷" DIVISION SIGN --> <Key latin:keyLabel="÷" /> <!-- U+00D7: "×" MULTIPLICATION SIGN --> <Key latin:keyLabel="×" /> - <include - latin:keyboardLayout="@xml/keys_curly_brackets" /> + <!-- U+00B6: "¶" PILCROW SIGN + U+00A7: "§" SECTION SIGN --> + <Key + latin:keyLabel="¶" + latin:moreKeys="§" /> + <!-- U+2206: "∆" INCREMENT --> + <Key + latin:keyLabel="∆" /> </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="°" - latin:moreKeys="′,″" /> + latin:keyStyle="moreCurrency4KeyStyle" /> <!-- U+2191: "↑" UPWARDS ARROW U+2193: "↓" DOWNWARDS ARROW U+2190: "←" LEFTWARDS ARROW @@ -42,8 +36,12 @@ <Key latin:keyLabel="^" latin:moreKeys="↑,↓,←,→" /> + <!-- U+00B0: "°" DEGREE SIGN + U+2032: "′" PRIME + U+2033: "″" DOUBLE PRIME --> <Key - latin:keyLabel="_" /> + latin:keyLabel="°" + latin:moreKeys="′,″" /> <!-- U+2260: "≠" NOT EQUAL TO U+2248: "≈" ALMOST EQUAL TO U+221E: "∞" INFINITY --> @@ -51,5 +49,5 @@ latin:keyLabel="=" latin:moreKeys="≠,≈,∞" /> <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="™" /> - <!-- U+00AE: "®" REGISTERED SIGN --> <Key - latin:keyLabel="®" /> + latin:keyLabel="\\" /> <!-- U+00A9: "©" COPYRIGHT SIGN --> <Key latin:keyLabel="©" /> - <!-- U+00B6: "¶" PILCROW SIGN - U+00A7: "§" SECTION SIGN --> + <!-- U+00AE: "®" REGISTERED SIGN --> + <Key + latin:keyLabel="®" /> + <!-- U+2122: "™" TRADE MARK SIGN --> <Key - latin:keyLabel="¶" - latin:moreKeys="§" /> + latin:keyLabel="™" /> + <!-- U+2105: "℅" CARE OF --> <Key - latin:keyLabel="\\" /> + latin:keyLabel="℅" /> <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()); } /** |